A Vertex Array Object (VAO) is an OpenGL object. However, unlike a Buffer Objects which contains storage, a VAO does not. Instead, a VAO is a container for Vertex Buffer objects (VBO).
Why use a VAO?
Let's say that you need to render 12 different characters each with their own data type, offset, etc. All of this information must be prepared before it is rendered. This is a lot of states to set and a lot of error checking that the driver will have to do.
This is where a VAO can help organize all of this information. A VAO is a container that stores all the states needed for rendering. It stores the information of vertex-attribute as well as the buffer object.
Now, if you recall, before an OpenGL Object can be used, it must first be created and bound. Thus, before you can use a VAO, you have to create it and Bind it to the OpenGL Context.
Using a Vertex Array Object is quite simple. We create and bind a VAO before the creation of an OpenGL buffer.
Here I have outlined the 11 steps required for rendering in OpenGL:
- Generate a VAO (glGenVertexArrays): Informs OpenGL to create a VAO.
- Bind the VAO (glBindVertexArray): Informs OpenGL to bind a VAO.
- Generate a VBO (glGenBuffers()): Informs OpenGL to create a Buffer.
- Bind the VBO (glBindBuffer()): Informs OpenGL to use this buffer for subsequent operations.
- Buffer Data (glBufferData() or glBufferSubData()): Informs OpenGL to allocate and initialize sufficient memory for the currently bound buffer.
- Get Location of Attributes (glGetAttribLocation()): Get location of attributes in current active shader.
- Get Location of Uniform (glGetUniformLocation()): Get location of Uniforms in currect active shader.
- Enable (glEnableVertexAttribArray()): Enable the attribute locations found in the shader.
- Set Pointers (glVertexAttribPointer()):Informs OpenGL about the types of data in bound buffers and any memory offsets needed to access the data.
- Draw (glDrawArrays() or glDrawElements()): Informs OpenGL to render a scene using data in currently bound and enabled buffers.
- Delete (glDeleteBuffers()): Tell OpenGL to delete previously generated buffers and free associated resources.
Preparing a buffer with a VAO is simply done as shown above. Before we create an VBO, we create and bind a VAO (steps 1-2). The Vertex Array binding occured in step 2.