I have a varray full of triangles that make a large square. I'm trying to texture this large square and all i'm getting (it seems) is a one pixel column that is then stretched across the primitive.
I'm texturing each right angled triangle with UV coords (0,1), (0,0), (1,0) and (0,1), (1,1), (1,0) depending on which way up the triangle is.
rendering code.
glBindTexture(GL_TEXTURE_2D, m_texture.id());
//glEnableClientState(GL_INDEX_ARRAY);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_NORMAL_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
//glIndexPointer(GL_INT, 0, &m_indices[0]);
glVertexPointer(3, GL_FLOAT, sizeof(VertexData), &m_vertexData[0].x);
glNormalPointer(GL_FLOAT, sizeof(VertexData), &m_vertexData[0].nx);
glTexCoordPointer(2, GL_FLOAT, sizeof(UVData), &m_uvData[0].u);
glDrawElements(GL_TRIANGLES, m_indices.size(), GL_UNSIGNED_INT, &m_indices[0]);
glBindTexture(GL_TEXTURE_2D, 0);
texture is wrap mode is GL_CLAMP_TO_EDGE
Screenshot
EDIT
outputting the first two triangles i get values ...
Triangle 1:
Indices(0,1,31)
Vertex0 (-15, 0, -15), Vertex1 (-15,0,-14), Vertex31 (-14, 0, -14)
UV (0,1), (0,0), (1,0)
Triangle 2:
Indices(0, 30, 31)
Vertex0(-15, 0, -15), Vertex30(-14, 0, -15) Vertex31 (-14, 0, -14)
UV (0, 1), (1, 1), (1, 0)
For posterity the full code is here
The two triangles make up a square with the diagonal cut from top left to bottom right.
Don't use the glIndexPointer, is not what you think it is, is used for color-index mode, to do indexed meshes just use glDrawElements.
Looks like you're associating the UV data with the indices, not with the vertices. UV data is part of the vertex data, so you should probably pack it in the VertexData object, rather than keeping it separate. You can keep it separate, but you need one per vertex, not one per index.
Related
I am trying to do some simple graphics processing with OpenGL, but I am having trouble having 2 objects where one of them is static and the other moves. The objects are a simple cube and a square that represents the floor. I want the cube to move down until it touches the floor (as if it were moving). I can render the falling cube on its own, and I can get the floor on its own. But when I want to have them both in the same scene I am having issues as they either both fall down (the cubes behaviour), or both stay in the same place (the floors behaviour). Which one of these two options occurs is due to whether I push and pop my model matrix - when I do pop and push, they stay static, when I don't, they fall down (I guess this makes sense as I draw the floor then the cube.
This is my code in the draw phase of the program:
//Clear the screen to the colour specified earlier, as well as the depth
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glUseProgram(programID); // Use our shader
glUniformMatrix4fv(MatrixID, 1, GL_FALSE, &MVP[0][0]);
//RENDER THE FLOOR
pushMat(Model); //PUSH - WHEN ACTIVE, CUBE AND FLOOR FALL. WHEN COMMENTED OUT, BOTH FLOOR AND CUBE ARE STATIC
MVP = Projection * View * Model; //These are all matrices
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, floorVertexBuffer);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, (void*)0);
//FLOOR COLOURS
glEnableVertexAttribArray(1);
glBindBuffer(GL_ARRAY_BUFFER, colorbuffer2);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, (void*)0);
glDrawArrays(GL_TRIANGLES, 0, 2*3); //2 triangles, of 3 vertices each
Model = popMat(); //POP - WHEN ACTIVE, CUBE AND FLOOR FALL. WHEN COMMENTED OUT, BOTH FLOOR AND CUBE ARE STATIC
glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);
//RENDER THE CUBE
pushMat(Model); //PUSH - WHEN ACTIVE, CUBE AND FLOOR FALL. WHEN COMMENTED OUT, BOTH FLOOR AND CUBE ARE STATIC
Model = translate(Model, vec3(0.0f, deltaY, 0.0f)); //deltaY is the change in the y position of the cube, it is calculated earlier in this draw loop
MVP = Projection * View * Model;
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, cubeVertexBuffer);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void*)0);
//CUBE COLOURS
glEnableVertexAttribArray(1);
glBindBuffer(GL_ARRAY_BUFFER, colorbuffer);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, (void*)0);
//DRAW CUBE
glDrawArrays(GL_TRIANGLES, 0, 12 * 3); //12 triangle, of 3 vertices each
Model = popMat(); //FINAL POP - WHEN ACTIVE, CUBE AND FLOOR FALL. WHEN COMMENTED OUT, BOTH FLOOR AND CUBE ARE STATIC
glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);
Code for my push and pop functions:
stack<mat4> modelViewStack; //This is initialised with the identity matrix in the main function
void pushMat(mat4 m)
{
modelViewStack.push(m);
}
mat4 popMat()
{
mat4 temp = modelViewStack.top();
modelViewStack.pop();
return temp;
}
Any clues as to how I get it so the floor stays in one place and the cube moves down? I'm happy to help explain any code, provide more of my code, or answer any questions in general. Thanks for any help.
glUniformMatrix4fv(MatrixID, 1, GL_FALSE, &MVP[0][0]);
This call needs to appear before each call to glDrawArrays. Right now, it's only being called once, before you render everything, which means both objects are receiving the same MVP matrix.
Also, I would reconsider the logic of implementing this logic using a Matrix Stack. That was how it worked in Legacy OpenGL (because everything depended on Global State, and some other reasons) but it's not obvious that this is the best solution today, when we can simply associate Matrices with individual objects and simply bind them as needed.
I have been trying to draw points with unsigned integer coordinates
However, whenever I do one point is drawn at the center and the next at the far right, I cannot see any of the other points (except the first and second from the next line). Is there any way to fix this without converting to floats?
My draw code is as follows:
glDepthMask(GL_TRUE);
glEnable(GL_DEPTH_TEST);
glBindBuffer(GL_ARRAY_BUFFER, _vbo);
SDL_GL_SwapWindow(_window);
glPointSize(1);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_UNSIGNED_INT, GL_TRUE, 0, 0);
glDrawArrays(GL_POINTS, 0, _dataCount);
glDisableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
EDIT:
I have determined that it is related to the gl_Position.w value in the vertex shader, can anyone tell me how to use this correctly?
EDIT 2:
I have distributed the values between 0 and _maxValue (largest unsigned int for the moment), and set that to be gl_Position.w, for the moment it draws to the screen but only in the upper left quadrant, I would assume this is because it is being mapped to 0.0-1.0 instead of -1.0-1.0. How do you fix this issue?
Alternatively I feel I should be doing something with the projection matrix, I haven't needed to use it before as I'm relatively new to openGL, so I'm not sure exactly what I specifically need if this is the correct approach, so any help would be appreciated
Hi I needed to draw a round corner rectangle.
I followed the procedure of the above image. I first drew the green rectangle. Then I drew the two black rectangles.And then I drew circles on the edges to make the corner round. Now what I get after doing this is in the image below.
As it can be seen that the corner circles have less transparency on the portions where they overlap with the rectangles. But more transparency when not overlapped with the rectangles. The rectangles have alpha set to 0.5f. and the circle also have 0.5f alpha. So thats why its white on the overlapped portions and transparent on non overlapped portions. I want the overlapped portions to have same transparency as the rectangle so that the overlapped circle portion can not be seen.My blend function is glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); I tried to understand the blend functions in more details in here. But I could not understand anything.
My code is below,
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glViewport(0, 0, (int) screenWidth, (int) screenHeight);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrthof(0.0f, (double)screenWidth / screenHeight, 0.0f, 1.0f, -1.0f, 1.0f);
glEnable(GL_TEXTURE_2D);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glEnable(GL_COLOR_MATERIAL);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glDisable(GL_TEXTURE_2D);
glBlendFunc(GL_ONE_MINUS_DST_ALPHA, GL_DST_ALPHA);
glEnableClientState(GL_COLOR_ARRAY);
glVertexPointer(3, GL_FLOAT, 0, bubbleMiddleRectStartCoord);
glColorPointer(4, GL_FLOAT, 0, rectColor);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
glVertexPointer(3, GL_FLOAT, 0, bubbleTopRectStartCoord);
glColorPointer(4, GL_FLOAT, 0, rectColor);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
glVertexPointer(3, GL_FLOAT, 0, bubbleBottomRectStartCoord);
glColorPointer(4, GL_FLOAT, 0, rectColor);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
//smooth edge of the bubble rectangle
drawCircle(triangleAmount,bubbleEdgeRadius,bubbleMiddleRectStartCoord->upperLeft.x+bubbleEdgeRadius,bubbleMiddleRectStartCoord->upperLeft.y,255,255,255,128);
drawCircle(triangleAmount,bubbleEdgeRadius,bubbleMiddleRectStartCoord->lowerLeft.x+bubbleEdgeRadius,bubbleMiddleRectStartCoord->lowerLeft.y,255,255,255,128);
drawCircle(triangleAmount,bubbleEdgeRadius,bubbleMiddleRectStartCoord->upperRight.x-bubbleEdgeRadius,bubbleMiddleRectStartCoord->upperRight.y,255,255,255,128);
drawCircle(triangleAmount,bubbleEdgeRadius,bubbleMiddleRectStartCoord->lowerRight.x-bubbleEdgeRadius,bubbleMiddleRectStartCoord->lowerRight.y,255,255,255,128);
glDisableClientState(GL_COLOR_ARRAY);
glEnable(GL_TEXTURE_2D);
glDisable(GL_BLEND);
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisableClientState(GL_COLOR_MATERIAL);
glDisable(GL_TEXTURE_2D);
swapBuffers();
rectColor has value
GLfloat rectColor[]=
{
1.0f,1.0f,1.0f,0.5,
1.0f,1.0f,1.0f,0.5,
1.0f,1.0f,1.0f,0.5,
1.0f,1.0f,1.0f,0.5
};
drawCircle function generates the points for the circle and draws it. The drawing portion of that function is
glVertexPointer(2, GL_FLOAT, 0, vertices);
glColorPointer(4, GL_UNSIGNED_BYTE, 0, color);
glDrawArrays(GL_TRIANGLE_FAN, 0, triangleAmount+2);
Can anyone help me to solve the problem? Thanks.
EDIT: this is how it looks after using those two blend functions.
I see where you are going with this and seeing your result you probably only need to disable blend while you are drawing the mask (the 3 rectangles and 4 circles), then using glBlendFunc(GL_DST_ALPHA, GL_ZERO). Though this will only work if nothing has already been drawn on the scene.
To explain what you did there is you are drawing a white color with .5 alpha and blending it.
Consider on the beginning the pixel color "destination" is (0,0,0,0) and incoming "source" is always in your case (1,1,1,.5). Lets say source color is "S" and destination is "D" while the components are (r,g,b,a) so that source alpha is "S.a" what you wrote in your blend function is:
output = S*S.a + D*(1.0-S.a) =
(1,1,1,.5)*.5 + (0,0,0,0)*(1.0-.5) =
(.5, .5, .5, .25) + (0,0,0,0) =
(.5, .5, .5, .25)
so when you draw your circle over the already drawn rectangle:
output = S*S.a + D*(1.0-S.a) =
(1,1,1,.5)*.5 + (.5, .5, .5, .25)*(1.0-.5) =
(.5, .5, .5, .25) + (.25, .25, .25, .125) =
(.75, .75, .75, .375)
resulting in alpha difference. So from this I hope you can understand what the 2 parameters mean in the blend function: First one tells what factor to use to multiply the source (incoming) color and the second one how to multiply the destination color. In the end they are summed together.
So for your case you would like to force the alpha channel to some value everywhere you draw those primitives. To achieve that you would need S*1.0 + D*.0 and parameters for that are glBlendFunc(GL_ONE, GL_ZERO), though this is the same as just disabling the blend. Only writing this primitives would produce a white(gray) rounded rect with transparency of .5 while all the rest is fully transparent. Now after this you need to set blend function to multiply your incoming color with the destination alpha glBlendFunc(GL_DST_ALPHA, GL_ZERO).
EDIT:
I did not totally understand what you want to achieve till now. As I mentioned above, this will not work if you already have some scene drawn.
To overlay an existing scene with some complex object (in this case the object is overlapping itself on some parts) it would be most bulletproof to use a stencil buffer. Creating it is much like depth buffer but you may consider it as another color channel, it is easy to draw to it and later use it so you might want to look at it at some point.
In your case it is probably safe to say this is your main buffer and is meant for displaying. In that case you can just use the alpha channel:
To draw only to alpha channel you have to set glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_TRUE) and when you are done, put all the parameters to true.
To clear the alpha channel you have to draw a fullscreen rect with some color with desired alpha (I suggest you use (1,1,1,1)) and draw only to alpha channel
To draw that mask (the 3 rects and 4 circles) use glBlendFunc(GL_ONE, GL_ZERO) and color (1,1,1, 1-desiredAlpha)
To draw your rounded label use glBlendFunc(GL_ONE_MINUS_DST_ALPHA, GL_DST_ALPHA)
So the procedure would be:
//your background is drawn, time to overly labels
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_TRUE);
glColor(1.0f, 1.0f, 1.0f, 1.0f);
//draw fullscreen rect
glBlendFunc(GL_ONE, GL_ZERO);
glColor(1.0f, 1.0f, 1.0f, 1.0f-.5f);
//draw 3 rects and 4 circles
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
glBlendFunc(GL_ONE_MINUS_DST_ALPHA, GL_DST_ALPHA);
//draw the label as a normal rect (the rounded parts will be trimmed because of alpha channel)
and you can just repeat that in a for loop for all the labels.
I know things got a bit complicated but what you are trying to do is not as easy as it would seem. I presented this solution to you because this way you have least code to change, in general I would suggest to use stencil buffer (already mentioned) or a FBO (frame buffer object). The FBO system would be to create another frame buffer and attach a texture to it, draw the whole label object to it and then use the bound texture to draw it to main screen.
I am doing some opengl in cocos2d draw() method, as I need some 3d effects. To test, I draw a texture by a triangle strip. The problem is that the result picture is just upside-down. Code is quite simple, I cannot figure out why it is upside down:
ccVertex3F newPoint[4] = {{-20,0, -100},
{20,0, -100},
{-20,40, -100},
{20,40, -100}
};
ccVertex2F _textCoordArray[4] = {{0,0}, {1,0}, {0,1}, {1,1}};
glDisableClientState(GL_COLOR_ARRAY);
glBindTexture(GL_TEXTURE_2D, [lineTexture name]);
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
glVertexPointer(3, GL_FLOAT, 0, newPoint);
glTexCoordPointer(2, GL_FLOAT, 0, _textCoordArray);
glEnableClientState(GL_VERTEX_ARRAY);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
glPopMatrix();
Some libraries just have different ideas of which point on a texture is (0,0) (top left or bottom left corner). I'm guessing that whatever image loading library you've used considers (0,0) to be the top left, while opengl considers it to be the bottom left.
To correct it you can either tell cocoa to load it upside down (don't know how or if its even possible), or flip your UV's veritcal orientation:
from:
_textCoordArray[4] = {{0,0}, {1,0}, {0,1}, {1,1}};
to:
_textCoordArray[4] = {{0,1}, {1,1}, {0,0}, {1,0}};
I've been trying to figure this out for a while, but I'm failing. I need to draw a cube, and then add a border around it. The cube works fine, and I got the border to draw, but there's always an extra line sticking in. I use the GL_ARRAY_BUFFER to store data and switch from GL_TRIANGLES (to draw the cube itself) to GL_LINES (to draw the outline borders). Each offset in the buffer has its own set of vertices.
My code for the display function (GLUT):
// cubeLen = number of cube's vertices in buffer
// sidesLen = number of side vertices in buffer
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glDrawArrays(GL_TRIANGLES, 0, cubeLen);
glDrawArrays(GL_LINES, cubeLen, cubeLen + sidesLen);
glutSwapBuffers();
My code to set up the buffers:
GLuint buffer;
glGenBuffers( 1, &buffer );
glBindBuffer( GL_ARRAY_BUFFER, buffer );
glBufferData( GL_ARRAY_BUFFER, sizeof(points) + sizeof(colors)
+ sizeof(points2) + sizeof(colors2),
NULL, GL_STATIC_DRAW );
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(points), points);
glBufferSubData(GL_ARRAY_BUFFER, sizeof(points), sizeof(colors), colors);
glBufferSubData(GL_ARRAY_BUFFER, sizeof(points) + sizeof(colors),
sizeof(points2), points2);
glBufferSubData(GL_ARRAY_BUFFER, sizeof(points) + sizeof(colors) + sizeof(points2),
sizeof(colors2), colors2);
I use 12 triangles (3 vertices each) for each side of the cube, and 12 lines (24 vertices) to cover all of the edges. The cube and edges are in sycn sitting at the center of the screen (centered at 0,0,0). The extra unwanted line (which appears to stretch from the center-left 3D position to the center-front 3D position) to comes in even if I disable drawing the cube in the display function. It does, however, go away when I do not set up vertices for the cube. Any ideas why this might be happening? Thanks for any and all help.
The extra line was a misplaced index to the buffer when it called the display function. Basically, it tried to display the color data instead of the actual vertex data.