PDA

View Full Version : Questions on VAOs



zhugh
05-11-2011, 03:11 PM
Hi all,

I understand that VBOs store vertex data and that attributes define how VBO data should be interpreted. I've read that VAOs store the bindings between VBOs and attributes, but I'm still having trouble with them.

1. How do you decide which VBOs/attributes should be placed in one VAO and which should be placed in another? Is it a good idea to create one VAO per model object?

2. For performance purposes, it seems like a good idea to place a lot of data in one VBO (colors, coordinates, normals, etc.) and associate the VBO with multiple attributes. In this case, should this large VBO have its own VAO? Or should multiple VBOs be placed in a VAO?

3. My OpenGL code compiles with and without VAO code (i.e. glGenVertexArrays, glBindVertexArray). Does this mean that I'm using a single VAO? Is this bad?

4. I've read that VAOs allow you to reuse attribute data for multiple VBOs. Does that mean that every VBO associated with a VAO has to use the same attributes?

5. At what point in the application does VAO data get transferred to the GPU?

Thanks in advance. I've read the OpenGL SuperBible and the OpenGL wiki, but I'm still pretty confused on the VAO subject.

Zack

Kopelrativ
06-11-2011, 03:29 PM
I also tried to understand this, but failed.

I am trying to port a program using VAO:s to an environment where they are not supported. At least glGenVertexArrays is 0 (using glew.h), even though it is OpenGL version 3.3.

What is the purpose of VAO:s, why do you want to use them?

If you can't use them, what is the work-around?

The OpenGL documentation for glGenVertexArrays() is not helpful, it gives no clue. The wiki at http://www.opengl.org/wiki/Vertex_Array_Object adds a little more information (save state), and http://www.opengl.org/wiki/Vertex_Specification says that VAO:s are required. This is a surprise to me, as I use VBO:s but not VAO:s today.

My guess is that using VAO:s means you only have to do glVertexAttribPointer() once, and then get the same mapping back with glBindVertexArray()?

Kopelrativ
06-11-2011, 03:45 PM
Reading the documentation for glVertexAttribPointer, you can find:

"When a generic vertex attribute array is specified, size, type, normalized, stride, and pointer are saved as vertex array state, in addition to the current vertex array buffer object binding."

I am not sure what is meant by "is specified". The index argument "Specifies the index of the generic vertex attribute to be modified", is that it?

Again, I have the feeling that what is really meant should be "When a vertex array object is specified..."?

The follow-up question (repeated) then is, for how long is the size, type, etc saved if no VAO is used?

Aleksandar
06-12-2011, 02:00 AM
VAO is a container. It contains vertex array state on the client side. The main purpose is to alleviate simultaneous change of a large set of array states.

Do you need to use VAO? No, unless you are using core profile on AMD cards. Although the spec is explicit that VAOs must be used, using heavy artillery to kill ants is not very wise. NVIDIA, as more pragmatic implementer of OpenGL, doesn't require VAO usage. Furthermore, there is more efficient way to achieve higher efficiency on NV called Bindless. On the other hand, even if VAOs are required, you can make just one (default) and use it through the whole application. Don't ask me if it is efficient. :)
It depends on the way drivers implement it. But for small number of attributes being changed from single drawing to another, individual attribute enabling/disabling is probably more efficient.

Alfonse Reinheart
06-12-2011, 03:28 AM
Do you need to use VAO? No, unless you are using core profile on AMD cards. Although the spec is explicit that VAOs must be used, using heavy artillery to kill ants is not very wise. NVIDIA, as more pragmatic implementer of OpenGL, doesn't require VAO usage.

It should be noted that "use VAO" can mean as little as adding this to your initialization routines:



GLuint temp;
glGenVertexArrays(1, &temp);
glBindVertexArray(temp);