3
\$\begingroup\$

I've just started digging through OpenGL and GLSL, and now stumbled on something I can't get my head around this one!? I've stepped back to loading a simple cube and using a simple shader on it, but the result is triangles drawn incorrectly and/or missing. The code I had working perfectly on meshes, but was attempting to move to using VAOs so none of the code for storing the vertices and indices has changed.

https://i.stack.imgur.com/RxxZ5.jpg

https://i.stack.imgur.com/zSU50.jpg

What I have for creating the VAO and buffers is this

//Create the Vertex array object
glGenVertexArrays(1, &vaoID);

// Finally create our vertex buffer objects
glGenBuffers(VBO_COUNT, mVBONames);

glBindVertexArray(vaoID);

    // Save vertex attributes into GPU
    glBindBuffer(GL_ARRAY_BUFFER, mVBONames[VERTEX_VBO]);

    // Copy data into the buffer object
    glBufferData(GL_ARRAY_BUFFER, lPolygonVertexCount*VERTEX_STRIDE*sizeof(GLfloat), lVertices, GL_STATIC_DRAW);

    glEnableVertexAttribArray(pos);
    glVertexAttribPointer(pos, 3, GL_FLOAT, GL_FALSE, VERTEX_STRIDE*sizeof(GLfloat),0);

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mVBONames[INDEX_VBO]);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, lPolygonCount*sizeof(unsigned int), lIndices, GL_STATIC_DRAW);

glBindVertexArray(0);

And the code for drawing the mesh.

glBindVertexArray(vaoID);
glUseProgram(shader->programID);

GLsizei lOffset = mSubMeshes[pMaterialIndex]->IndexOffset*sizeof(unsigned int);
const GLsizei lElementCount = mSubMeshes[pMaterialIndex]->TriangleCount*TRIAGNLE_VERTEX_COUNT;
glDrawElements(GL_TRIANGLES, lElementCount, GL_UNSIGNED_SHORT, reinterpret_cast<const GLvoid*>(lOffset));

// All the points are indeed in the correct place!?
//glPointSize(10.0f);
//glDrawElements(GL_POINTS, lElementCount, GL_UNSIGNED_SHORT, 0);

glUseProgram(0);
glBindVertexArray(0);

Eyes have become bleary looking at this today so any thoughts or a fresh set of eyes would be greatly appreciated.

\$\endgroup\$
1
  • 1
    \$\begingroup\$ Your lOffset and glBufferData use unsigned int but your glDrawElements uses GL_UNSIGNED_SHORT. Shouldn't they be the same type? \$\endgroup\$
    – S22h
    Oct 5, 2012 at 10:43

2 Answers 2

6
\$\begingroup\$

The size of your GL_ELEMENT_ARRAY_BUFFER looks wrong:

lPolygonCount*sizeof(unsigned int)

Based on the rest of your code it's highly probable that should be:

lElementCount*sizeof(unsigned short)

You're also binding mVBONames[INDEX_VBO] as your GL_ELEMENT_ARRAY_BUFFER, which is going to overwrite the data you previously loaded to your GL_ARRAY_BUFFER - perhaps you meant to use mVBONames[INDEX_IBO] or something similar instead?

Other than that your VAO code looks good.

\$\endgroup\$
1
  • \$\begingroup\$ Thanks for the reply, I've given this another stab this morning but with no avail. I tried hardcoding the size of the cube directly after your suggestion of using the lElementCount*sizeof(unsigned short) but no joy there. The INDEX_VBO I may have named wrong but actually is the object for the index buffer object and renders fine when not using the VAOs at all. Or is doing that wrong like you said and overwriting data? I've tried using the rendering without any of the VAO bindings and it renders correctly? Cheers \$\endgroup\$
    – Bleary
    Sep 17, 2012 at 7:51
0
\$\begingroup\$

The element array is not part of the VAO. Only the vertex attribute arrays get saved to it. Make sure to bind the element array buffer before the draw call.

glBindVertexArray(vao);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index_vbo);
glDrawElements(...);
\$\endgroup\$
3
  • 3
    \$\begingroup\$ -1: "The element array is not part of the VAO." This is completely wrong and is a common misconception. The standard is very clear on this. Looking at the 4.3 spec, on page 308 (PDF-page 329), it says that VAOs contain the state listed in tables 23.3 and 23.4. And if you look at table 23.4, it clearly has GL_ELEMENT_ARRAY_BUFFER_BINDING in it. VAOs do contain the element array buffer. \$\endgroup\$ Oct 6, 2012 at 7:30
  • 1
    \$\begingroup\$ The spec says one thing; implementations do another. Apple's VAO extension doesn't bind the element array, nor does Mesa with intel's drivers and the ARB VAO extension (causing rather spectacular crashes). \$\endgroup\$
    – ccxvii
    Oct 29, 2012 at 23:56
  • \$\begingroup\$ The ARB_vao extension and the core 3.0 behavior are very clear on this. GL_ELEMENT_ARRAY_BUFFER_BINDING is in the tables that it says are part of VAO state. Therefore, they are VAO state. If some implementations don't do this correctly, then they are broken and need to be fixed. Apple's VAO spec predates buffer objects, so the interactions with them are not specified. \$\endgroup\$ Oct 30, 2012 at 0:56

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .