Will VBOs be faster than display lists for simple meshes?

Sage
Posts: 1,199
Joined: 2004.10
Post: #1
All,

Some time back I wrote a pretty capable mesh system for rendering procedurally generated objects, such as spheres, cylinders, capped cylinders, beveled boxes, etc etc. It does solid wireframing and shadow volume extrusion as well as silhouetting for outlines; I use it in several projects.

The thing is, however, I wrote it about a year ago when I had only been programming OpenGL for a couple months and I was a complete noob. I didn't know about vertex arrays or VBOs, so it's basically just a display list wrapping GL_TRIANGLE calls.

Now, recently I wrote a simple terrain system for a game and I discovered how amazingly fast VBOs can be -- Which leads me to wonder if it would benefit my mesh code to switch to VBOs.

Thus far, none of my meshes use more than ~200 triangles. But my simulations and the game I'm writing tend to have many instances of these meshes, perhaps 100 or more.

Does this sound like something which would benefit from a rewrite to use VBOs?
Quote this message in a reply
Luminary
Posts: 5,143
Joined: 2002.04
Post: #2
In general, display lists will be faster than VBOs. They do, however, have a significant per-use penalty, which VBOs shouldn't.

In conclusion, try it and see Rasp
Quote this message in a reply
Sage
Posts: 1,199
Joined: 2004.10
Post: #3
I *knew* it would come to that. Well, something to do tonight.
Quote this message in a reply
Sage
Posts: 1,199
Joined: 2004.10
Post: #4
I just thought I'd let you know about the results, in case you're interested.

With a little profiling I was able to determine that using display lists for actually drawing the mesh is so fast as to be not worth optimizing. My code spends less than a few percent of time drawing the meshes themselves, even when there's quite a few of them.

So, I decided to focus on where the hit is -- and that's shadow volume extrusion. Well, that said, I've read the papers on doing it in hardware and I don't think I have the expertise to approach that. What I was able to do, however, was to speed it up 25% by using vertex arrays to draw the volume instead of drawing it as a bunch of GL_QUADS. So now, instead of drawing all the quads twice, instead I just call glDrawArrays twice. Very nice. Plus, I polished some sore spots in the code, thanks to Shark.

Anyway, my next step will be to try to figure out how to use the extensions that allow for single-pass shadow volume drawing, instead of doing it twice.

Then, I suppose, I should try to figure out robust shadow volumes using Carmak's reverse and whatnot. Could anybody give me a 10,000 foot view on how that actually works? I'm a little uncertain of the concept right now.
Quote this message in a reply
Sage
Posts: 1,199
Joined: 2004.10
Post: #5
Woohoo!

