Jump to content
  • Advertisement
Sign in to follow this  
CyberSlag5k

OpenGL VBO questions

This topic is 4941 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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]

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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)

Share this post


Link to post
Share on other sites
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!

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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)

Share this post


Link to post
Share on other sites
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 code
else
{
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]

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!