"invisible" VBOs

Started by
16 comments, last by Mantear 19 years, 1 month ago
MAR_999, sounds like you're talking about using interleaved data arrays. I've thought about using those, but for now, I want to stick with non-interleaved.

Since I'm using Object.Triangles.Index, an array of vertex indicies, I must have to use GL_ELEMENT_ARRAY_BUFFER somewhere, right? Do I need to glGenBuffer and get a buffer for Object.Triangles.Index? Something like:
// Initialization CodeglGenBuffers( 1, &Object.Triangles.VBOName);glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, Object.Triangles.VBOName);glBufferData( GL_ELEMENT_ARRAY_BUFFER, Object.Triangles.IndexCurrentSize*sizeof(unsigned int), Object.Triangles.Index, GL_STATIC_DRAW);glGenBuffers( 1, &Object.VertexName);glBindBuffer( GL_ARRAY_BUFFER, Object.VertexName);glBufferData( GL_ARRAY_BUFFER, Object.VertexCurrentSize*3*sizeof(float), Object.Vertex, GL_STATIC_DRAW);glGenBuffers( 1, &Object.ColorName );	glBindBuffer( GL_ARRAY_BUFFER, Object.ColorName );glBufferData( GL_ARRAY_BUFFER, Object.VertexCurrentSize*4*sizeof(unsigned char), Object.Color, GL_STATIC_DRAW);glGenBuffers( 1, &Object.NormalName );	glBindBuffer( GL_ARRAY_BUFFER, Object.NormalName );glBufferData( GL_ARRAY_BUFFER, Object.VertexCurrentSize*3*sizeof(float), Object.Normal, GL_STATIC_DRAW);

// Draw CodeglEnableClientState(GL_VERTEX_ARRAY);glEnableClientState(GL_COLOR_ARRAY);glEnableClientState(GL_NORMAL_ARRAY);		    glBindBuffer(GL_ARRAY_BUFFER, Object.VertexName);glVertexPointer(3, GL_FLOAT, 0, 0);glBindBuffer(GL_ARRAY_BUFFER, Object.ColorName);glColorPointer(4, GL_UNSIGNED_BYTE, 0, 0);glBindBuffer(GL_ARRAY_BUFFER, Object.NormalName);glNormalPointer(GL_FLOAT, 0, 0);glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, Object.Triangles.VBOName);glDrawElements(GL_TRIANGLES, Object.Triangles.IndexCurrentSize, GL_UNSIGNED_INT, Object.Triangles.Index);


If I'm thinking of this right, I'm setting the gl*Pointers to their correct buffers, binding the array of vertex indices, then drawing. Am I on the right track?






Advertisement
That last line should read:
glDrawElements(GL_TRIANGLES, Object.Triangles.IndexCurrentSize, GL_UNSIGNED_INT, 0);


since you're giving an offset into the buffer.
I had this exact same problem early last week. It looks to me like the code you have in your third and most recent post (other then what rick_appleton pointed out) should work just fine. The only way this wouldn't work is if your normals were messed up, or if something was wrong with your lighting. To check the first you might want to try drawing in intermediate mode (the usual glVertex3f stuff) and make sure your normals are correct.

After that, I would guess (as this is what my problem was) that something is wrong with your lighting somewhere. I'm afraid I've forgotten exactly what my problem was, but I'm certain it had something to do with lighting.

