-2

I thought the VAO (Vertex Array Object) was supposed to store state like the vertex attributes. When I create a VBO I specify my vertex attributes:

glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)nullptr);
glEnableVertexAttribArray(0);
// And so on

If I bind another VBO I have to call glVertexAttribPointer and glEnableVertexAttribArray three times, that's for every time I switch my VBO. I only have one VAO, I never change it. Is there something wrong? I only use one vertex layout and I'm not understanding what the VAO does if it loses this information each time I switch. Is it only one VBO per VAO?

Zebrafish
  • 11,682
  • 3
  • 43
  • 119

1 Answers1

2

If you don't want to respecify glVertexAttribPointer before calling a glDraw* function then you need several VAOs not just one. I think you are confusing the what a VBO and a VAO are. A VBO is just an inert piece of memory that contains data. A VAO contains all the information that OpenGL requires to draw a mesh, that includes:
- a reference to the Buffer object containing your vertex data (commonly named VBO)
- a reference to the Buffer object containing your vertex indices (if you are using glDrawElements*)
- the index of the different vertex attributes you are going to use and their layout in the Buffer object containing your vertex data (specified with glEnableVertexAttribArray and glVertexAttribPointer)

So basically for each mesh you are going to draw you need to prepare a corresponding vao:

// at scene preparation time
glBindVertexArray(vaoA); // the following functions will only affect vaoA
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index_buffer_of_meshA);
glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer_of_meshA);
foreach attrib of meshA
  glEnableVertexAttribArray(***);
  glVertexAttribPointer(***)
glBindVertexArray(0)

glBindVertexArray(vaoB); // the following functions will only affect vaoB
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index_buffer_of_meshB);
glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer_of_meshB);
foreach attrib of meshB
  glEnableVertexAttribArray(***);
  glVertexAttribPointer(***)
glBindVertexArray(0)

//And now at render time:
void render()
{
   glBindVertexArray(vaoA);
   glDrawElements(***);

   glBindVertexArray(vaoB);
   glDrawElements(***);
}

for more info check: https://www.opengl.org/wiki/Vertex_Specification

Yvain
  • 96
  • 2