Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does VAO keep buffer bindings?

I am struggling to understand how exactly VAO is handling buffer mapping. What I'm doing could be described in this pseudocode:

SetUp:
  BindVAO
  BindArrayBuffer
  glBufferData(GL_ARRAY_BUFFER, ExpectedMaxCount, NULL, GL_DYNAMIC_DRAW);//Allocate storage
  glEnableVertexAttribArray
  glVertexAttribPointer

  BindElementBuffer
  Allocate storage (no data yet)

  UnbindVAO
  UnbindArrayBuffer
  UnbindElementBuffer

Draw:
  SubArrayAndElementDataIfNeeded
  BindVAO
  DrawElements
  1. Is this correct that when DrawElements is called OpenGL uses bound VAO to resolve array and element buffer bindings? After a Draw call the bound array buffer is 0, but element buffer is still the one that was used to Draw.

  2. Is it mandatory to allocate buffer memory during VAO setup? Would VAO be invalidated if BufferData was called after setup?

like image 477
Kimi Avatar asked Sep 28 '12 14:09

Kimi


People also ask

Does binding VAO bind VBO?

No. You can bind a VBO before you bind a VAO, and fill the VBO with data using glBufferData() . A VBO is essentially just a dumb data container. But any kind of vertex attribute setup tracked in the VAO can only be done after the VAO is bound.

What does VAO store?

A Vertex Array Object (VAO) is an OpenGL Object that stores all of the state needed to supply vertex data (with one minor exception noted below). It stores the format of the vertex data as well as the Buffer Objects (see below) providing the vertex data arrays.

What is an OpenGL buffer?

Buffer Objects are OpenGL Objects that store an array of unformatted memory allocated by the OpenGL context (AKA the GPU). These can be used to store vertex data, pixel data retrieved from images or the framebuffer, and a variety of other things.

What is element buffer?

Thankfully, element buffer objects work exactly like that. An EBO is a buffer, just like a vertex buffer object, that stores indices that OpenGL uses to decide what vertices to draw. This so called indexed drawing is exactly the solution to our problem.


1 Answers

I am struggling to understand how exactly VAO is handling buffer mapping.

Be very careful when using the word "mapping" around "buffers"; that has a specific meaning when dealing with buffer objects, one that you probably don't intend.

Is this correct that when DrawElements is called OpenGL uses bound VAO to resolve array and element buffer bindings? After a Draw call the bound array buffer is 0, but element buffer is still the one that was used to Draw.

One has nothing to do with the other. A Vertex Array Object, as the name implies, contains all of the state that is necessary to pull vertex data from arrays. When you bind one, all of that state comes back into the context.

The reason the "bound array buffer" is 0 after the call is because it was 0 before the call. Draw calls do not change OpenGL state.

Furthermore, you seem to have fallen for the GL_ARRAY_BUFFER trap. The GL_ARRAY_BUFFER binding only matters to three functions: glVertexAttribPointer, glVertexAttribIPointer, and glVertexAttribLPointer (see a pattern?). These are the only functions that look at that binding. What they do is take the buffer that is bound at the time these functions are called and associates that buffer with the current VAO. GL_ARRAY_BUFFER is not part of the VAO's state. A buffer object becomes associated with a VAO only when you call one of those three functions. Once you make that call, you can bind whatever you want to GL_ARRAY_BUFFER.

GL_ELEMENT_ARRAY_BUFFER is part of the VAO's state.

Is it mandatory to allocate buffer memory during VAO setup? Would VAO be invalidated if BufferData was called after setup?

Technically no, but it's good form to not use a buffer until it has storage. Especially if they're static buffers.

like image 172
Nicol Bolas Avatar answered Oct 02 '22 21:10

Nicol Bolas