VBO questions

Started by
13 comments, last by CyberSlag5k 19 years, 1 month ago
I'm learning VBOs for us in my vertex arrays. I found this article on the subject but I have a few questions. As seen in the artice, "data" is loaded into the VBO tagged bufferObject. That buffer is then bound to then "selected" using pglBindBufferARB(). Then the vertex pointer is set to point to...0? This is the part that confuses me. Does OpenGL just know to revert to the most recently bound VBO when passed null for a vertex array pointer? If this is indeed the case, would I do the exact same thing for my normals, materials, etc.? Just create the VA as normal but pass null (0) in as the pointer and just ensure I bind the correct VBO first? Assuming I am correct up to this point, can I use any of the VA rendering functions? glDrawElements, for example? And if I can, does it make sense to pass the indexed array as a VBO? Can you just pass anything into a VBO? I'd imagine you would only want to put stuff in there used by the GPU (that's the point, right? to avoid AGP transfers and use speedy VRAM), but is it possible to put any list of real numbers in there to be used however the hell you want? How do you get them out, then? It seems to me they're only available in situations like the one above, where you just select the VBO and hope what you're using next can use it? If anyone could answer some/all of these questions, I would be very appreciative. Thanks in advance! [Edited by - CyberSlag5k on March 14, 2005 9:27:06 AM]
Without order nothing can exist - without chaos nothing can evolve.
Advertisement
When you setup a VBO as the source for data the 'address' param. of the gl*Pointer() functions changes from meaning a memory address to meaning an offset in bytes from the start of the currently bound VBO (remember, OpenGL is a state machine so it knows the current state of bound buffers etc).

So, if you just have a buffer with vertex data in and you want to draw it all then yes, you'd supply an off set of 0. If the data is interleaved around other data in the same VBO (say vertex pos, vertex normal and texture coords) then you'd bind each pointer with an offset to that data. (glVertexPointer(...., 0), glNormalPointer(....., 12), glTexCoordPointer(....., 24) for example).

VBOs are basically VAs which can exist in video ram, so all VA calls apply to them when they are bound as the source for the data.

You can put indices in VBOs (there is a special token for it, check the VBO spec for details) which can help the speed as the gfx card is just reading from VRam and not VRam and System ram.
You can put practically anything in them (for example, if you are doing normal mapping you could put the various tangent space vectors in them), but the infomation will only be usefull if access and used by the GPU (again, see normal mapping as an example of this).

Its not so much a case of 'hope' you should know what you are binding next and what you are using it for, remember you are in complete control of the operations which go on.
Thanks, _the_phantom_. I thought you'd be the one to answer my question :P. I think understand what is going on now. Plus I never really thought to check the official VBO spec, so now I have that as a resource too.
Without order nothing can exist - without chaos nothing can evolve.
heh, its a pretty safe bet that i'll turn up in a VBO or GLSL thread [wink]

the VBO spec is a pretty good source of infomation for VBOs, pretty much the best spec around for an extension (framebuffer_object is also pretty good from what i can remember)
Hmm...it doesn't like it when I pass an int to the last argument of glVertexPointer. The compiler says it can't convert from an int to a const GLvoid. Do I have to do anything special? Right now it's just:

glNormalPointer(GL_FLOAT, sizeof(struct myStruct), 0);
glVertexPointer(3, GL_FLOAT, sizeof(struct myStruct), 12);

It makes it past the call to glNormalPointer (must just see 0 as NULL), but it blows up on the second line. Am I making the call wrong?

Thanks!
Without order nothing can exist - without chaos nothing can evolve.
if you check the spec there is a little macro at the top of the examples which they use for converting ints to GLvoid type for use with the function call.
Quote:Original post by _the_phantom_
if you check the spec there is a little macro at the top of the examples which they use for converting ints to GLvoid type for use with the function call.


I was afraid you'd say something like that. The spec has been down all day :(. Perhaps there is a mirror site? Er...we're talking about the extension registery on www.OpenGL.org, right?

EDIT: Haha, thank you google cache! I'm in. Thanks phantom.
Without order nothing can exist - without chaos nothing can evolve.
ah, that would be a problem indeed, however via the magic of having used it in a project I happen to have it to hand [grin]

#define BUFFER_OFFSET(i) ((char *)NULL + (i))


Its as simple as that.
Used thusly;
glVertexPointer(3, GL_FLOAT, sizeof(terraindata), BUFFER_OFFSET(vertoffset_));


Where vertoffset_ is the offset in bytes from the start of the buffer to the first vertices position data [smile]

(coz I didnt want to recalculate the positions of various parts of my terraindata structure if I moved it around/added bits I calculatate the offsets and store them)
My only regret is that the user rating system does not support a higher value for me to give you, my friend.

Thanks as always.
Without order nothing can exist - without chaos nothing can evolve.
Will my call to glDrawRangeElements need to be altered at all to use the VBO? Will the final argument still be the indexed array I'm using? I have it like that now and my object just...disappears.

Here's the generation code:

pglGenBuffersARB(1, &buffList[0]);pglBindBufferARB(GL_ARRAY_BUFFER_ARB, buffList[0]);pglBufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(*myStruct), vertList, GL_STATIC_DRAW);glNormalPointer(GL_FLOAT, sizeof(myStruct), BUFFER_OFFSET(0));glVertexPointer(3, GL_FLOAT, sizeof(myStruct), BUFFER_OFFSET(12));


And here's the rendering call:

if(useDisplayLists)//display list codeelse{	pglBindBufferARB(GL_ARRAY_BUFFER_ARB, buffList[0]);	pglDrawRangeElements(GL_TRIANGLES, 0, numVert-1, numIndex, GL_UNSIGNED_INT, index);}


Am I using this wrong? I don't think I am...

EDIT: Wait a minute. Since I'm using glDraw*Elements(), I shouldn't have to bind the VBO as I render, right? I mean it won't make a difference as I only have 1 VBO anyway, but no VBO is being used in the call to pglDrawRangeElements (at least not until I move my indexed array into a VBO itself), so I don't need to bind anything. Right? That still doesn't explain why the object doesn't draw right.

To clarify, I have a key bound to switch the drawing mode from display lists to the VA (I want to note the performance changes). When I go from the DL to the VA, the object disppears.

[Edited by - CyberSlag5k on March 11, 2005 2:25:54 PM]
Without order nothing can exist - without chaos nothing can evolve.

This topic is closed to new replies.

Advertisement