Problem switching from conventional vertex arrays to VBO's

This was bound to happen, I really dont see where there is a problem too.

With vertex arrays everything works perfect, but when I make the switch I get some major visual problems.

This is what I used to do :
posVB = new float[3*noVertices];
//…here build the position vertex buffer
glVertexPointer(3, GL_FLOAT, 0, posVB);

//frame loop
glVertexPointer(3, GL_FLOAT, 0, posVB);

//recursively go into the quadtree until you find a leaf node then draw :
glDrawElements(GL_TRIANGLES, indexLength, GL_UNSIGNED_INT, indexBuffer);

Now, instead I simply do during initialisation:
glBindBufferARB(GL_ARRAY_BUFFER_ARB, 1);
glBufferDataARB(GL_ARRAY_BUFFER_ARB, 3noVerticessizeof(float), posVB, GL_STATIC_DRAW_ARB);

Rendering code is the same except the call to glVertexPointer is now :

glBindBufferARB(GL_ARRAY_BUFFER_ARB, 1);
glVertexPointer(3, GL_FLOAT, 0, BUFFER_OFFSET(0));

Heres what I get look like http://pages.infinit.net/mnok/vboprob.jpg

Any help is appreciated thanks.

What kind of hw are you using?
What driver version?

Im using a good old geforce2 mx.
I updated my drivers to Nvidia detonators 44.03 which supports VBO’s.

I dont think the problem is with the drivers.

You don’t generate a buffer anywhere in that code.

Instead of this:
glBindBufferARB(GL_ARRAY_BUFFER_ARB, 1);

You should have something like this:
GLuint buffer;
glGenBuffersARB(1, &buffer);
glBindBufferARB(GL_ARRAY_BUFFER_ARB, buffer);

You don’t ever have to call glGenBuffers; that is just a convenience function to let the GL make sure you never have duplicated names. It may also allow them to pick “better” names for any internal hashing they do, though the few times I’ve looked at the results it looks like they just use an internal counter.

EDIT: And, according to the spec, the call to glBindBufferARB is the point where the buffer is finally created, even if you call glGenBuffersARB beforehand.

[This message has been edited by Coriolis (edited 06-17-2003).]

Yea thats not the problem. I tried with glGenBuffers still the same thing. You can actually make up some of the terrain, it just seems that some vertices are WAY not at the right position, there is also an occasional poping of geometry, very weird…

You might also change
glVertexPointer(3, GL_FLOAT, 0, BUFFER_OFFSET(0));

to this
glVertexPointer(3, GL_FLOAT, 3 * sizeof(float), BUFFER_OFFSET(0))

should work either way but with recent Nvidia drivers i’ve seen lots of little bugs here and there…

nope that didnt change anything. Maybe using gl*Pointer for the index can help??

(ELEMENT_ARRAY_BUFFER_ARB)

[This message has been edited by dopeflow (edited 06-17-2003).]

For those interested, theres a part in the vbo specs that deals with this (which I dont quite get)
2.8A.1 http://oss.sgi.com/projects/ogl-sample/registry/ARB/vertex_buffer_object.txt

It mentions the use of GL_ARRAY_BUFFER_BINDING_ARB, which im not using. I just coded it like they do in the vertex array example given at the end of the specs

[This message has been edited by dopeflow (edited 06-17-2003).]

Is your example simple enough to post the rendering src?

If not, could you email it to me offline?

I don’t see anything obvious from your description, but there are a number of things you could be doing wrong - and, of course, it could be a driver bug.

Thanks -
Cass

Hi, source is a little bit too big, I sent you the appropriate files by mail.

Thanks.

[This message has been edited by dopeflow (edited 06-17-2003).]

Is there any known issues with the current set of drivers? More specifically with geforce2mx’s?

Well I just did a little test application with a very small buffer to draw triangles and both drawArrays and drawElements works fine with it. So I guess its just the way I have my vertex array set up or my index buffer set up.

What bugs me though is that the only difference between the 2 versions (vertex arrays vs vertex buffer objects) is that in one I send the vertices every frame with glVertexPointer and with the vbo one I simply switch that so that it uses the array stores in the buffer object. Everything else doesnt change.

Does anyone understand this taken from the vbo specs at 2.8A.1

“Instead, the commands that specify the locations and organizations of vertex arrays
copy the buffer object name that is bound to ARRAY_BUFFER_ARB to the binding point corresponding to the vertex array of the type being specified. For example, the NormalPointer command copies the value
of ARRAY_BUFFER_BINDING_ARB (the queriable name of the buffer binding corresponding to the target ARRAY_BUFFER_ARB) to the client state variable NORMAL_ARRAY_BUFFER_BINDING_ARB.”

Thanks for the help all!

[This message has been edited by dopeflow (edited 06-19-2003).]

[b]Does anyone understand this taken from the vbo specs at 2.8A.1

“Instead, the commands that specify the locations and organizations of vertex arrays
copy the buffer object name that is bound to ARRAY_BUFFER_ARB to the binding point corresponding to the vertex array of the type being specified. For example, the NormalPointer command copies the value
of ARRAY_BUFFER_BINDING_ARB (the queriable name of the buffer binding corresponding to the target ARRAY_BUFFER_ARB) to the client state variable NORMAL_ARRAY_BUFFER_BINDING_ARB.”
[/b]

By way of an example…

/* This sets the state variable
ARRAY_BUFFER_BINDING_ARB to ‘1’.
ARRAY_BUFFER_BINDING_ARB is simply
the name of the currently bound buffer.
*/
BindBufferARB(ARRAY_BUFFER_ARB, 1);

/* This sets the state variable
NORMAL_ARRAY_BUFFER_BINDING_ARB to
whatever ARRAY_BUFFER_BINDING_ARB
currently is, in this case, ‘1’.
Basically, it sets which vertex buffer
object the normal data is going to be
sourced from. It also sets the offset
into this buffer object in addition to
the stride and type of the normal data,
as usual.
*/
NormalPointer(FLOAT, 0, BUFFER_OFFSET(0));

/* Enable the normal array. */
EnableClientState(NORMAL_ARRAY);

/* Set up other vertex attributes, possibly
contained in other vertex buffer objects.
/
BindBufferARB(ARRAY_BUFFER_ARB, …);
VertexPointer(3, FLOAT, 0, …);
EnableClientState(VERTEX_ARRAY);
/
etc. */

/* Draw something. For each enabled vertex
array, the source of the vertex array
data is given by
_BUFFER_BINDING_ARB (for
example, normal data is coming from the
vertex buffer object with name
NORMAL_BUFFER_BINDING_ARB) and the
pointer or offset into that vertex buffer
object.
*/
DrawElements(…);

Hopefully that makes sense…

– Ben

[edit: formatting]

[This message has been edited by bashbaug (edited 06-19-2003).]

Originally posted by bashbaug:
<…>

Hopefully that makes sense…

– Ben

Yes it does (at least to me). Very useful, Ben. Thanks

It does make sense, thanks a lot