PDA

View Full Version : VBO and offset



V-man
04-16-2008, 07:38 AM
I forgot this one. If I bind another VBO, do I need to call glVertexPointer and the others?

Relic
04-16-2008, 08:32 AM
Only gl*Pointer calls following a glBindBuffer set the offsets in only that buffer. gl*Pointer calls done before are unaffected by glBindBuffer calls. The gl*Pointer calls are the ones which associate attributes with VBOs.
So I guess you asked for "Yes!" as an answer.

Means you can easily setup multiple independent VBOs one for each attrib, or some attribs together, interleaved or not.

Like this mixed example for a single array for vertices and a separate interleaved normal and color.

glBindBuffer(GL_ARRAY_BUFFER, vboVertices); // v3f
glVertexPointer(3, GL_FLOAT, 12, 0); // sourcing vboVertices
glBindBuffer(GL_ARRAY_BUFFER, vboNormalsAndColors); // n3f, c3f
glNormalPointer(GL_FLOAT, 24, 0); // sourcing vboNormalsAndColors
glColorPointer(3, GL_FLOAT, 24, 12); // sourcing vboNormalsAndColors
glDrawArrays(GL_POINTS, 0, 1);

Normally interleaving all attributes should be fastest, but if you have an attribute which frequently changes it makes sense to put it separate.

V-man
04-16-2008, 10:24 AM
I'm not sure if that answered the question. I was wondering if the gl*Pointer calls become parts of the VBO.
If is part of the object, then I could do this



glBindBuffer(GL_ARRAY_BUFFER, vbo1);
glVertexPointer(3, GL_FLOAT, 0, 0x00000000);

glBindBuffer(GL_ARRAY_BUFFER, vbo2);
glVertexPointer(3, GL_FLOAT, 0, 0x00000800);

glBindBuffer(GL_ARRAY_BUFFER, vbo1);
DrawObject1();

glBindBuffer(GL_ARRAY_BUFFER, vbo2);
DrawObject2();

-NiCo-
04-16-2008, 10:49 AM
Well, I'm not 100% sure but when reading this (http://developer.nvidia.com/object/using_VBOs.html) document I tend to believe they're part of the object.
Especially this section in the document gave me the impression that they're part of the object:



Avoid Calling glVertexPointer() more than once per VBO
The “glVertexPointer” function does a lot of setup in VBO, so to avoid redundancy. The most efficient way to do is to bind the VBO buffer, setup various array pointers (glNormalPointer etc) and then call glVertexPointer(). glVertexPointer should be called one time for one VBO. You might think the essentials of VBO management are done in glBindBufferARB(), but it’s the opposite. VBO systems wait for the next upcoming important function (like glVertexPointer). The binding operation is cheap compared to the setup of various pointers. This advice fits any other function working in the same manner as glVertexPointer().

Groovounet
04-16-2008, 03:38 PM
The quick answer is no, means the nVidia paper is wrong. However, the good question is do you actually need to set it again ? If the buffer format is the same maybe not. However this work only when you use just a single ARRAY_BUFFER. OpenGL 3 will clarify this with the vertex array object and format object I guest, if it hopefully get release someday.

Groovounet
04-16-2008, 03:42 PM
You can even render an object doing this:
glBindBuffer(GL_ARRAY_BUFFER, 0);
glDrawArrays(...);

Komat
04-17-2008, 01:18 AM
The glBindBuffer just sets buffer which is used as implicit parameter for all functions which would otherwise need to take it as parameter in different design. The following sequence



glBindBuffer( GL_ARRAY_BUFFER, some_buffer ) ;
glVertexPointer(3, GL_FLOAT, 0, 0x00000000) ;


is equivalent of something like



nextgenapiVertPointer( 3, FLOAT, 0, 0x00000000, some_buffer ) ;


and specifies that the vertex position attribute should be source from offset 0 inside some_buffer VBO. This means that just calling glBindBuffer() will not change place from which the positions are read until you call the glVertexPointer() to define the new pair (VBO:offset) for the position attribute.

Relic
04-17-2008, 02:51 AM
The quick answer is no, means the nVidia paper is wrong. However, the good question is do you actually need to set it again ? If the buffer format is the same maybe not. However this work only when you use just a single ARRAY_BUFFER.

The paper is not wrong. It has just said that you do not need to re-issue gl*Pointer calls if the association with a specific VBO and offset hasn't changed.
If you want to change the VBO ID or offset you're sourcing for an established association, you must issue the resp. gl*Pointer call.
Means you cannot cache array offsets alone. Like Komat said, it's the (VBO, offset) pair which defines the source.

The spec is clear about that:
http://www.opengl.org/registry/specs/ARB/vertex_buffer_object.txt


When is the binding between a buffer object and a specific vertex array
(e.g., VERTEX_ARRAY_BUFFER_BINDING_ARB) established?

The array's buffer binding is set when the array pointer is specified.
Using the vertex array as an example, this is when VertexPointer is
called. At that time, the current array buffer binding is used for
the vertex array. The current array buffer binding is set by calling
BindBufferARB with a <target> of ARRAY_BUFFER_ARB. Changing the
current array buffer binding does not affect the bindings used by
already established arrays.

BindBufferARB(ARRAY_BUFFER_ARB, 1);
VertexPointer(...); // vertex array data points to buffer 1
BindBufferARB(ARRAY_BUFFER_ARB, 2);
// vertex array data still points to buffer 1