I just wanted to tell anybody reading here that I was able to implement zfail ( Carmack's reverse ) stencil shadows, and using the vertex array optimizations I worked out earlier I still have better performance now ( even with the added geometry of drawing the volume capping ) than before with my naive zpass implementation.

Woohoo! Robust shadows!
Quote this message in a reply
Sage
Posts: 1,232
Joined: 2002.10
Post: #6
A bit late now I guess, but the technique is demonstrated here. I have that demo ported to OS X here too if you want it.

btw, any chance of sharing your meshed object generation? I'll probably have to write something similar so I wouldn't mind looking at an implementation.
Quote this message in a reply
Sage
Posts: 1,199
Joined: 2004.10
Post: #7
arekkusu Wrote:A bit late now I guess, but the technique is demonstrated here. I have that demo ported to OS X here too if you want it.

btw, any chance of sharing your meshed object generation? I'll probably have to write something similar so I wouldn't mind looking at an implementation.

Sure, I'll post a simple demo once I've got the development hokey-pokey code taken out and the rest prettied up and documented a little better.

The cool thing, if I say so myself, is that my mesh generation code handles live resizing very well, while still maintaining the plane connectivity information. This is cool for situations in my simulator where I've got, say, a piston or some other dynamically resizing object and I want it to be a shadow caster.

One thing to note, however, is that my mesh api is designed for procedurally/declaratively generated geometry. This makes it very easy to port code that draws an object in immediate mode via GL_TRIANGLES or GL_QUADS by simply calling the methods triangle(...) or quad(...). I've already written several classes that generate simple primitive geometry types. It also supports very basic texture mapping, but only one texture.

For example, you make a MeshEntity and then give it an implementation of a MeshObject, such as a SphereObject or a CappedCylinderObject. There's no reason why you couldn't write an MD2Object class and have it load a file and then pump vertices. I just haven't done it yet. You can have several MeshEntities use a single MeshObject to save memory -- the entity handles the positioning and shadow casting, the object just represents disembodied geometry.

Also, in case it interests you, I've written a subclass of my MeshEntity which handles the transformation matrices used by the OpenDynamicsEngine. This way you can simply do something like:

Code:
someEntity->applyODETransform( dBodyGetPosition( someBody ), dBodyGetRotation( someBody() );

someEntity->draw();

//later

someEntity->castShadow( lightPosition );

EDIT: I just checked out the link you posted -- that's actually what I used as a reference for my implementation Wink

Though I should point out -- my implementation isn't fully as robust as their's -- mine doesn't do the infinite projection frustum like they do. It's trivial to tack on, however. I didn't do it because my game doesn't *need* it, and because I make use of a far plane for frustum clipping.
Quote this message in a reply
Sage
Posts: 1,232
Joined: 2002.10
Post: #8
TomorrowPlusX Wrote:Sure, I'll post a simple demo... my mesh api is designed for procedurally/declaratively generated geometry.
Cool, looking forward to it.

What I'd like to do is generate classes of objects procedurally, including composite boolean operations, apply multiple textures, and compute backprojected shadows into the assembled room mesh for the direct lighting pass of a radiosity solution (a discontinuity mesh.)

That's all new territory for me so looking at a mesh generator will be helpful. I suppose glu does a bit of that but it's pretty simple...
Quote this message in a reply
Sage
Posts: 1,199
Joined: 2004.10
Post: #9
It ought to be easy to hack out the shadowing related bits from my code and keep just the mesh parts.

Wether or not my mesh code is up to the task is another matter altogether Wink

What my code does is to allow for your generator code to make arbitrary declarative primitive calls to triangles and quads. It gathers the points up and "welds" those which are deemed to be the same ( or close enough), and in the meantime it maintains index lists so in the end you'll have a vertex array and an index array. it also supports texture coordinates and edges, since for my robotics simulation I like to have solid wireframing in some circumstances.

I'll polish it and I'll put up source when it's ready. I'd love to see the radiosity stuff you're going to do. As a person who studied art ( painting and printmaking, all this programming work is self taught ) light and shadow in 3d graphics mean a *lot* to me.
Quote this message in a reply
Sage
Posts: 1,199
Joined: 2004.10
Post: #10
OK, I put a zip file on my earthlink account.

http://home.earthlink.net/~zakariya/files/Mesh.zip

The package is -- I hope -- a properly self-contained Xcode project which will build my test app. It has a little extra like FTGL & GLEW (headers and compiled libs are packaged) which I needed for various reasons, but the whole thing's only 1.2 megs anyway.

The stuff you will be interested in is in src/Mesh/* in particular the files Mesh.h/cpp

I hope my mesh code isn't too naive to be of use to you. It works for me -- but then I'm not doing hairy logical volume generation like you plan to. I guess it comes down to this: if your volume generation code can be boiled down to declarative triangle or quad geometry, my mesh code ought to be up to the task.

Anyway, enjoy!
Quote this message in a reply
Sage
Posts: 1,232
Joined: 2002.10
Post: #11
Thanks, this is very interesting to look at. Some parts, like the recursive sphere subdivision, are quite different than what I would have thought to do. But that's what I wanted-- to see different implementations to get ideas.

One thing I'm going to have to do differently for radiosity purposes is to regularly subdivide objects on a grid according to their scale in world space. Looks like maintaining the face connectivity is going to be critical, I'll have to go read up on data structures for that...

Also, I think that you can do your shadow stenciling in one pass on 9600+ with ATI_separate_stencil or with EXT_stencil_two_side on 5200+, so you might want to check those extensions out. Still need two passes on earlier cards...
Quote this message in a reply
Sage
Posts: 1,199
Joined: 2004.10
Post: #12
arekkusu Wrote:Also, I think that you can do your shadow stenciling in one pass on 9600+ with ATI_separate_stencil or with EXT_stencil_two_side on 5200+, so you might want to check those extensions out. Still need two passes on earlier cards...

That's my next step -- profiling with and without shadowing you can really see what a fillrate hit drawing the volume twice causes.

As regards further subdivision of surfaces, the recursive sphere example shows you can declare points several times and the internal mechanisms will manage edge lists and filter out redundant points automatically -- so long as it's in the first call to reshape().
Quote this message in a reply
Sage
Posts: 1,199
Joined: 2004.10
Post: #13
I got single-pass stencil shadowing working! FPS went up from 125 to 165!

But I can only test against NVIDIA; and I'm not certain even *how* to use the ATI extension. I'll read up on it. Thanks for the tips!
Quote this message in a reply
Sage
Posts: 1,199
Joined: 2004.10
Post: #14
One more question...

I realized with some testing that without an infinite projection matrix, the shadows are in fact quite non-robust. So, reading up I discovered the NVIDIA extension GL_DEPTH_CLAMP_NV -- which *seems* to solve the problem more or less.

That said, I don't have a machine with an ATI card to test against. Will DEPTH_CLAMP work on an ATI? If not, what alternative(s) do I have -- aside from an infinite projection?
Quote this message in a reply
Sage
Posts: 1,232
Joined: 2002.10
Post: #15
NV_DEPTH_CLAMP isn't supported on any ATI cards. You can use a fragment program as an alternative, on cards which can run fragment programs. See for example frustrum's shadow volume demo.
Quote this message in a reply
Post Reply 

Possibly Related Threads...
Thread: Author Replies: Views: Last Post
  OpenGL and concave meshes Ashford 3 4,151 Nov 21, 2009 10:31 AM
Last Post: AnotherJake
  Display Lists and Obj. File Loader Problems merrill541 0 1,898 Oct 17, 2008 06:42 PM
Last Post: merrill541
  VBOs and Vertex Arrays in OpenGL not working Talyn 6 6,243 Jul 8, 2008 01:14 PM
Last Post: Fenris
  Text rendering problem with VBOs on myfeng 9 5,830 Feb 29, 2008 04:54 PM
Last Post: OneSadCookie
  GL_SELECT mode in VBOs myfeng 0 2,301 Feb 28, 2008 10:38 AM
Last Post: myfeng