Possible approaches to drawing > 200000 objects

Hello everybody!

I am considering possible ways to handle more than 200000 polygonal objects efficiently in an OpenGL scene.

Each object is a polygonal mesh contaning about 50-60 triangles.
Each object’s geometry is static. The object list varies: arbitrary objects can be deleted or inserted.
Visual attributes (e.g. color) can be changed individually for each object, also it should be possible to enable/disable depth test for individual objects.

So far I have realized that there are two alternatives:

  1. Packing each object into a display list.
  2. Creating a VBO for each object.

Could anybody tell me if there is a clear benefit of one of these techniques or not?
What is more efficient: creating and redrawing 200000 display lists or creating and redrawing 200000 equivalent VBOs?

I guess my problem is not at all new, for instance I have found this topic: http://www.opengl.org/discussion_boards/ubbthreads.php?ubb=showflat&Number=280780#Post280780
But the situation is different there, in my case I really need to have fine granularity of geometry…

Thanks a lot in advance for the answers!

Cheers,
Sergey

Is the geometry for each object unique, or is it the same?
How are you handling the positioning and colour / texture for each object?
If there is enough similarity between objects you may be able to use some instancing techniques; the exact choice of technique will depend on what you are trying to do.

Geometry of each object is unique, it comes from an external application, so instancing is hardly applicable.
All objects can be grouped according to their material properties and depth test being on/off. But geometry is different for any two objects.

Basically, here is what I am going to do:

  1. Create a separate dislay list of VBO per an object that draws the geometry.
  2. Group display lists/VBOs according to material properties and depth test flag, to minimize OpenGL state changes, set corresponding attributes for the whole group and draw all display lists/VBOs belonging to the group at once.
  3. When an object is created or deleted, I simply create/delete the display list/VBO and update the group the object belongs to.
  4. When some object’s attributes are changed, I need to update only two groups: the previous and the new ones, without rebuilding any geometry.

It looks nice on the paper, but I have serious doubts that OpenGL can handle such a large number of display lists/VBOs efficiently, this is why I’m here with my question :slight_smile:

You should not create 200,000 individual buffer objects. You should create a few buffer objects and put multiple objects in each one.

Sounds cool!
But what about adding/deleting some objects? In case of a global VBO I would have to:

  1. Copy the updated array of vertex coorinates + normals to graphic card when I insert or remove some vertices belonging to the object being added/deleted.
  2. Re-index all the vertices and rebuild more than 10M triangles.
  3. Copy the updated element array to graphic memory.

So the procedure is really time-killing!

Another issue: I need to change the color of some element individually, or enable/disable depth test for it - how can I do this if I have a single array of vertex coordinates and a single element array?

I admit I might not understand something about efficient VBO usage in situations like mine.
So if you give some hints on that or some links to good articles, I would be really thankful!

Copy the updated array of vertex coorinates + normals to graphic card when I insert or remove some vertices belonging to the object being added/deleted.

You don’t need to copy anything when deleting an object. You only need to change things when uploading data.

Re-index all the vertices and rebuild more than 10M triangles.

Um, what? Each object is independent of the rest. So there’s no need to re-index anything.

Copy the updated element array to graphic memory.

You mentioned this one already.

I need to change the color of some element individually

What do you mean by “element”? A vertex, a triangle, an object? None of the above?

Sorry, I didn’t understand this at all. Does “uploading” stand for “copying data to graphic memory”? If yes, then I do need to copy, of course if I don’t want to create a vertex array that contains all vertices ever existed since the app was started and thus grows endlessly.
Or maybe VBOs allow deleteing a piece in the middle at zero cost like C++ lists - but I’m not sure at all.

Apart from the above, I have to keep a copy of my geometry in CPU memory for some other reasons. For me, it would be ideal if I could upload the inital geometry once and then add/remove small chunks of it corresponding to specific objects…

Then I guess I miss something important.
I believe all vertices should be kept in a global array, for drawing speed reasons, right?

Then, I need another array (connectivity) holding indices of vertices, to draw triangles. Each vertex has its unique index, some vertices might be shared by several triangles. Thus when some vertices are removed, I have to update the connectivity array one way or another, because the indices of remaining vertices have also changed!
Is there any way to avoid this?

Not exactly this one, but the array of vertex coordinates.
I have to handle at least two arrays: coordinates and connectivity, right?

An object, that is, a set of triangles. And also I have to turn on/off depth test for a specific object or a sub-set of objects.