Search code examples
vboopengl-3vao

VBO indexing in OpenGL 3.x


I'm initializing my VBO/VAO state in the following way, I'd like to know if this is the correct order of things because glDrawElements() give me a SIGSEGV. As far as I know vertex data and index data buffers are tied to te current bound VAO:

glGenVertexArrays(1, (GLuint*)&vaoId); // make VAO
glGenBuffers(2, (GLuint*)&vboIds); // make data and idx buffers

glBindVertexArray(vaoId);
glBindBuffer(GL_ARRAY_BUFFER, vboIds[0]);
glBufferData(GL_ARRAY_BUFFER, mumVertices * strideBytes, NULL, static_cast<GLenum>(usagePattern)); // numVertices == 4

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vboIds[1]);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, numElements * sizeof(cx_uint_t), NULL, static_cast<GLenum>(usagePattern)); // numElements == 6

Then, buffer data initialization from another point in code:

glBindVertexArray(vaoId);
glBindBuffer(GL_ARRAY_BUFFER, vboIds[0]);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vboIds[1]);

currentDataBuffer = glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY);
currentElemBuffer = glMapBuffer(GL_ELEMENT_ARRAY_BUFFER, GL_WRITE_ONLY);

// setup vertex data in 'currentDataBuffer' (coords, color):
// vert1: -100.0f,-100.0f, 0.0f,    1.0f, 1.0f, 1.0f, 1.0f
// vert2:  100.0f,-100.0f, 0.0f,    1.0f, 1.0f, 0.0f, 1.0f
// vert3:  100.0f, 100.0f, 0.0f,    0.0f, 1.0f, 0.0f, 1.0f
// vert4: -100.0f, 100.0f, 0.0f,    0.0f, 0.0f, 1.0f, 1.0f

// setup element data in 'currentElemBuffer':
// 0, 1, 3, 1, 2, 3

// shader attribs setup
glEnableVertexAttribArray(getAttribName("vert"));
glVertexAttribPointer(getAttribName("vert"), 3, GL_FLOAT, false, 7 * sizeof(cx_float_t), NULL);
glEnableVertexAttribArray(getAttribName("color"));
glVertexAttribPointer(getAttribName("color"), 4, GL_FLOAT, false, 7 * sizeof(cx_float_t), (cx_genptr_t)(3 * sizeof(cx_float_t)));

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

glBindVertexArray(0);

Now the rendering part:

glPushAttrib(GL_CURRENT_BIT | GL_ENABLE_BIT);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

glBindVertexArray(vaoId);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, NULL);
glBindVertexArray(0);

glPopAttrib();

I would really appreciate some help, thanks in advance.


Solution

  • You're correct in assuming that the GL_ELEMENT_ARRAY_BUFFER binding is tied to the VAO. That's exactly your problem. Looking at the end of your buffer initialization code:

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
    
    glBindVertexArray(0);
    

    Here you're unbinding the GL_ELEMENT_ARRAY_BUFFER while the VAO is still bound. This means that the current binding tracked in the VAO becomes 0.

    When you then bind the VAO for rendering:

    glBindVertexArray(vaoId);
    

    you don't have the index buffer bound.

    To fix this, simply remove the call that unbinds the GL_ELEMENT_ARRAY_BUFFER at the end of the buffer initialization code.