20,741
edits
m (→Data Variance) |
m (→Sharing scenes) |
||
Line 429: | Line 429: | ||
mechanisms for doing a swap ready check for multi-context systems <ref>https://www.mail-archive.com/osg-users@lists.openscenegraph.org/msg72040.html</ref> | mechanisms for doing a swap ready check for multi-context systems <ref>https://www.mail-archive.com/osg-users@lists.openscenegraph.org/msg72040.html</ref> | ||
=== Scene Modification === | |||
You should only update a stateset, drawable, or the scene graph structure from the update traversal, update callback, or update operation. Are you modifying anything at runtime? | |||
Outside of the Optimizer, DataVariance has no effect in SingleThreaded mode. It also has no effect on Nodes (only Drawables and StateSets). | |||
Modifying the scene graph outside of the frame call is safe in | |||
SingleThreader, and CullDrawThreadPerCamera threading models as they | |||
don't leave any threads active after the end of the | |||
renderingTraversals() method (called from frame()). | |||
With DrawThreadPerContext and CullThreadPerCamewraDrawThreadPerContext | |||
the draw threads will still be active on completion of the | |||
renderingTraversals(), so if you modifying drawables and state that | |||
the thread is still reading from in the draw traversal you will end up | |||
with problems - and potential crashes. There is a standard mechanism | |||
to deal with this issue - and that is the renderingTraversals() method | |||
to block till all dynamic objects in the draw traversals have been | |||
dispatched. The way you tell the draw traversal that an drawable or | |||
stateset will be modified dynamically is to set its data variance to | |||
DYNAMIC.<ref>https://groups.google.com/g/osg-users/c/xCW-Y721YiI/m/vuYJEx_jcAYJ</ref> | |||
<code> | |||
drawable->setDataVariance(osg::Object::DYNAMIC); | |||
stateset->setDataVariance(osg::Object::DYNAMIC); | |||
</code> | |||
If you are modifying the stateset then you'll need | |||
to set its data variance to DYNAMIC. For a StateSet that decorates | |||
the whole scene graph you'll end you holding back the frame till the | |||
whole scene graph is completed, so it won't have any performance | |||
advantage over CullDrawThreadPerContext. You can double buffer | |||
objects to allow you to retain the STATIC data variance and keep the | |||
threads overlapping, to do this you do: | |||
<code> | |||
osg::Camera* cam = getViewer()->getView(i)->getCamera(); | |||
cam->setStateSet() = new StateSet; // this is where we just use a new | |||
StateSet rather than modify the previous one | |||
</code> | |||
<code> | |||
cam->getOrCreateStateSet()->setGlobalDefaults(); | |||
... And some other changes ... | |||
</code> | |||
The draw traversal takes a reference to the StateSet and Drawables so | |||
it's safe to go an remove them from the scene graph outside the | |||
frame() call, this isn't something makes then dynamic so you won't | |||
need to set their data variance to DYNAMIC. | |||
=== Sharing scenes === | === Sharing scenes === | ||
The osgViewer has a mechanism for avoid multiple traversals of shared | The osgViewer has a mechanism for avoid multiple traversals of shared |