[osg-users] Best practice for dynamic StateSets & Geometry

Jannik Heller scrawl at baseoftrash.de
Tue Apr 14 10:28:44 PDT 2015

Hi OSG friends,

A common challenge for OSG users are the implications of the viewer threading model - by default the viewer.frame() will return before the draw dispatch is complete, meaning users (and the OSG) can start preparing the next frame before the current frame has completed. However, if you attempt to change a StateSet or Drawable in the frame update, you run the risk of modifying data that the OSG is still working with in a background thread, resulting in crashes.
Often times you will see code dealing with this by setting the DataVariance of the object to DYNAMIC. Unfortunately as result the draw dispatch has to complete before the frame() returns, for me this dropped the frame rate in half. 
Recently I developed a more efficient solution for dealing with this and would like to hear your thoughts.
The idea is similar to "double buffering" with the framebuffer - you create two copies of the data on start, one copy is write only, another copy is read only, and when the frame completes the roles are swapped. You can implement this idea for both Drawables and StateSets:
- Dynamic Drawables (RigGeometry, MorphGeometry, etc): create a deep copy of the Drawable, decorate both Drawables with a FrameSwitch node. A FrameSwitch node is a variant of Group that only traverses even or non-even children based on the current FrameStamp. Code (https://github.com/OpenMW/openmw/blob/f7da9796692e14c79632cb85fa75a90b082cd863/components/nifosg/nifloader.cpp#L179) 
- Dynamic StateSets: Create two copies of the StateSet on start, then every frame in a NodeCallback swap the roles of these StateSets, apply changes to the first StateSet, then set the currently active StateSet on the Node. Code (https://github.com/scrawl/openmw/blob/osg/components/sceneutil/statesetupdater.cpp#L8)

There are some downsides to this approach (mostly that for data that is just rarely changing, you have to apply every change twice), but other than that it works beautifully and now I've got 2x the framerate again.

I'm curious how the OSG veterans are dealing with this. Anything I've missed?


Read this topic online here:

More information about the osg-users mailing list