Reputation: 1279
I ran into an issue where my vertices were being drawn offscreen. I changed the stride to 0 for all my vertex attribute pointers and now they draw at the correct location.
Here is some code to start this off:
glGenVertexArrays(1, &vertexID);
glBindVertexArray(vertexID);
glGenBuffers(1, &bufferID);
glBindBuffer(GL_ARRAY_BUFFER, bufferID);
GLfloat verts[4 * 2 * 3] = { -0.5, -0.5, 0.0, 1.0,// bottom left
.5, -.5, 0.0, 1.0, // bottom right
-.5, .5, 0.0, 1.0, // top left
0.5, 0.5, 0.0, 1.0,
.5, -.5, 0.0, 1.0, // bottom right
-.5, .5, 0.0, 1.0, // top left// top right
};
GLfloat color[4 * 3 * 2] = {
1.0f, 1.0f, 1.0f, 1.0f,
1.0f, 1.0f, 1.0f, 1.0f,
1.0f, 1.0f, 1.0f, 1.0f,
1.0f, 1.0f, 1.0f, 1.0f,
1.0f, 1.0f, 1.0f, 1.0f,
1.0f, 1.0f, 1.0f, 1.0f };
GLfloat tex[8] = {
1.0f, 1.0f,
1.0f, 0.0f,
0.0f, 0.0f,
0.0f, 1.0f
};
glBufferData(GL_ARRAY_BUFFER, sizeof(verts) + sizeof(color) + sizeof(tex), nullptr, GL_STATIC_DRAW);
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(verts), verts);
glBufferSubData(GL_ARRAY_BUFFER, sizeof(verts), sizeof(color), color);
glBufferSubData(GL_ARRAY_BUFFER, sizeof(verts) + sizeof(color), sizeof(tex), tex);
glClearColor(0.05f, 0.05f, 0.05f, 1.0f);
glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 10, NULL);
glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 10, (const GLvoid *)(sizeof(GLfloat) * 4));
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 10, (const GLvoid *)(sizeof(GLfloat) * 8));
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
glEnableVertexAttribArray(2);
glGenBuffers(1, &ebo);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
GLuint indices[4] = {
0,2,1,3
};
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_DYNAMIC_DRAW);
and then here is the rendering code
glClear(GL_COLOR_BUFFER_BIT);
glBindTexture(GL_TEXTURE_2D, texture);
glBindVertexArray(vertexID);
glDrawElements(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_INT, 0);
//glDrawArrays(GL_TRIANGLES, 0, 6);
glFlush();
SDL_GL_SwapWindow(window);
Okay so here is where I am confused:
glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 10, NULL);
glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 10, (const GLvoid *)(sizeof(GLfloat) * 4));
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 10, (const GLvoid *)(sizeof(GLfloat) * 8));
With this above code, the program doesn't render the proper square I am trying to render. If I change the stride to 0 for all of these, then it renders in the correct position. My understanding of it was that i sub buffered 3 sets of information: position, color, and tex coordinates. Therefor I thought the data looked like the following:
There for I set the stride to sizeof(GLFloat) * 10, however, this doesn't work. This makes me assume I also don't have the offset values set correctly. So why is my stride messing up the vertex position?
Upvotes: 0
Views: 736
Reputation: 52084
You're uploading your vertex data in blocks:
glBufferData(GL_ARRAY_BUFFER, sizeof(verts) + sizeof(color) + sizeof(tex), nullptr, GL_STATIC_DRAW);
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(verts), verts);
glBufferSubData(GL_ARRAY_BUFFER, sizeof(verts), sizeof(color), color);
glBufferSubData(GL_ARRAY_BUFFER, sizeof(verts) + sizeof(color), sizeof(tex), tex);
So it ends up like:
<vert 0, ... vert N><color 0, ..., color N><tex 0, ..., tex N>
But your glVertexAttribPointer()
calls are claiming the buffer is interleaved like this:
<vert 0><color 0><tex 0><vert 1><color1><tex 1>...
Either interleave the data at upload or adjust your glVertexAttribPointer()
calls to take into account the block layout.
Upvotes: 2
Reputation: 473547
Therefor I thought the data looked like the following:
But that's not what you told OpenGL.
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(verts), verts);
This tells OpenGL to take the array verts
and copy it into the start of the buffer object.
glBufferSubData(GL_ARRAY_BUFFER, sizeof(verts), sizeof(color), color);
This tells OpengL to take the array color
, and copy it into the buffer object, but after all of verts
.
There's no interleaving here. You buffer stores all of verts
, followed by all of color
, followed by all of tex
. It does not store 4 floats of verts
followed by 4 floats of color
, followed by 4 floats of tex
.
glBufferSubData
cannot interleave data for you (well, you could do it in a long series of calls, but that'd be ridiculous). If you want to upload interleaved vertex data, you have to interleave it on the CPU, then upload it.
And setting the strides to 0 doesn't make this work. Well, it doesn't make it work correctly. Your base offsets are still wrong, relative to the data you actually uploaded. You'll get the correct position data, but the colors and texture coordinates will be wrong.
Upvotes: 2