diff --git a/include/osgUtil/DisplayListVisitor b/include/osgUtil/DisplayListVisitor index c1971ea1b..9581098c9 100644 --- a/include/osgUtil/DisplayListVisitor +++ b/include/osgUtil/DisplayListVisitor @@ -14,68 +14,52 @@ namespace osgUtil { /** Visitor for traversing scene graph and setting each osg::GeoSet's _useDisplayList flag, - * with option to immediately compile osg::GeoSet's OpenGL Display lists. - * The mode of operation - * of the visitor is controlled by setting the DisplayListMode either on visitor - * constructor or via the setDisplayListMode() method. DisplayListMode options are: - * _displayListMode == SWITCH_ON_AND_COMPILE_DISPLAY_LISTS cals gset->compile() on - * all Geode children. Note, the visitor must only be used within a valid - * OpenGL context as compile uses OpenGL calls. - * _displayListMode == SWITCH_ON_DISPLAY_LISTS sets the Geode's children with - * gset->setUseDisplayList(true), this method does not directly create display list, - * or uses OpenGL calls so if safe to use before a valid OpenGL context has been set up. - * On the next redraw of the scene, the gset's draw methods will be called - * which then will respond to their _useDisplayList being set by creating display lists - * automatically. - * _displayListMode == SWITCH_OFF_DISPLAY_LISTS sets the Geode's children with - * gset->setUseDisplayList(false), this method does not directly create display list, - * or uses OpenGL calls so if safe to use before a valid OpenGL context has been set up. + * with option to immediately compile osg::Drawable OpenGL Display lists and + * osg::StateAttribute's. */ class OSGUTIL_EXPORT DisplayListVisitor : public osg::NodeVisitor { public: - /** Operation modes of the DisplayListVisitor.*/ - enum DisplayListMode + /** Operation modes of the.*/ + enum ModeValues { - SWITCH_ON_AND_COMPILE_DISPLAY_LISTS, - COMPILE_ON_DISPLAY_LISTS, - SWITCH_ON_DISPLAY_LISTS, - SWITCH_OFF_DISPLAY_LISTS + SWITCH_ON_DISPLAY_LISTS = 0x1, + SWITCH_OFF_DISPLAY_LISTS = 0x2, + COMPILE_DISPLAY_LISTS = 0x4, + COMPILE_STATE_ATTRIBUTES = 0x8 }; + + typedef unsigned int Mode; /** Construct a CompileGeoSetsVisior to traverse all child, * with set specified display list mode. Default mode is to * gset->setUseDisplayList(true). */ - DisplayListVisitor(DisplayListMode mode=SWITCH_ON_DISPLAY_LISTS); + DisplayListVisitor(Mode mode=COMPILE_DISPLAY_LISTS|COMPILE_STATE_ATTRIBUTES); /** Set the operational mode of how the visitor should set up osg::GeoSet's.*/ - void setDisplayListMode(DisplayListMode mode) { _displayListMode = mode; } + void setMode(Mode mode) { _mode = mode; } /** Get the operational mode.*/ - DisplayListMode getDisplayListMode() const { return _displayListMode; } + Mode getMode() const { return _mode; } + /** Set the State to use during traversal. */ void setState(osg::State* state) { - _externalState = state; - if (_externalState.valid()) _activeState = _externalState; - else _activeState = _localState; + _state = state; } osg::State* getState() { - return _activeState.get(); + return _state.get(); } /** Simply traverse using standard NodeVisitor traverse method.*/ - virtual void apply(osg::Node& node) - { - traverse(node); - } - + virtual void apply(osg::Node& node); + /** For each Geode visited set the display list usage according to the * _displayListMode. */ @@ -83,14 +67,9 @@ class OSGUTIL_EXPORT DisplayListVisitor : public osg::NodeVisitor protected: - DisplayListMode _displayListMode; + Mode _mode; - /** local state is created in constructor and used as the default state during traversal.*/ - osg::ref_ptr _localState; - /** external state is used to override the default state.*/ - osg::ref_ptr _externalState; - /** active state is equal to _externalState when it is valid, otherwise defaults to _localState.*/ - osg::ref_ptr _activeState; + osg::ref_ptr _state; }; diff --git a/include/osgUtil/SceneView b/include/osgUtil/SceneView index 4ea05d61e..bf09a99fc 100644 --- a/include/osgUtil/SceneView +++ b/include/osgUtil/SceneView @@ -110,6 +110,10 @@ class OSGUTIL_EXPORT SceneView : public osg::Referenced const osg::State* getState() const { return _state.get(); } + void setInitVisitor(osg::NodeVisitor* av) { _initVisitor = av; } + osg::NodeVisitor* getInitVisitor() { return _initVisitor.get(); } + const osg::NodeVisitor* getInitVisitor() const { return _initVisitor.get(); } + void setAppVisitor(osg::NodeVisitor* av) { _appVisitor = av; } osg::NodeVisitor* getAppVisitor() { return _appVisitor.get(); } const osg::NodeVisitor* getAppVisitor() const { return _appVisitor.get(); } @@ -181,14 +185,22 @@ class OSGUTIL_EXPORT SceneView : public osg::Referenced inline const osg::FrameStamp* getFrameStamp() const { return _frameStamp.get(); } + /** Do init traversal of attached scene graph using Init NodeVisitor. + * The init traversal is called once for each SceneView, and should + * be used to compile display list, texture objects intialize data + * not otherwise intializaed during scene graph loading. Note, is + * called automatically by app&cull if it hasn't already been called + * elsewhere. Also init() should only ever be called within a valid + * graphics context.*/ + virtual void init(); - /** do app traversal of attached scene graph using App NodeVisitor.*/ + /** Do app traversal of attached scene graph using App NodeVisitor.*/ virtual void app(); - /** do cull traversal of attached scene graph using App CullVisitor.*/ + /** Do cull traversal of attached scene graph using Cull NodeVisitor.*/ virtual void cull(); - /** do draw traversal of draw bins generated by cull traversal.*/ + /** Do draw traversal of draw bins generated by cull traversal.*/ virtual void draw(); protected: @@ -201,6 +213,8 @@ class OSGUTIL_EXPORT SceneView : public osg::Referenced osg::ref_ptr _camera; osg::ref_ptr _state; + bool _initCalled; + osg::ref_ptr _initVisitor; osg::ref_ptr _appVisitor; osg::ref_ptr _cullVisitor; osg::ref_ptr _rendergraph; diff --git a/src/osgUtil/DisplayListVisitor.cpp b/src/osgUtil/DisplayListVisitor.cpp index b98909b15..69c51d3ce 100644 --- a/src/osgUtil/DisplayListVisitor.cpp +++ b/src/osgUtil/DisplayListVisitor.cpp @@ -4,53 +4,71 @@ using namespace osg; using namespace osgUtil; -DisplayListVisitor::DisplayListVisitor(DisplayListMode mode) +DisplayListVisitor::DisplayListVisitor(Mode mode) { setTraversalMode(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN); - _displayListMode = mode; - _localState = new osg::State; - _externalState = NULL; + _mode = mode; - _activeState = _localState; + _state = NULL; } +void DisplayListVisitor::apply(osg::Node& node) +{ + if ((_mode&COMPILE_STATE_ATTRIBUTES) && node.getStateSet() && _state.valid()) + { + node.getStateSet()->compile(*_state); + } + + traverse(node); +} + void DisplayListVisitor::apply(osg::Geode& node) { - switch(_displayListMode) + if (_mode&COMPILE_STATE_ATTRIBUTES && _state.valid()) { - case(SWITCH_OFF_DISPLAY_LISTS): + if (node.getStateSet()) { - for(int i=0;isetUseDisplayList(false); - } + node.getStateSet()->compile(*_state); } - break; - case(SWITCH_ON_DISPLAY_LISTS): + + for(int i=0;igetUseDisplayList()) { - node.getDrawable(i)->setUseDisplayList(true); - } - } - break; - case(COMPILE_ON_DISPLAY_LISTS): - { - for(int i=0;igetUseDisplayList()) + if (drawable->getStateSet()) { - node.getDrawable(i)->compile(*_activeState); + drawable->getStateSet()->compile(*_state); } } } - break; - case(SWITCH_ON_AND_COMPILE_DISPLAY_LISTS): + } + + if (_mode&SWITCH_OFF_DISPLAY_LISTS) + { + for(int i=0;isetUseDisplayList(false); + } + } + if (_mode&SWITCH_ON_DISPLAY_LISTS) + { + for(int i=0;isetUseDisplayList(true); + } + } + + if (_mode&COMPILE_DISPLAY_LISTS && _state.valid()) + { + for(int i=0;igetUseDisplayList()) + { + node.getDrawable(i)->compile(*_state); + } } - break; } } diff --git a/src/osgUtil/SceneView.cpp b/src/osgUtil/SceneView.cpp index f5cb78fd5..8298bbb49 100644 --- a/src/osgUtil/SceneView.cpp +++ b/src/osgUtil/SceneView.cpp @@ -1,5 +1,6 @@ #include #include +#include #include #include @@ -28,6 +29,8 @@ SceneView::SceneView() _viewport = new Viewport; + _initCalled = false; + } @@ -46,19 +49,21 @@ void SceneView::setDefaults() _light->setDiffuse(Vec4(0.8f,0.8f,0.8f,1.0f)); _light->setSpecular(Vec4(0.1f,0.1f,0.1f,1.0f)); - - - _camera = new osg::Camera; + _camera = new Camera; - _state = new osg::State; + _state = new State; - _rendergraph = new osgUtil::RenderGraph; - _renderStage = new osgUtil::RenderStage; + _rendergraph = new RenderGraph; + _renderStage = new RenderStage; - _appVisitor = new osgUtil::AppVisitor; - - _cullVisitor = new osgUtil::CullVisitor; + DisplayListVisitor* dlv = new DisplayListVisitor(); + dlv->setState(_state.get()); + _initVisitor = dlv; + + _appVisitor = new AppVisitor; + + _cullVisitor = new CullVisitor; _cullVisitor->setRenderGraph(_rendergraph.get()); _cullVisitor->setRenderStage(_renderStage.get()); @@ -85,9 +90,29 @@ void SceneView::setDefaults() } +void SceneView::init() +{ + _initCalled = true; + + if (_sceneData.valid() && _initVisitor.valid()) + { + _initVisitor->reset(); + _initVisitor->setFrameStamp(_frameStamp.get()); + + if (_frameStamp.valid()) + { + _initVisitor->setTraversalNumber(_frameStamp->getFrameNumber()); + } + + _sceneData->accept(*_initVisitor.get()); + + } +} void SceneView::app() { + if (!_initCalled) init(); + if (_sceneData.valid() && _appVisitor.valid()) { _appVisitor->reset(); @@ -108,8 +133,11 @@ void SceneView::app() void SceneView::cull() { + if (!_sceneData) return; + if (!_initCalled) init(); + _camera->adjustAspectRatio(_viewport->aspectRatio());