I'm sorry I don't have a quick answer for you, but your code seems to be correct. This leads me to believe the problem is somewhere other then the VBOs. Especially since I had this same problem.
I've verified by hand that the normals are correct, and the lighting works for my non-VBO objects. My last post is code I have yet to try out, so I don't know if it works yet. Just to be sure, am I using GL_ARRAY_BUFFER and GL_ELEMENT_ARRAY_BUFFER in the correct places? Thanks everyone for their input.
As far as I can see, yes you are.
Hmm, things are still not working correctly. If I try:
// Loading// TrianglesglGenBuffers(1, &pEngine->NewObject[ObjectIndex].Triangles.VBOName);glBindBuffer(GL_ARRAY_BUFFER, pEngine->NewObject[ObjectIndex].Triangles.VBOName);glBufferData(GL_ARRAY_BUFFER, pEngine->NewObject[ObjectIndex].Triangles.IndexCurrentSize * sizeof(unsigned int), pEngine->NewObject[ObjectIndex].Triangles.Index, GL_STATIC_DRAW);// VertexglGenBuffers(1, &pEngine->NewObject[ObjectIndex].VertexName);glBindBuffer(GL_ARRAY_BUFFER, pEngine->NewObject[ObjectIndex].VertexName);glBufferData(GL_ARRAY_BUFFER, pEngine->NewObject[ObjectIndex].VertexMaxSize * 3 * sizeof(float), pEngine->NewObject[ObjectIndex].Vertex, GL_STATIC_DRAW);// ColorglGenBuffers(1, &pEngine->NewObject[ObjectIndex].ColorName);glBindBuffer(GL_ARRAY_BUFFER, pEngine->NewObject[ObjectIndex].ColorName);glBufferData(GL_ARRAY_BUFFER, pEngine->NewObject[ObjectIndex].VertexMaxSize * 4 * sizeof(unsigned char), pEngine->NewObject[ObjectIndex].Color, GL_STATIC_DRAW);// NormalglGenBuffers(1, &pEngine->NewObject[ObjectIndex].NormalName);glBindBuffer(GL_ARRAY_BUFFER, pEngine->NewObject[ObjectIndex].NormalName);glBufferData(GL_ARRAY_BUFFER, pEngine->NewObject[ObjectIndex].VertexMaxSize * 3 * sizeof(float), pEngine->NewObject[ObjectIndex].Normal, GL_STATIC_DRAW);...// Drawing// Enable client states for vertex, color, and normalglEnableClientState(GL_VERTEX_ARRAY);glEnableClientState(GL_COLOR_ARRAY);glEnableClientState(GL_NORMAL_ARRAY);		    // Bind the vertex dataglBindBuffer(GL_ARRAY_BUFFER, pObject->VertexName);glVertexPointer(3, GL_FLOAT, 0, 0);// Bind the color dataglBindBuffer(GL_ARRAY_BUFFER, pObject->ColorName);glColorPointer(4, GL_UNSIGNED_BYTE, 0, 0);// Bind the normal dataglBindBuffer(GL_ARRAY_BUFFER, pObject->NormalName);glNormalPointer(GL_FLOAT, 0, 0);// Draw the TrianglesglBindBuffer(GL_ARRAY_BUFFER, pObject->Triangles.VBOName);glDrawElements(GL_TRIANGLES, pObject->Triangles.IndexCurrentSize, GL_UNSIGNED_INT, pObject->Triangles.Index);

I thought when Binding and loading the buffer data, I should use GL_ELEMENT_ARRAY_BUFFER instead of GL_ARRAY_BUFFER for pObject->Triangles.Index, but if I do that, nothing shows up. With the posted code, I'm only seeing an object with the same color as the background color.

pObject->Triangles.Index is an a array of unsigned int, indicating the index location of the vertex/color/normal. pObject->Vertex is an array of float[3], pObject->Color is an array of unsigned char[4], and pObject->Normal is an array of float[3].
For a cube, IndexCurrentSize of the Vertex/Color/Normal arrays would be 8 (one for each vertex), and the size of Quads.Index would be 24 (6 quads * 4 vertices each).

*scratches his head*

Any ideas?
Quote:Original post by rick_appleton

I'm afraid this is incorrect. You are allowed to use different buffers:
Quote:From Specs: http://oss.sgi.com/projects/ogl-sample/registry/ARB/vertex_buffer_object.txt
In the case of vertex arrays, this extension defines not merely one
binding for all attributes, but a separate binding for each
individual attribute. As a result, applications can source their
attributes from multiple buffers. An application might, for example,
have a model with constant texture coordinates and variable geometry.
The texture coordinates might be retrieved from a buffer object with
the usage mode "STATIC_DRAW", indicating to the GL that the
application does not expect to update the contents of the buffer
frequently or even at all, while the vertices might be retrieved from
a buffer object with the usage mode "STREAM_DRAW", indicating that
the vertices will be updated on a regular basis.


Yikes! I have to apologize then. That's a heck of a mistake, and I went and looked at the extension doc specifically to confirm that it would work the way I thought it did. You learn something useful every day...
If I do use different buffers for each, does that add any overhead? Is glBindBuffer fast enough that it shouldn't matter that I call it once for each buffer I'm using?

I finally figured out what I was doing wrong. I had GL_TEXTURE_2D enabled when I went to draw my VBO object. It's working great now. Thanks everyone!

This topic is closed to new replies.

Advertisement