Jump to content
  • Advertisement
Sign in to follow this  
ileonte

OpenGL How do you structure your geometry data ?

This topic is 2838 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've been fiddling with OpenGL lately. I've done some pretty basic stuff (I can load 3DS files, lighting, texturing, move the camera around, etc.) but with no 'logic' behind it - I just fly around 'space' with floating objects :) Now I'd like to start actually making a small game but I'm having a hard time figuring out how I should structure my data.

Say I have a scene where I have to load several meshes from different files. These will be structured into 'objects' (houses, trees, cars, whatever) which will be part of the scene graph (tree) (1). On top of this I will probably end up using an octtree to perform view frustum culling (2). Right now I'm using display lists to draw the meshes but that can lead to inefficient culling (say I have an object so large that I can only display a small part of it - using display lists would still cause me to draw the entire object). I was thinking of switching to indexed arrays (glDrawElements() and co.) in order to be able to 'cut' the geometry data using the view frustum bounding planes (3).

This is where I hit the road block:
(*) how do I structure the geometry data so that (1),(2) and (3) can be easily done ?
(*) how do I structure the geometry data so that I can handle the above as well as moving objects ?

Any and all tips are welcome and greatly appreciated.

Share this post


Link to post
Share on other sites
Advertisement
In my experience it doesn't work like that

Each major type of object lends itself to different rendering techniques and different frustum culling approaches etc.

For example:

Tree instance data is loaded when they are potentially visible
actual visibility is a simple case of intersecting the view frustum with a 5x5 uniform grid (of cells surrounding the camera)

At no point in that scenario would an octree help.

In fact octrees are not much use in a video game, maybe in architectural rendering etc.

I group my objects like so:

- mostly static (either don't move or don't move far) trees, bldgs, birds, rocks
- totally dynamic (could be anywhere at any time)
- terrain

So don't make your mind up too soon and end up wasting time and energy on things like octrees - wait until you understanding the issues (taking into account instancing and impostering etc.) and the right solution will then be obvious.

I think everybody builds an octree only to find out they are rubbish.

What isn't rubbish: uniform grids, spatial hashes, modulo grids.

Share this post


Link to post
Share on other sites
In fact octree has been useful mainly and probably just with voxel rendering. It is also possible to not use any optimisation scheme at all with current gpus (though it is not common in complex scenes).

Optimisation is based upon what kind of scene are you rendering, games like Oblivion - large open world - are critical in good LOD and frustum culling ... no occlusion is probably needed (it might also slow it down!).

Frustum culling can be done simply testing objects bounding box (the best is axis aligned ... it makes it simple and fast) against frustum ... that is 6 planes (left, right, top, bottom, near and far) ... or one can use even bounding box of view frustum to make it even more simple (and faster).

I'm structuring my data in a more complicated way, I store model and its bounding volume hierarchy (optimisation scheme I need for raytracing), In fact octree has been useful mainly and probably just with voxel rendering. It is also possible to not use any optimisation scheme at all with current gpus (though it is not common in complex scenes).

Optimisation is based upon what kind of scene are you rendering, games like Oblivion - large open world - are critical in good LOD and frustum culling ... no occlusion is probably needed (it might also slow it down!).

Frustum culling can be done simply testing objects bounding box (the best is axis aligned ... it makes it simple and fast) against frustum ... that is 6 planes (left, right, top, bottom, near and far) ... or one can use even bounding box of view frustum to make it even more simple (and faster).

I'm structuring my data in a more complicated way, scene holds models and tree of them, models holds mesh id, material id, where mesh holds the model (vertices, tangents, and such) and bounding volume hierarchy of the model, material holds material properties and texture ids, textures holds texture itself.
The meshes/models are divided to fully static (I build model BVH just once, at application start, again they're inserted into scene tree just once at start of level), dynamic (non skinned, non deforming ... again I build their BVH just once, although they're removed and re-inserted every time they move) and fully dynamic (skinned, deforming ... I have to rebuild their BVH every frame they're deforming/moving, and remove and re-insert them into scene every time they move).

For handling moving objects it is the best to have them in some leaf node and every frame they move, remove that leaf and insert them into new one, best suited for them (you have to do some search of course).

Cutting parts of geometry is practically useless unless you use really huge model. The only huge model you should use for beginning should be terrain afaik, and it is better to compose it from cells (with good LOD and applied view frustum culling), they are very fast.

Share this post


Link to post
Share on other sites
Thank you both for your replies. There are a few things I don't understand.

First, you say that 'cutting' geometry is useless in practice. I don't really understand this point. Say that one of the view frustum bounding plane intersects several models totaling 2 million faces of which only 100.000 faces are actually visible. How is it not desirable to cull those 1.9 million invisible faces ?

Second, you seem to be advocating 'specialized' culling methods optimized based on the type of game that I'm working on. This seems counter-productive to me, clearly against the 'game engine' paradigm. Surely there must exist generic methods to perform culling irrespective of the type of scene I'm rendering.

Share this post


Link to post
Share on other sites
Because in games, the only objects you're likely to have that are of that scale are the ground and the sky and there are better ways of culling both of those.

In general, most objects will either be "human scale" -- people, trees, vehicles etc, which can be culled or drawn in their entirety, or they can reasonably easily be subdivided -- buildings can be split into components.

Share this post


Link to post
Share on other sites
I would advise to use Octrees for big static meshes. I've used them in my engines and they certainly have a big impact on the speed of rendering.

For dynamic objects, try to do narrow-phase collisions first and if you still have a slow engine, then that's the time to find other ways to optimize rendering.

Share this post


Link to post
Share on other sites
Quote:
Because in games, the only objects you're likely to have that are of that scale are the ground and the sky and there are better ways of culling both of those.

I'm very curious on that. Would you mind to elaborate?

Thank you.

Share this post


Link to post
Share on other sites
You can split them into sections, for example. The landscape can be turned into square chunks. You only draw chunks which are visible. You *can* do this with an oct tree or stuff like that, but if your landscape chunks are all the same size, you can just do it with grid-based calculations.

For example, you know which grid section the camera is over. So you immediately have a pretty good candidate set. If your camera is roughly horizontal or downwards pointing, you can possibly construct a grid which contains the rotation angle about the vertical at which relative grid chunks are visible.

Or you could just take the NxN square around the camera and test each chunk for visibility. Or you could assume the MxM and draw it and then just test the NxN larger square's chunks.

Share this post


Link to post
Share on other sites
Quote:
Original post by relsoft
I would advise to use Octrees for big static meshes. I've used them in my engines and they certainly have a big impact on the speed of rendering.

For dynamic objects, try to do narrow-phase collisions first and if you still have a slow engine, then that's the time to find other ways to optimize rendering.
Seconded, a lightweight, non-recursive Octree will definitely help if your scene is suitable (not much occlusion, relatively static and high total polygon count with lop sided ratio of visible:non-visible at any given time). They are very easy to write as well, so hardly a waste of time if you have no scheme at all, in fact a great way to ease into a more complex system.

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!