PDA

View Full Version : VBO interleaved arrays



blender
07-12-2003, 12:16 PM
I have an array of vertex -structures, where I have position, tc and normal vectors.
How can I use this with ARB_vertex_buffer_object?

Currently I load the vertex array into video card's memory and use glVertexPointer(3, GL_FLOAT, sizeof(vertex_t), 0). This works fine, but how can I set the pointer for texture coordinates with glTexCoordPointer(), becouse the pointer argument must be zero for VBO (at least so I think)?
Is it possible witehout creating separate arrays for positions, tc:s and normals?

Asgard
07-12-2003, 12:37 PM
The pointer argument must not be set to zero. Instead it specifies the offset in bytes from the buffer start address of the currently bound buffer.
So when you call glVertexPointer with a buffer offset of 0 and then glTexCoordPoninter with a buffer offset of 12 that would mean you have an interleaved array of 3-component float positions followed by a set of texture coordinates stored in the buffer.

blender
07-12-2003, 01:26 PM
Thanks. I think I got it to work now.
BTW, I read one tutorial about VBO but it didn't explain much. So does glDeleteBuffersARB() destroy the allocated data from video memory?

Csiki
07-13-2003, 12:04 AM
Originally posted by blender:
Thanks. I think I got it to work now.
BTW, I read one tutorial about VBO but it didn't explain much. So does glDeleteBuffersARB() destroy the allocated data from video memory?
Yes.

blender
07-16-2003, 11:05 AM
How much overhead does glDrawArrays() add when using with VBO? Does it have a big difference if I call it for every polygon (3-20 vertices but send with GL_TRIANGLE_FAN:s) or is it better to call it once per shader/texture to send as many vertices as possible in one instance?

If I have cyliders in my scene, should I send every polygon as a triangle with one call to glDrawArrays() or send each polygon separately and take the advatange of triangle fans is most polygons?

zeckensack
07-16-2003, 03:45 PM
Originally posted by blender:
<...> or is it better to call it once per shader/texture to send as many vertices as possible in one instance?Absolutely, definitely, yes.

If your primitive runs are too short, you won't even notice a difference between immediate mode (glVertex yadda yadda) and VBO.

Bottom line: batch up primitives. Draw lots of stuff at once. It doesn't matter (much) whether it's one call or many, but it is worthwhile to minimize state changes.

jwatte
07-16-2003, 06:11 PM
If you dynamically collect/generate geometry, then putting all of it into one VBO per material makes a lot of sense.

If you pre-load or pre-generate your data, then using one VBO per cullable object might make sense, and then issue more than one VBO per material. It's better to avoid the copy if you can. But, once you have a VBO, try to put at least 50 verts into each. It's better to have fewer materials and more vertices, than to have tons of itty-bitty VBOs.

"material" really means general set of state.

Korval
07-16-2003, 07:16 PM
Draw lots of stuff at once. It doesn't matter (much) whether it's one call or many, but it is worthwhile to minimize state changes.

Minimizing state changes is different from batching primitives. As long as you don't actually change any state between glDraw* calls, then the only thing to worry about is function-call overhead. And such overhead is all CPU-bound, and not too terrible anyway.

The main reason to have larger batches is to take more advantage of the post-T&L vertex caching. If your geometry isn't helped by the post-T&L cache (a bag of particles, etc), then the only thing you should worry about with multiple glDraw* calls (for the same state) is function call overhead. It's best to minimize this; pathologically small objects (say, 10 verts) being rendered in single glDraw* calls will be slow due to function call overhead (unless a state change is involved). If you can batch them together, do so.

By state change, I mean anything, including glBind-ing a new VBO. Putting many objects into one VBO isn't the same as rendering them all with one glDraw* call. The VBO is just a block of memory. What you do with it is up to you.

blender
07-17-2003, 07:56 AM
Thanks for your replys.
Heh, it's kind of funny how this technology works. To render things fast, I have to send as much data as possible at once (at least so I understood), but then again, I must use some kind of a space partition to divide the geometry into small cullable sets http://www.opengl.org/discussion_boards/ubb/biggrin.gif.
I havn't figured out any good solution for my cases. I think the best way to go would be to divide geometry into sectors (linked with portals), then sort the polygons in each sector by shader and send those meshes to GPU via VBO. Now I think this would be ideal with lightmapping. And if I have understood correctly, it's wiser to just send a visible sector for GPU and not do frustum culling at all.
But there appears a lot of troubles if I wan't to have some shadows or other dynamic gizmos where it would be a great benefit to get the polygons in light radius etc. Then there would have to be some kind of a space partitioning, which would be bad for VBO.
I guess it would'n be wise anymore to make a shadow volume out of a whole sector if there's a tiny light inside of it.

roffe
07-17-2003, 09:18 AM
When we are on the subject of batching I have to recommend this document from NVIDIA.
For me it was a real eye opener.
http://developer.nvidia.com/docs/IO/4449/SUPP/BatchBatchBatch.pdf

From my experience, using MultiDraw* calls is just as bad as small batches.And if I have to duplicate vertices, I try sorting them(take advantage of cache) and using DrawArrays as much as possible.
Just my 2 cents.

jwatte
07-17-2003, 12:13 PM
Yes, there is a trade-off between batch size and degree of culling. Depending on how detailed your geometry is, and how much transfer/transform is hurting you, you may make different trade-offs.

Personally, I feel that keeping a bounding sphere or box per object, and rendering the entire object if the box/sphere intersects the frustum, is the right trade-off. To get good triangles-per-second rates (which may or may not traslate to good visuals :-) you then need to use compact vertex formats, and high-poly models/meshes.

For surrounding environment, you need some kind of chunking, and some kind of lodding, such as chunklodding :-) A typical target for each chunk of surrounding terrain would be at least 100 verts and probably not more than 2000 verts. Of course, if you don't actually have, or want to pay for, that detailed data, it's perfectly fine to send smaller buffers; all that'll happen is that you get fewer triangles per second. But customers seldom pay for triangles-per-second, they pay for visuals.

blender
07-17-2003, 12:15 PM
Thanks for the paper reference.
BTW, I don't want to go too much off the topic here, but I would like to ask a question that has been in my mind for the past few days: How long do you think lightmapping will be used by the games industry (mostly FPS games) now when we have per-pixel lighting etc.?
Now, doom3 looks awsome of cource, but how long does it take until we can use that kind of a lighting and shadowing in complex, half outdoor scenes (like a block of a city with apartments)?
Should a decent engine still support lightmapping with static geometry?

roffe
07-17-2003, 01:05 PM
Originally posted by blender:
How long do you think lightmapping will be used by the games industry (mostly FPS games) now when we have per-pixel lighting etc.?

The good thing about static lightmaps are that you can store surface illumination that can't be calculated at interactive rates.

For fast paced fps games(especially multi-player) we might see less of this, but for games that aim for those more subtle visual effects it might be the other way around.

blender
07-18-2003, 08:20 AM
BTW, I forgot to ask, how can I know if the video/agp memory allocation was a success or not?