PDA

View Full Version : VBO related crash



V-man
01-12-2004, 07:27 PM
I was having some strange problems, so I decided to make a small test and I experienced crashes.

It turns out that if I call it like this

glBindBuffer(GL_ARRAY_BUFFER, VBO[0]);
glVertexPointer(3, GL_FLOAT, 0, 0);

it runs OK, but if I call it like this

glVertexPointer(3, GL_FLOAT, 0, 0);
glBindBuffer(GL_ARRAY_BUFFER, VBO[0]);

(where previously no VBO was bound, as in glBindBuffer(GL_ARRAY_BUFFER, 0); ) then it crashes.

Is that normal?

Korval
01-12-2004, 09:57 PM
Yes, this is expected.

Unless a buffer is bound (or if buffer #0 is bound), all gl*Pointer calls expect a pointer, not an offset. At the moment you call a gl*Pointer call, it either stores a VBO+offset, or an actual system memory pointer. This lets you use multiple VBO's for different attributes of the same object.

V-man
01-13-2004, 08:12 AM
Meaning what exactly?

If I construct a VBO, can I call gl*Pointer and this becomes part of the VBO?

Then I can do

loop()
{
glBindBuffer(........, VBO[i++]);//For vertex
//no need to call any gl*Pointer
glBindBuffer(........, VBO[i++]);//For normal
.......
.......
glDrawElement or whatever
}

I thought the gl*Pointer functions were global.

I'm still experiencing some other problem but I'll try to solve it myself.


[This message has been edited by V-man (edited 01-13-2004).]

Korval
01-13-2004, 01:33 PM
I thought the gl*Pointer functions were global.

Think of it this way.

When you call glBindBuffer, you are telling OpenGL that all of the following gl*Pointer calls are going to use that VBO. This means that when you call:





glBindBuffer(1);
glVertexPointer(<stuff>, 0);


The implementation stores, "Vertex Pointer uses VBO 1 at offset 0." If you then do:




glBindBuffer(5);


This will not make the vertex pointer change to using VBO 5. It will still use VBO 1.

If you have not bound a buffer, and you call a gl*Pointer call, it records that this pointer is a real pointer to system memory, not an offset. So, if no buffer is bound and you do this:



glVertexPointer(<stuff>, 0)


Then the implementation records that the vertex pointer is using regular vertex arrays (not VBOs) and comes from memory location NULL. Clearly, this is going to cause a crash at some point.

So, if I have 2 VBOs, one that contains positions and one with normals, I do this to use them:




glBindBuffer(iPosBuffer);
glVertexPointer(<stuff>, 0);
glBindBuffer(iNormBuffer);
glNormalPointer(<stuff>, 0);


Remembering that the glVertexPointer call is not affected by the later call to glBindBuffer.

In short, you must bind the correct buffer before calling gl*Pointer calls.

V-man
01-18-2004, 11:25 AM
OK, I went back to this problem.
After much testing, I found that this works.

---------------------------
//Conventional arrays
glBindBuffer(GL_ARRAY_BUFFER, VBO[2]);
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_FLOAT, VertexSize, VBO_VertexAddress);
glEnableClientState(GL_NORMAL_ARRAY);
glNormalPointer(GL_FLOAT, VertexSize, VBO_NormalAddress);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(2, GL_FLOAT, VertexSize, VBO_TexCoordsAddress);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, VBO[3]);
glDrawRangeElements(GL_TRIANGLES, 0, EndVertexDRE, TotalIndex, GL_UNSIGNED_SHORT, 0);

---------------------------
but this doesn't

glBindBuffer(GL_ARRAY_BUFFER, VBO[2]);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, VertexSize, VBO_VertexAddress);
glEnableVertexAttribArray(2);
glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, VertexSize, VBO_NormalAddress);
glEnableVertexAttribArray(8);
glVertexAttribPointer(8, 2, GL_FLOAT, GL_FALSE, VertexSize, VBO_TexCoordsAddress);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, VBO[3]);
glDrawRangeElements(GL_TRIANGLES, 0, EndVertexDRE, TotalIndex, GL_UNSIGNED_SHORT, 0);

The above 2 codes render the exact same object, using the exact same VBO. The only diff is that conventional vs generic attributes. I check if I'm loading the functions pointers OK and that is fine.

By "not working", I mean that it is running, but normal and tex coords are screwed up, but the geometry (vertices) seem fine.

Extra info: I tried both interleaved arrays and non-interleaved but this doesn't make a difference (I think)

Any ideas?

Mikkel Gjoel
01-18-2004, 12:31 PM
Are you setting the clamping correctly? Should be set to [0..1] for colors, [-1..1] for tex-coords?

Also, shouldn't you still use a '0' for the pointer? So this...


glBindBuffer(GL_ARRAY_BUFFER, VBO[2]);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, VertexSize, VBO_VertexAddress);

becomes this instead:



glBindBuffer(GL_ARRAY_BUFFER, VBO[2]);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, VertexSize, 0);

V-man
01-18-2004, 11:19 PM
Who says that tex coords need to be in the range [-1..1]?

Mikkel Gjoel
01-19-2004, 08:48 AM
Well, no-one. Did it work? But I thought it might clamp if you didn't set the right mode.

V-man
01-19-2004, 06:41 PM
There isn't any issue with clamping. Values are passed through as is for tex coords.

Even If I get rid of texturing, the normals are still wrong. The geometry is rendered ok, but it looks like the last normal vector remains.

So I have no idea.
I will create a small test and upload it then and maybe check with someone.