#258699 - 06/09/09 05:06 AM
VBO to VAO
|
Newbie
Registered: 01/27/08
Posts: 46
Loc: phobos, mars
|
VBO: All our geometry is currently drawn from the bound IBO and VBO with glDraw[Range]Elements(). I never did understand why, but we could not make our code work unless we specified the offsets/types/normalizations of every vertex attribute every time we switched to another IBO/VBO pair. Does anyone understand why? Note: the vertices in all our VBOs are identical (same attributes, same offsets, same types, etc).
VAO: After reading the OpenGL v3.10 specification, I have a few questions about VAOs. The description of VAOs led did not make it clear to me that the VAO remembers and restores the VBO attributes and their offsets/types/normalizations when they are bound. However, table 6.3 and 6.4 seems to clearly state this information is stored with the VAO.
Here are my VAO questions:
#1: Does binding the VAO make all this VBO state active too? And does it also somehow make clear to the GPU whether the indices in the corresponding IBO are 16-bits or 32-bits (I don't see that)?
#2: Why do I not see an IBO or VBO identifier in the VAO state (in tables 6.3 and 6.4)? How can binding the VAO also bind the IBO and VBO if they are not identified in the VAO state?
---------------
context: upgrading cross platform 3D engine from OpenGL210/GLSL120 to OpenGL310/GLSL140 (with 185.85 drivers).
computers: CPU = phenom + 4GB RAM : video = nvidia GTX285 + 2GB VRAM : OS #1 = ubuntu64 v9.04 : OS #2 = winxp64
|
|
Top
|
|
|
|
#258711 - 06/09/09 06:50 AM
Re: VBO to VAO
[Re: bootstrap]
|
Regular Contributor
 
Registered: 05/16/01
Posts: 332
|
I never did understand why, but we could not make our code work unless we specified the offsets/types/normalizations of every vertex attribute every time we switched to another IBO/VBO pair. Does anyone understand why? Because GL_ARRAY_BUFFER_BINDING is a latched state. You never bind a buffer for a certain vertex attribute directly, instead you bind a buffer to GL_ARRAY_BUFFER, then call glVertexAttribPointer (or one of the deprecated gl*Pointer functions). Only at that point is GL_ARRAY_BUFFER_BINDING copied to GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING for the specific vertex attribute. You cannot switch to another buffer by calling glBindBuffer(GL_ARRAY_BUFFER, x) without subsequent calls to gl*Pointer(). GL_ARRAY_BUFFER_BINDING is never used for rendering. #1: Does binding the VAO make all this VBO state active too? And does it also somehow make clear to the GPU whether the indices in the corresponding IBO are 16-bits or 32-bits (I don't see that)? Yes, no. The index type remains a parameter of glDrawElements and is not stored in a VAO. #2: Why do I not see an IBO or VBO identifier in the VAO state (in tables 6.3 and 6.4)? How can binding the VAO also bind the IBO and VBO if they are not identified in the VAO state? It's right there in table 6.4. GL_ELEMENT_ARRAY_BUFFER_BINDING for the index buffer binding, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING for each vertex attribute binding.
|
|
Top
|
|
|
|
#258713 - 06/09/09 07:03 AM
Re: VBO to VAO
[Re: Xmas]
|
Newbie
Registered: 01/27/08
Posts: 46
Loc: phobos, mars
|
#2: Why do I not see an IBO or VBO identifier in the VAO state (in tables 6.3 and 6.4)? How can binding the VAO also bind the IBO and VBO if they are not identified in the VAO state? It's right there in table 6.4. GL_ELEMENT_ARRAY_BUFFER_BINDING for the index buffer binding, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING for each vertex attribute binding. If that's what GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING means, why are there 16 of them?
|
|
Top
|
|
|
|
#258718 - 06/09/09 07:30 AM
re: VBO to VAO
[Re: Xmas]
|
Newbie
Registered: 01/27/08
Posts: 46
Loc: phobos, mars
|
Because you can use a different buffer for each vertex attribute. Wait. So the VAO doesn't know which VBO is attached? It only knows the offsets of the <= 16 attributes in the first vertex of the VBO? I assume you're not saying you can have <= 16 VBOs attached to the VAO, right? After all, a VBO is a VERTEX buffer object, not an ATTRIBUTE buffer object. This leaves me a bit confused. What does the driver do when we call the glDrawElements() function? How does the driver convert this VAO information into something the GPU understands? I would imagine the GPU needs the 64-bit starting address in *GPU* memory of each attribute, plus the rest of the information in the VAO state. But how does the driver know this if it does not keep track of which VBO is attached? I'm missing something. Does the VAO know which IBO and VBO are attached to it, or not? If so, how (where is that state)? If not, how can the driver send sufficient information to the GPU when the glDrawElements() is called?
|
|
Top
|
|
|
|
#258724 - 06/09/09 08:11 AM
Re: re: VBO to VAO
[Re: bootstrap]
|
OpenGL Pro
  
