40
\$\begingroup\$

I've just started out with OpenGL I still haven't really understood what Vertex Array Objects are and how they can be employed.

If Vertex Buffer Object are used to store vertex data (such as their positions and texture coordinates) and the VAOs only contain status flags, where can they be used? What's their purpose?

As far as I understood from the (very incomplete and unclear) GL Wiki, VAOs are used to set the flags/statūs for every vertex, following the order described in the Element Array Buffer, but the wiki was really ambiguous about it and I'm not really sure about what VAOs really do and how I could employ them.

\$\endgroup\$

4 Answers 4

52
\$\begingroup\$

I think you will understand their purpose better with a sample. By reading the comments you will understand how VAOs are used.

// BEGIN INITIALIZATION
// Define some vertex data 
struct Vertex {
  GLfloat position[3];
  GLfloat texcoord[2];
};
Vertex vertexdata[NUM_VERTS] = { ... };
GLubyte indexdata[NUM_INDICES] = { 0, 1, 2, ... };

// Create and bind a VAO
GLuint vao;
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);

// Create and bind a BO for vertex data
GLuint vbuffer;
glGenBuffers(1, &vbuffer);
glBindBuffer(GL_ARRAY_BUFFER, vbuffer);

// copy data into the buffer object
glBufferData(GL_ARRAY_BUFFER, NUM_VERTS * sizeof(Vertex), vertexdata, GL_STATIC_DRAW);

// set up vertex attributes
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, position));
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, texcoord));

// Create and bind a BO for index data
GLuint ibuffer;
glGenBuffers(1, &ibuffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibuffer);

// copy data into the buffer object
glBufferData(GL_ELEMENT_ARRAY_BUFFER, NUM_INDICES * sizeof(GLubyte), indexdata, GL_STATIC_DRAW);

// At this point the VAO is set up with two vertex attributes
// referencing the same buffer object, and another buffer object
// as source for index data. We can now unbind the VAO, go do
// something else, and bind it again later when we want to render
// with it.

glBindVertexArray(0);

// END INITIALIZATION

// BEGIN RENDER LOOP

// This is it. Binding the VAO again restores all buffer 
// bindings and attribute settings that were previously set up
glBindVertexArray(vao);
glDrawElements(GL_TRIANGLES, NUM_INDICES, GL_UNSIGNED_BYTE, (void*)0);

// END RENDER LOOP
\$\endgroup\$
2
  • 2
    \$\begingroup\$ Can I do this with GL_DYNAMIC_DRAW buffer data too? Would the rendering part just contain the glBindVertexArray(), glBufferData() and then glDrawElements()? \$\endgroup\$
    – Piku
    Commented Nov 30, 2011 at 10:52
  • \$\begingroup\$ How do you deal with normals in this example? I mean what if you add a GLfloat normal[3] in your Vertex class and want to upload the normals to client? \$\endgroup\$
    – linello
    Commented Apr 29, 2013 at 20:05
2
\$\begingroup\$

VAOs are useful, because you don't have to set up everytime all attributes. It should also be faster just bind one VAO rather then setting all attributes.

\$\endgroup\$
1
\$\begingroup\$

This is my favorite link: http://www.songho.ca/opengl/gl_vertexarray.html

It should help you get a better understanding of the differences between VAO and VBOs. Also, Id recommend reading a chapter in OpenGL superbible on this topic. It does a good job at explaining these basics at length and with examples.

\$\endgroup\$
2
  • 7
    \$\begingroup\$ The article you linked does not cover VAO's, only vertex arrays (which have been around a while longer). I'm puzzling over the specific differences between these two myself. \$\endgroup\$
    – Steven Lu
    Commented Jan 10, 2012 at 19:30
  • \$\begingroup\$ There is not much difference. The VAO just encapsulates all state regarding the vertex arrays and their usages and formats, except for the array data itself, which is stored in VBOs. But you're right in that this answer (or the link) doesn't really talk about VAOs. \$\endgroup\$ Commented Jan 18, 2012 at 19:39
0
\$\begingroup\$

Lecture 9 Here http://nccastaff.bournemouth.ac.uk/jmacey/CA1/index.html has some stuff about it (as do the rest of my notes) and If you look at the NGL library on the same site I have a class that wraps up the behaviour of a VAO

\$\endgroup\$

You must log in to answer this question.