View Full Version : VBO related crash
V-man
01-12-2004, 06: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, 08: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, 07: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, 12: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, 10: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, 11:31 AM
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, 10:19 PM
Who says that tex coords need to be in the range [-1..1]?
Mikkel Gjoel
01-19-2004, 07: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, 05: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.
Powered by vBulletin® Version 4.2.0 Copyright © 2013 vBulletin Solutions, Inc. All rights reserved.