GL_ARB_vertex_array_object

I installed 180 nvidia drivers to play a bit with the new extensions :smiley:

First try … first failure …
How are we supose to use VAOs?

Here is how I did:

Create a vertex object:


glGenVertexArrays(1, &positionArrayName);
glBindVertexArray(positionArrayName);
glVertexAttribPointer(positionBufferAttrib, 2, GL_FLOAT, GL_FALSE, 0, 0);

Create a buffer object:


glGenBuffers(1, &positionBufferName);
glBindBuffer(GL_ARRAY_BUFFER, positionBufferName);
glBufferData(GL_ARRAY_BUFFER, PositionSize, PositionData, GL_STATIC_DRAW);

Draw:


glBindVertexArray(positionArrayName);
glBindBuffer(GL_ARRAY_BUFFER, positionBufferName);
glEnableVertexAttribArray(positionBufferAttrib);
	glDrawArrays(GL_TRIANGLES, 0, VertexCount);
glDisableVertexAttribArray(positionBufferAttrib);

Result:
Black screen …

any idea?

I make something working but … I don’t understand!

What I would like to do it is something like:

A: Create a single vertex array object. (VAO)
B: Create several buffer objects. (BO)
C: Bind the VAO
D: Loop over all BOs by binding them as array buffer object and draw.

This results to crashes.

If I unbind a buffer object it just crashes … (even at creation stage!)

are function pointers resolved? should be != NULL.

Oki I get it all … I’m a bit disappointed by this extension …

This is nice:


for(std::size_t i = 0; i < positionArrayName.size(); ++i)
{
  glBindVertexArray(positionArrayName[i]);
  glDrawArrays(GL_TRIANGLES, 0, VertexCount);
}
glBindVertexArray(0);

But I was expecting a feature that allow fast buffer bind not a calls wrapper.

I would like somting like this:


glBindVertexArray(positionArrayName);
for(std::size_t i = 0; i < positionBufferName.size(); ++i)
{
  glActiveArray(GL_ARRAY0);
  glBindBuffer(positionBufferName[i]);
  glDrawArrays(GL_TRIANGLES, 0, VertexCount);
}
glBindVertexArray(0);

Or even better the direct state access way:


glBindVertexArray(positionArrayName);
for(std::size_t i = 0; i < positionBufferName.size(); ++i)
{
  "glVertexArrayBindBuffer"(positionArrayName, GL_ARRAY0, positionBufferName[i]);
  glDrawArrays(GL_TRIANGLES, 0, VertexCount);
}
glBindVertexArray(0);

Vertex buffer objects? i get it, should be an array.

But I was expecting a feature that allow fast buffer bind not a calls wrapper.

I would like somting like this:

The point of VAO is to get rid of the overhead of calling the gl*Pointer calls when using buffer objects. So the VAO must naturally store the buffer objects that the pointers are bound to.

Yes, but could they be improved to allow changing buffers? Seams possible to me.

One pattern with VAO might be to create a limited set of (ring) buffers (with a correspondingly limited set of formats) - pretty common nowadays. You could, at least in theory, utilize a single VAO for the whole enchilada.

Steps to creating and using a VAO are roughly

// Create vertex buffer
uint vb;
GenBuffers(1, &vb);
BindBuffer(…);
BufferData(…);
BindBuffer(0);

// Create vertex array object
uint vao;
GenVertexArrays(1, &vao);

// Establish vertex array buffer and format
BindVertexArray(vao);
BindBuffer(VERTEX_ARRAY_BUFFER, vb);
VertexAttribPointer(0, …);
VertexAttribPointer(1, …);
VertexAttribPointer(2, …);

BindBuffer(0);
BindVertexArray(0);

// Then to draw…
BindVertexArray(vao);
DrawArrays(…);
BindVertexArray(0);

I’m not exactly sure what the ring buffer patter would look like in GL3, but the new buffer mapping API looks like a good candidate for some trial and error…

So you mean using few buffers but big ones and put all the meshes with the same format in this buffer?

I believe the problem with your example code (first post) is that you’re not calling VertexAttribPointer after binding the VBO. Remember, VertexAttribPointer latches whatever is currently bound to ARRAY_BUFFER. i.e. it should be:

glGenVertexArrays(1, &positionArrayName);
glGenBuffers(1, &positionBufferName);
glBindVertexArray(positionArrayName);
glBindBuffer(GL_ARRAY_BUFFER, positionBufferName);
glBufferData(GL_ARRAY_BUFFER, PositionSize, PositionData, GL_STATIC_DRAW);
glVertexAttribPointer(positionBufferAttrib, 2, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(positionBufferAttrib);
glDrawArrays(GL_TRIANGLES, 0, VertexCount);

> Yes, but could they be improved to allow changing buffers?

This is legal and should work.