1

Can I get a more overall/general description of this?

I've been trying to research these things all week, but I only come into super technical explanations or examples.

Could somebody explain the overall process or goal of these VAO's? Maybe outline a bit of a "step-by-step" flowchart for setting up a VAO in OpenGL?

I've never been someone who learns by examples... so all the things I've found online have been really unhelpful so far.

genpfault
  • 51,148
  • 11
  • 85
  • 139
user83676
  • 339
  • 1
  • 9
  • 15
  • This has been asked in a similar form many times before. See for example my answer here: http://stackoverflow.com/questions/26552642/when-is-what-bound-to-a-vao/26559063#26559063. Or here: http://stackoverflow.com/questions/26228498/glvertexattribpointer-overwrite/26229019#26229019. – Reto Koradi Feb 02 '15 at 04:34
  • 1
    I've found that this concept isn't actually covered very well at all, having recently gotten my head around it myself. There is information about it but it is fragmented and either doesn't appear when searched or is buried under substantial noise. – Francis Feb 03 '15 at 21:44

4 Answers4

6

Your Vertex Buffer Objects (VBOs) contain the vertex data. You set up attribute pointers which specify how that data should be accessed and interpreted in order to draw a vertex - how many components are there to each vertex, how are they stored (GL_FLOAT for example) etc.

The Vertex Array Object (VAO) saves all these attributes. Their purpose is to allow you to set up these attributes once and then restore them with one state change whenever you need to use them.

The advantage of this is you can easily set up multiple states and restore them - if I want to draw a cube and a triangle these are two different states - I create a VAO for each and the VAO saves the state for each of them. When I want to draw the cube, I restore the state for the cube only.

Setup

Setup has four steps:

  1. Create the VAO
  2. Bind the VAO
  3. Set up the state
  4. Unbind the VAO

Creating a VAO is very simple:

GLuint vao_name;
glGenVertexArrays(1, &vao_name);

This will generate one vertex array, and store it's name in vao_name.

Once your VAO is created you need to bind it:

glBindVertexArray(vao_name);

Now, any changes you make to the attribute pointers or bindings to the element array buffer will be saved. This is a call to any of the following:

  1. glVertexAttribPointer(...)
  2. glEnableVertexAttribArray(...)
  3. glDisableVertexAttribArray(...)
  4. glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ...)

Whenever you make one of these calls, the corresponding state is saved in the currently bound VAO. And when you later bind the VAO again, the state is restored.

Once you have set up the state you can unbind the VAO. Do this by binding VAO 0:

glBindVertexArrays(0);

You could also bind a different VAO and set up a different state for that. When this happens it is safe to make changes to the attribute pointers without disrupting your previous state.

Drawing

When you want to draw something all you have to do is restore the VAO:

glBindVertexArray(cube_vao)
glDrawArrays(GL_TRIANGLES, 0, 36);

glBindVertexArray(triangle_vao);
glDrawArrays(GL_TRIANGLES, 0, 3);

glBindVertexArray(0);                //Unbind the VAO

Edit:

These are some answers that helped me when I was trying to understand VAOs: glVertexAttribPointer overwrite, glVertexAttribPointer clarification, When should glVertexAttribPointer be called?

Also, the OpenGL specification explains it well once you've got your head around the basics: https://www.opengl.org/registry/

Community
  • 1
  • 1
Francis
  • 1,151
  • 1
  • 13
  • 29
  • That's pretty liberal borrowing from previous answers. I'm not going to flag this for plagiarism, but it's really borderline. In the future, please write the content yourself, and don't copy from other people without attribution. – Reto Koradi Feb 03 '15 at 03:53
  • @RetoKoradi I found most of the information about VAOs is sparsely distributed so I answered based off what I've picked up from multiple sources. I have tried to track down some of the contributing sources I used to build this answer, I think one of them was yours which would explain why parts of it were similar. This was my first time answering so if I've made a few blunders that's probably why. Hopefully this is more in line with community expectations now. – Francis Feb 03 '15 at 21:02
1

The VAO holds all information about how to read the attributes from the VBOs.

This includes for each attribute, which VBO it is in; the offset, the stride, how it is encoded (int, float, normalized or not), how many values per attribute. In other words the parameters of glVertexAttribPointer (and the bound GL_ARRAY_BUFFER at the time of the call.

It also holds the element array buffer that holds the indexes.

ratchet freak
  • 47,288
  • 5
  • 68
  • 106
0

For what VAO's are, see @ratchet-freak's answer.

As for the goal of VAO's, it's a matter of improving performance by allowing one single state change to setup all vertex attributes bindings, which not only means fewer function calls but also more opportunity for the OpenGL implementation to optimize for this state as a whole.

Shadocko
  • 1,186
  • 9
  • 27
0

For VAO, an understanding of VBOs and Shader is a pre-requisite. VAOs provide a way to “pre-define” vertex data and its attributes.

One way to understand is to draw with VBOs and then draw the same with VAOs. You will notice that it is similar to drawing with VBOs, except that it is first "saved" in a VAO for later use. Subsequently, the VAO is made active to actually draw the saved state.

See VBO, Shader, VAO for a fairly good example.

ap-osd
  • 2,624
  • 16
  • 16