Element array association with vertex array

I have a few VERY basic questions about indexed drawing…
How does a GL_ELEMENT_ARRAY_BUFFER “know” which GL_ARRAY_BUFFER it is associated with? I.e. how does OpenGL know which vertices are referenced by the indices? E.g. in something similar to Example 3.5 from the Red Book:

// Four vertices
static const GLfloat vertex_positions[] =
   -1.0f, -1.0f, 0.0f, 1.0f,
   1.0f, -1.0f, 0.0f, 1.0f,
   -1.0f, 1.0f, 0.0f, 1.0f,
   -1.0f, -1.0f, 0.0f, 1.0f,
// Three indices (we’re going to draw one triangle at a time
static const GLushort vertex_indices[] =
   0, 1, 2
 // Set up the element array buffer
 glGenBuffers(1, ebo);
 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo[0]);
 // Put indices into element array buffer
         sizeof(vertex_indices), vertex_indices, GL_STATIC_DRAW);

 // Set up the vertex attributes
 glGenVertexArrays(1, vao);       // Does this vao "know" about the ebo created above?

 glGenBuffers(1, vbo);
 glBindBuffer(GL_ARRAY_BUFFER, vbo[0]);
 // Put vertices into 
                    vertex_positions, GL_STATIC_DRAW);

When the code later draws the vertices, what should it “bind” to? Should it bind to ebo or to vao? Should it do this?

glBindVertexArray(vao[0]);   // Bind to VAO
glDrawElements(GL_TRIANGLES, 3, GL_SHORT, 0);

Or should it do this?

 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo[0]); // Bind to EBO
 glDrawElements(GL_TRIANGLES, 3, GL_SHORT, 0);


Read: When is the binding between a buffer object and a specific vertex array (e.g., VERTEX_ARRAY_BUFFER_BINDING_ARB) established?

I am not sure how to answer your question.
In my example (based on Example 3.5 in Red Book):

1. Generate the ebo
3. Put index data into GL_ELEMENT_ARRAY_BUFFER
4. Generate the vao
5. Bind vao
6. Generate vbo
7. Bind vbo to GL_ARRRAY_BUFFER
8. Put vertex data into GL_ARRAY_BUFFER

It isn’t associated with a particular one; it’s associated with all of them. If you’re doing an indexed rendering command, all attributes use the index buffer and thus use the same index.

Also, in core OpenGL, youc annot bind to the GL_ELEMENT_ARRAY_BUFFER binding point unless a VAO is bound. So you need to use a different binding when setting up the buffer’s data:

 glGenBuffers(1, ebo);
 glBindBuffer(GL_ARRAY_BUFFER, ebo[0]);
 // Put indices into element array buffer
         sizeof(vertex_indices), vertex_indices, GL_STATIC_DRAW);

The binding itself is meaningless here; you’re just binding the buffer to modify it.

To make it simple, the VAO does it for you. This is the purpose of VAO: it “contains” all the VBO (and thus the potential EBO) you had assigned it. When VAOs did not existed, you had to bind each VBO and the EBO before rendering. Now you just bind the VAO.

1 Like

This is incorrect. The binding to an attribute’s VBO is made during VertexPointer (etc), and it persists forever (as VERTEX_ARRAY_BUFFER_BINDING, etc) until another call to VertexPointer (etc) changes the binding.

VAOs wrap those bindings, so you can toggle all of them at once by binding another VAO.

Please read the documentation.