Question

I am currently learning OpenGL and VAO's are confusing me. As far as I understand VAO's are just encapsulating the state of VBO's.

Bind VAO
load buffer data
Disable VAO

and then you can draw it like

activate VAO
DrawArray ...
deactivate VAO

But I am not sure if this is really useful in practice. Let's say I have a really huge scene that I want to render. Maybe 10km² and I obviously don't want to load every object to the GPU at one time, I probably want to separate the scene into different chunks.

Now I am moving around and at one point I have to load another chunk of objects to the GPU right? But as far as I know I can't change a VAO and I would have to create a new VAO every time something changes in my scene.

So what in my scene would be a VAO? Would the entire scene be a VAO? Or would every object be a VAO?

And for me to have multiple VAO's doesn't make too much sense because I can't compose the VAO's together I can only draw them on top of each other like this

activate VAO1
DrawArray ...
deactivate VAO1

activate VAO2
DrawArray ...
deactivate VAO2
Was it helpful?

Solution 2

Your first statement:

As far as I understand VAO's are just encapsulating the state of VBO's.

is mostly correct, in that VBOs are the most stored type of buffer in an VAO, but any type of buffer associated with vertex processing (i.e., element arrays, indirect draw buffers, etc. depending upon which ones are supported by your version of OpenGL) are also contained within a VAO.

The reason for adding VAOs to the API was to reduce the number of functions calls required to swap data for different objects. In applications with multiple objects that require different sets of vertex attributes, before VAOs, you'd need to call glBindBuffer for each VBO (including element array buffers) that were required to render that object (the association of a vertex attribute location and a buffer is a property of that buffer, and not of a VAO, in case you ever had that question). VAOs allow all of those bindings to be encapsulated into a single object which can be bound with a single call to glBindVertexArray, as you mention.

You're also on the right track in swapping between VAOs. In your application's initialization (or whenever you need to add more objects), you'd create and initialize as many VAOs as required, and for each one, bind it, and populate it with all its relevant buffers. When you wanted to use one, you'd merely bind it. It's also worth noting that you can always update the data in a VBO using glBufferData or similar calls, and that operation will have no effects on the binding contained with the VAO associated with that buffer.

OTHER TIPS

You cannot enable or disable a VAO, they are a class of objects in OpenGL known as containers (same as FBOs). They provide the context for vertex array drawing operations and the state necessary to describe them. You most certainly can change a VAO, they are just state containers... bind it and then change one of the states it stores. Whether you use one VAO for your entire scene or multiple is up to you, but keep in mind in a core OpenGL 3.2 context, you cannot issue any vertex drawing commands without at least some VAO bound.

Also, VAOs have nothing to do with currently bound buffer objects per-se, except for the element array buffer. VAOs store vertex array pointers, which may be directly or indirectly (see: GL_ARB_vertex_attrib_binding) bound to a VBO, but the VAO does not care at all about what VBO is currently bound to GL_ARRAY_BUFFER. It is different for the element array buffer as I mentioned, VAOs do track the currently bound element array buffer so that a call to glDrawElements (...) will have consistent behavior merely by binding a VAO. Without this property, you would have to bind a VAO and then also bind an element array buffer before you could issue an indexed drawing operation.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top