Questions about VAOs

I’m trying to get into VAOs, and not everything is clear.
Suppose I have two buffers a and b. I bind a to GL_ARRAY_BUFFER and then I call glVertexAttribPointer. Then I bind b to GL_ARRAY_BUFFER.

  1. if I understand correctly the attribute I specified in the call to glVertexAttribPointer is linked to a. So when I call glDraw* buffer a will be used. Is it correct? And what happens to b, which is currently bound?
  2. what happens if I put some other data in a, that is, I call glBufferData again? I would assume the new data is used
  3. how about GL_ELEMENT_ARRAY_BUFFER? Is it not influenced at all?
  4. I read that glVertexAttribPointer returns an error if there is no GL_ARRAY_BUFFER, but only if pointer is not NULL. What is the reason?
  1. When you call glDraw*, the currently bound VAO will be used.

“And what happens to b, which is currently bound?” B will be used.

  1. I think you are confusing VAO and VBO. A VAO is the bound IBO/VBO and pointer definitions. It doesn’t concern itself with a IBO/VBO contents.

  2. A GL_ELEMENT_ARRAY_BUFFER (IBO) should be defined in your VAO as well.

  3. Which GL version?

  1. if I understand correctly the attribute I specified in the call to glVertexAttribPointer is linked to a. So when I call glDraw* buffer a will be used. Is it correct? And what happens to b, which is currently bound?

If you bind buffer B, then that’s the buffer object which will be used. If you have not specified glVertexAttribPointer, then the results of the glDraw* will be undefined.

  1. what happens if I put some other data in a, that is, I call glBufferData again? I would assume the new data is used

If you first bind buffer A, then yes, glBufferData will orphan the buffer memory and reupload the new data to the buffer object.

  1. how about GL_ELEMENT_ARRAY_BUFFER? Is it not influenced at all?

Yep. A different binding point completely and entirely separate. GL maintains a number of buffer objects binding points - ARRAY_BUFFER, ELEMENT_ARRAY_BUFFER,UNIFORM_BUFFER, etc.

  1. I read that glVertexAttribPointer returns an error if there is no GL_ARRAY_BUFFER, but only if pointer is not NULL. What is the reason?
    Any references to what you read? Sounds reasonable though.

uhmmm, I’m starting to think I haven’t been completely clear. Let me see if I get this straight.
When I call glVertexAttribPointer the currently bound VBO is “linked” to the attribute in the VAO. The VAO hold information about the attribute and the buffer. So, if my buffer A is currently bound, my VAO will know that it has to use buffer A for the attribute. Now I bind buffer B, calling glBindBuffer. Are you saying that, when I draw my VAO, buffer B will be used and not buffer A? And what would be the point in keeping the information in the VAO?

and all of them are included in my VAO? Not sure I get it.

The official documentation:

http://www.opengl.org/sdk/docs/man4/xhtml/glVertexAttribPointer.xml

If pointer is not NULL, a non-zero named buffer object must be bound to the GL_ARRAY_BUFFER target (see glBindBuffer), otherwise an error is generated. pointer is treated as a byte offset into the buffer object’s data store. The buffer object binding (GL_ARRAY_BUFFER_BINDING) is saved as generic vertex attribute array state (GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING) for index index

And the official spec too (par. 2.8):

An INVALID_OPERATION error is generated under any of the following conditions:
 - if no vertex array object is currently bound (see section 2.10);
 - size is BGRA and type is not UNSIGNED_BYTE, INT_2_10_10_10_REV or
UNSIGNED_INT_2_10_10_10_REV;
 - type is INT_2_10_10_10_REV or UNSIGNED_INT_2_10_10_10_REV,
and size is neither 4 or BGRA;
 - size is BGRA and normalized is FALSE;
 - any of the *Pointer commands specifying the location and organization of
vertex array data are called while zero is bound to the ARRAY_BUFFER
buffer object binding point (see section 2.9.6), and the pointer argument is
not NULL.

Now, why does it sound reasonable?

It’s 4.2