Registered: 10/06/04
Posts: 1506
Loc: Druidia
|
Because you can use a different buffer for each vertex attribute. Wait. So the VAO doesn't know which VBO is attached? It only knows the offsets of the <= 16 attributes in the first vertex of the VBO? I think we're in desperate need of a concrete example at this point. Here are two batches using VAOs and VBOs, supposing 1) you don't need to change any state between the batches except to change a texture, and 2) the VAOs to be used are already built:
glBindTexture
glBindVertexArray
glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, ...)
glDrawRangeElements
...
glBindTexture
glBindVertexArray
glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, ...)
glDrawRangeElements
... As you can see, no vertex attribute VBO binds, vertex attribute pointer calls, or vertex attribute enables/disables. All cached in the VAO.
|
|
Top
|
|
|
|
#258726 - 06/09/09 09:08 AM
Re: re: VBO to VAO
[Re: bootstrap]
|
Regular Contributor
 
Registered: 05/16/01
Posts: 332
|
I assume you're not saying you can have <= 16 VBOs attached to the VAO, right? That is indeed exactly what I am saying. After all, a VBO is a VERTEX buffer object, not an ATTRIBUTE buffer object. OpenGL only knows a single type of buffer object. Vertex buffer objects, index buffer objects, pixel buffer objects, uniform buffer objects, or texture buffer objects are just descriptions based on the usage of a particular buffer object. They all are the same type of object: a buffer object. And you can indeed use a single buffer object for all these purposes. I wouldn't recommend it, though. So yes, it is entirely possible that you use one buffer object for normals, another for vertex positions, a third one for texture coordinates, and so on. Or you can mix those attributes in whatever way you like. And all the information that is needed for each attribute (buffer binding, size, type, stride, offset, enabled, normalized, and integer flags) plus the binding for a buffer object containing vertex indices (ELEMENT_ARRAY_BUFFER) is stored in a VAO. Thus it's not even necessary to re-bind to GL_ELEMENT_ARRAY_BUFFER, Dark Photon.
|
|
Top
|
|
|
|
#258732 - 06/09/09 09:42 AM
re: VBO to VAO
[Re: Dark Photon]
|
Newbie
Registered: 01/27/08
Posts: 46
Loc: phobos, mars
|
I think we're in desperate need of a concrete example at this point. Here are two batches using VAOs and VBOs, supposing 1) you don't need to change any state between the batches except to change a texture, and 2) the VAOs to be used are already built:
glBindTexture(...)
glBindVertexArray(...)
glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, ...)
glDrawRangeElements(...)
...
glBindTexture(...)
glBindVertexArray(...)
glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, ...)
glDrawRangeElements(...)
... As you can see, no vertex attribute VBO binds, vertex attribute pointer calls, or vertex attribute enables/disables. All cached in the VAO. Sorry, but I'm still missing something here. When you say "no VBO binds", are you saying there IS no VBO? Are you saying the VAO replaces the VBO... that the VAO is essentially a VBO plus attached attribute information? If so, please explain the first sentence of the "Vertex Array Objects" section in the OpenGL v3.10 specification, which states: "The buffer objects that are to be used by the vertex stage of GL are collected together to form a vertex array object. All state related to the definition of data used by the vertex processor is encapsulated in a vertex array object." When I read the above, I hear them saying "the VBO and any other buffer objects needed by the vertex stage are part of the VAO". It does not say "the VAO ***is*** the buffer object". I am not saying you are wrong. But I am saying that is terribly misleading wording if you are correct. Also, if the VAO ***is*** a buffer object itself, and is not just a collection of buffer objects (like they say it is above), then why is the VAO not bound with: glBindBuffer (GL_ARRAY_BUFFER, vaoID); // ??? Instead, according to you *and* the OpenGL v3.10 specification, the VAO is bound not as a buffer object, but as a "vertex array" with: glBindVertexArray (vaoID); The above implies to me that the VAO does not contain vertex data, and does not correspond to a buffer object. So I ask again, if we don't bind a VAO, an IBO, ***and*** a VBO, then how does the vertex data get into the VRAM, and how does a given glDrawElements() know where the vertex data is? ----- Separately, in your example, why must you glBindVertexArray() and glBindBuffer(GL_ELEMENT_ARRAY_BUFFER...) before the second glDrawElements(...) call? Aren't they still bound? ----- In our current code, we bind an IBO, bind a VBO, call glVertexAttribPointer() 5 times, then call glDrawElements(). Therefore I understand how the GPU knows where to get vertex-indices from (the bound IBO), and how the GPU knows where to get vertex-data from (the bound VBO). In your code I see how the GPU knows which IBO to fetch from, but I do NOT see how the GPU knows which VBO to fetch from. I'm not saying your code is wrong, I'm just saying I don't see how sufficient information gets to the driver or GPU.
|
|
Top
|
|
|
|
#258733 - 06/09/09 10:05 AM
Re: re: VBO to VAO
[Re: Xmas]
|
Newbie
Registered: 01/27/08
Posts: 46
Loc: phobos, mars
|
I assume you're not saying you can have <= 16 VBOs attached to the VAO, right? That is indeed exactly what I am saying. Okay, then how do you attach (say) 5 VBOs to a VAO? Let me guess - you call glVertexAttribPointer() 5 times. But that is not a VBO, that is just a vertex attribute specification. True, this does provide the stride too, so it knows how far to the next instance of the same attribute, but glVertexAttribPointer() does NOT say how many of these attributes follow. It also doesn't transfer these attributes anywhere either. So how do all 5 sets of vertex attributes get into VRAM? And when glDrawElements() gets called, how does the GPU know where those 5 arrays of attributes are? After all, a VBO is a VERTEX buffer object, not an ATTRIBUTE buffer object. OpenGL only knows a single type of buffer object. Vertex buffer objects, index buffer objects, pixel buffer objects, uniform buffer objects, or texture buffer objects are just descriptions based on the usage of a particular buffer object. They all are the same type of object: a buffer object. And you can indeed use a single buffer object for all these purposes. I wouldn't recommend it, though. So yes, it is entirely possible that you use one buffer object for normals, another for vertex positions, a third one for texture coordinates, and so on. Or you can mix those attributes in whatever way you like. And all the information that is needed for each attribute (buffer binding, size, type, stride, offset, enabled, normalized, and integer flags) plus the binding for a buffer object containing vertex indices (ELEMENT_ARRAY_BUFFER) is stored in a VAO. Thus it's not even necessary to re-bind to GL_ELEMENT_ARRAY_BUFFER, Dark Photon. Then what does the setup code look like? Maybe that's what I need to see, to understand how this works? If I have 5 attributes, do I need to create 5 VBOs? Do I then glBuffer[Sub]Data() the vertex data from CPU memory into these 5 VBOs in VRAM? This is a total disaster, because my vertice are interleaved (per usual practice)! My code would need to call glBufferSubData() once for each attribute in each vertex, which would be thousands to millions of excess function calls!!!!! What does the code look like to attach 5 VBOs to a VAO? Yup, I think I need to see what comes first, what comes second, what comes third, etc - including setup code. Until I see how the GPU knows what to do (and where to get the vertex data) when glDrawElements() is called, I am confused. Remember, the data is in VRAM, not in CPU memory.
|
|
Top
|
|
|
|
|
|
2 registered (mfort, 1 invisible),
29
Guests and
9
Spiders online. |
|
Key:
Admin,
Global Mod,
Mod
|
|
25999 Members
13 Forums
54435 Topics
282267 Posts
Max Online: 482 @ 08/11/08 06:19 PM
|
|
|