问题
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?
回答1:
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.
来源:https://stackoverflow.com/questions/12642167/how-does-vao-keep-buffer-bindings