简体   繁体   中英

OpenGL Indexed VBO Rendering

I am getting a completely black screen while trying to draw a simple square in OpenGL. These methods are called before creation of the buffers:

glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glOrtho(0.0f, windowX, windowY, 0.0f, 1000.0f, 0);

I am creating the buffers like so:

std::vector<unsigned int> indices;
std::vector<unsigned int> vertices;    

vertices.push_back(0);
vertices.push_back(0);
vertices.push_back(0);

vertices.push_back(100);
vertices.push_back(0);
vertices.push_back(0);

vertices.push_back(100);
vertices.push_back(100);
vertices.push_back(0);

vertices.push_back(0);
vertices.push_back(100);
vertices.push_back(0);


indices.push_back(0);
indices.push_back(1);
indices.push_back(2);

indices.push_back(2);
indices.push_back(3);
indices.push_back(0);

glGenBuffers(1, &verticesbuffer);
glBindBuffer(GL_ARRAY_BUFFER, verticesbuffer);
glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(vertices[0]), &vertices[0], GL_STATIC_DRAW);

glGenBuffers(1, &indicesbuffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indicesbuffer);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(indices[0]), &indices[0], GL_STATIC_DRAW);

Display Function:

glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);

glBindBuffer(GL_ARRAY_BUFFER, verticesbuffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indicesbuffer);
glVertexPointer(3, GL_INT, 0, &vertices[0]);

glColor3f(1, 0, 0);

glEnableClientState(GL_VERTEX_ARRAY);

glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_INT, &indices[0]);

glDisableClientState(GL_VERTEX_ARRAY);

glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);

I have started using AMD GPU PerfStudio to look through my program's drawing calls, and at the glDrawElements() call, PerfStudio shows me the data behind the vertex and index buffers (the index buffer is apparently completely empty, while the vertex buffer only has one point set to x = y = z = 3.40282e+038 (maximum float value)):

Unable to map element array buffer for reading.
GL_VERTEX_ARRAY_SIZE: 3
GL_VERTEX_ARRAY_TYPE: GL_INT
GL_VERTEX_ARRAY_STRIDE: 0
GL_VERTEX_ARRAY_POINTER: 0x0C30F2A8
GL_VERTEX_ARRAY_BUFFER_BINDING: 1
BufferState
GL_BUFFER_SIZE: 0
GL_BUFFER_USAGE: GL_STATIC_DRAW
GL_BUFFER_ACCESS: GL_READ_WRITE
GL_BUFFER_MAPPED: GL_FALSE
GL_BUFFER_MAP_POINTER: 0x00000000

Obviously some of these values are incorrect, I just can't figure out why they didn't come out as they were intended.

This must have come up before, but I couldn't find a clear duplicate with a quick search.

The problem is here:

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indicesbuffer);
...
glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_INT, &indices[0]);

When a GL_ELEMENT_ARRAY_BUFFER is bound during a glDrawElements() call, which is the case in your code, the last argument of glDrawElements() is an offset into the index buffer . What you are passing is the CPU address of the index buffer.

If you want to use the index buffer from its start, which is the right thing to do in your case, the offset should be 0:

glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_INT, 0);

Very similarly, this is also broken:

glBindBuffer(GL_ARRAY_BUFFER, verticesbuffer);
...
glVertexPointer(3, GL_INT, 0, &vertices[0]);

Again, when a GL_ARRAY_BUFFER is bound, the last argument to glVertexPointer() is an offset into the buffer. So this should be:

glVertexPointer(3, GL_INT, 0, 0);

BTW, using integers for vertex coordinates is rather unusual in OpenGL. It looks like it's supported, so it should work. But it is much more common, and possibly more efficient, to use GLfloat / GL_FLOAT for the coordinates.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM