Search code examples
openglvertex-array-objectindex-buffer

Why should I bind the index buffer to draw elements with a VAO?


I use the following code to render a simple quad using a vertex array and an index buffer.

In the Vertex specification, I see

The index buffer binding is stored within the VAO.

But in my code, in the render loop, I need to bind the index buffer to see the quad.


The data:

float mesh[24] = {
        // pos           // color
          0, 0,  0,      1, 1, 0,
        -.5, 0,  0,      0, 1, 1,
        -.5, 0, .5,      1, 0, 1,
          0, 0, .5,      1, 1, 1
};
int indices[6] = {0, 1, 2, 0, 2, 3};

The initialization of the buffers:

GLuint vao{};
GLuint buffers[2]{};

glGenVertexArrays(1, &vao);
glBindVertexArray(vao);

glGenBuffers(2, buffers);
glBindBuffer(GL_ARRAY_BUFFER, buffers[0]);
glBufferData(GL_ARRAY_BUFFER, 24 * sizeof(float), mesh, GL_STATIC_DRAW);

glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void *)0);

glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void *)(3 * sizeof(float)));

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffers[1]);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, 6 * sizeof(int), indices, GL_STATIC_DRAW);

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

And in the main loop, I use:

glBindVertexArray(vao);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffers[1]); // Why this line is necessary ?
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, nullptr);
glBindVertexArray(0);

Why should I use glBindBuffer() with GL_ELEMENT_ARRAY_BUFFER in the render loop?


Solution

  • Why this line is necessary ?

    It is not necessary. However, the element buffer reference is stored in the VAO. Just remove glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);. This line breaks the binding of the index buffer and to the VAO.

    The Index Buffer (ELEMENT_ARRAY_BUFFER) binding is stored within the Vertex Array Object. When glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IBO) is called the element buffer object ID is stored in the currently bound Vertex Array Object. Therefore the VAO must be bound before the element buffer with glBindVertexArray(VAO).

    Unlike to the Index Buffer, the Vertex Buffer binding (ARRAY_BUFFER) is a global state.
    Each attribute which is stated in the VAOs state vector may refer to a different ARRAY_BUFFER. When glVertexAttribPointer is called the buffer which is currently bound to the target ARRAY_BUFFER, is associated to the specified attribute index and the ID of the object is stored in the state vector of the currently bound VAO.