VAO state simplified
2017-01-28 Permalink
There is a common confusion of what state VAOs hold. Some of the non-DSA functions used to setup the VAO modify the global state instead, further complicating the matter.
OpenGL specification contains detailed tables documenting what state VAOs are made of. However, I find them not as comprehensible. Instead I prefer to present the state in a way akin to a C structure:
struct VertexArrayObject { // VertexArrayElementBuffer uint element_buffer; struct Binding { // VertexArrayVertexBuffers uint buffer; intptr offset; sizei stride; // VertexArrayBindingDivisor uint divisor; } bindings[]; struct Attrib { // VertexArrayAttribBinding uint binding; // This is an index into bindings[] // EnableVertexArrayAttrib bool enabled; // VertexArrayAttrib*Format int size; enum type; boolean normalized; boolean integer; boolean long; uint relativeoffset; } attribs[]; };
The functions in the comments are the DSA functions that should be used to setup the corresponding state. If you use the older non-DSA functions, you should remember that glBindBuffer(GL_VERTEX_ARRAY)
does not modify the VAO state, it’s glVertexAttribPointer
which sets the VAO binding to the current GL_VERTEX_ARRAY
value.
Note also that the VAO is a container object. Thus it prolongs the lifetime of the buffer objects that it points to. Therefore you can delete the buffers the moment you bind them to the VAO.[1]
Footnotes
If the VAO is currently bound then unbind the VAO first. Otherwise
glDeleteBuffers
unbinds the buffer from the VAO. It’s not an issue if you use DSA to setup your VAOs.