I've been reading a bit about how VAOs work with VBOs. As far as I understand, the VAO only stores state information about a VBO when we call glVertexAttribPointer. My question is, when does it store state about an EBO (for indexed drawing), does it save state for both when glVertexAttribPointer is called?
//Vertices of the rectangle
std::vector<GLfloat> vertices
{
0.5f, 0.5f, 0.0f, // Top Right
0.5f, -0.5f, 0.0f, // Bottom Right
-0.5f, 0.5f, 0.0f, // Top Left
-0.5f, -0.5f, 0.0f, // Bottom Left
};
//Indices of the triangle
std::vector<GLuint> indices
{
0, 1, 3,
0, 3, 2
};
GLuint VAO, VBO, EBO;
glGenVertexArrays(1, &VAO);
glGenBuffers(1, &VBO);
glGenBuffers(1, &EBO);
glBindVertexArray(VAO); //Bind the VAO
//Bind the buffers
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(GLfloat), &vertices[0], GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (GLvoid*)0);
glEnableVertexAttribArray(0);
glBindVertexArray(0); //Unbind the VAO
//Supply Index Buffer information
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(GLuint), &indices[0], GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
//Custom shader class that stores the program to be used at render time
Shader shader("..path_to_shader\\shaders\\vertexshader.vert", "..path_to_shader\\shaders\\fragmentshader.frag");
while (!glfwWindowShouldClose(window))
{
glUseProgram(shader.Program());
glBindVertexArray(VAO); //Bind the VAO to draw.
glClearBufferfv(GL_COLOR, 0, &color[0]);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, nullptr);
glfwPollEvents();
glfwSwapBuffers(window);
glBindVertexArray(0);
glUseProgram(0);
}
Best Answer
The
GL_ELEMENT_ARRAY_BUFFER
binding becomes part of the VAO state when you bind it with:while a VAO is bound.
Note that it's also legal to bind the element array buffer without a VAO bound. This is only really useful to fill it with data, using
glBufferData()
or similar calls. Since in the Core Profile you need a VAO bound for any draw calls, you need to bind the element array buffer you want to use for rendering while the VAO is bound.Regarding your code, the sequence of calls you are using will not give the desired result. Here are the critical calls you have, with comments explaining the result:
To get this working, the easiest solution is that you change the order of the last two calls:
Just to explore this some more, the following sequence would also work:
Note that in this sequence, you have to bind the element array buffer again after binding the VAO, because the element array buffer binding in the VAO state will override the current binding as soon as you bind the VAO.