I am struggling to understand how exactly VAO is handling buffer mapping. What I'm doing could be described in this pseudocode:
SetUp:
BindVAO
BindArrayBuffer
glBufferData(GL_ARRAY_BUFFER, ExpectedMaxCount, NULL, GL_DYNAMIC_DRAW);//Allocate storage
glEnableVertexAttribArray
glVertexAttribPointer
BindElementBuffer
Allocate storage (no data yet)
UnbindVAO
UnbindArrayBuffer
UnbindElementBuffer
Draw:
SubArrayAndElementDataIfNeeded
BindVAO
DrawElements
Is this correct that when DrawElements is called OpenGL uses bound VAO to resolve array and element buffer bindings? After a Draw call the bound array buffer is 0, but element buffer is still the one that was used to Draw.
Is it mandatory to allocate buffer memory during VAO setup? Would VAO be invalidated if BufferData was called after setup?
No. You can bind a VBO before you bind a VAO, and fill the VBO with data using glBufferData() . A VBO is essentially just a dumb data container. But any kind of vertex attribute setup tracked in the VAO can only be done after the VAO is bound.
A Vertex Array Object (VAO) is an OpenGL Object that stores all of the state needed to supply vertex data (with one minor exception noted below). It stores the format of the vertex data as well as the Buffer Objects (see below) providing the vertex data arrays.
Buffer Objects are OpenGL Objects that store an array of unformatted memory allocated by the OpenGL context (AKA the GPU). These can be used to store vertex data, pixel data retrieved from images or the framebuffer, and a variety of other things.
Thankfully, element buffer objects work exactly like that. An EBO is a buffer, just like a vertex buffer object, that stores indices that OpenGL uses to decide what vertices to draw. This so called indexed drawing is exactly the solution to our problem.
I am struggling to understand how exactly VAO is handling buffer mapping.
Be very careful when using the word "mapping" around "buffers"; that has a specific meaning when dealing with buffer objects, one that you probably don't intend.
Is this correct that when DrawElements is called OpenGL uses bound VAO to resolve array and element buffer bindings? After a Draw call the bound array buffer is 0, but element buffer is still the one that was used to Draw.
One has nothing to do with the other. A Vertex Array Object, as the name implies, contains all of the state that is necessary to pull vertex data from arrays. When you bind one, all of that state comes back into the context.
The reason the "bound array buffer" is 0 after the call is because it was 0 before the call. Draw calls do not change OpenGL state.
Furthermore, you seem to have fallen for the GL_ARRAY_BUFFER
trap. The GL_ARRAY_BUFFER
binding only matters to three functions: glVertexAttribPointer
, glVertexAttribIPointer
, and glVertexAttribLPointer
(see a pattern?). These are the only functions that look at that binding. What they do is take the buffer that is bound at the time these functions are called and associates that buffer with the current VAO. GL_ARRAY_BUFFER
is not part of the VAO's state. A buffer object becomes associated with a VAO only when you call one of those three functions. Once you make that call, you can bind whatever you want to GL_ARRAY_BUFFER
.
GL_ELEMENT_ARRAY_BUFFER
is part of the VAO's state.
Is it mandatory to allocate buffer memory during VAO setup? Would VAO be invalidated if BufferData was called after setup?
Technically no, but it's good form to not use a buffer until it has storage. Especially if they're static buffers.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With