/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield * * This library is open source and may be redistributed and/or modified under * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or * (at your option) any later version. The full license is in LICENSE file * included with this distribution, and on the openscenegraph.org website. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * OpenSceneGraph Public License for more details. */ #ifndef OSGUTIL_GLOBJECTSVISITOR #define OSGUTIL_GLOBJECTSVISITOR 1 #include #include #include #include #include namespace osgUtil { /** Visitor for traversing scene graph and setting each osg::Drawable's _useDisplayList flag, * with option to immediately compile osg::Drawable OpenGL Display lists and * osg::StateAttribute's. */ class OSGUTIL_EXPORT GLObjectsVisitor : public osg::NodeVisitor { public: /** Operation modes of the.*/ enum ModeValues { SWITCH_ON_DISPLAY_LISTS = 0x1, SWITCH_OFF_DISPLAY_LISTS = 0x2, COMPILE_DISPLAY_LISTS = 0x4, COMPILE_STATE_ATTRIBUTES = 0x8, RELEASE_DISPLAY_LISTS = 0x10, RELEASE_STATE_ATTRIBUTES = 0x20, SWITCH_ON_VERTEX_BUFFER_OBJECTS = 0x40, SWITCH_OFF_VERTEX_BUFFER_OBJECTS = 0x80, CHECK_BLACK_LISTED_MODES = 0x100 }; typedef unsigned int Mode; /** Construct a GLObjectsVisitor to traverse all children, operating on * node according to specified mode, such as to compile or release * display list/texture objects etc. Default mode is to compile * GL objects. */ GLObjectsVisitor(Mode mode=COMPILE_DISPLAY_LISTS|COMPILE_STATE_ATTRIBUTES|CHECK_BLACK_LISTED_MODES); META_NodeVisitor("osg","GLObjectsVisitor") virtual void reset() { _drawablesAppliedSet.clear(); _stateSetAppliedSet.clear(); } /** Set the operational mode of what operations to do on the scene graph.*/ void setMode(Mode mode) { _mode = mode; } /** Get the operational mode.*/ Mode getMode() const { return _mode; } /** Set the State to use during traversal. */ void setState(osg::State* state) { _renderInfo.setState(state); } osg::State* getState() { return _renderInfo.getState(); } void setRenderInfo(osg::RenderInfo& renderInfo) { _renderInfo = renderInfo; } osg::RenderInfo& getRenderInfo() { return _renderInfo; } /** Simply traverse using standard NodeVisitor traverse method.*/ virtual void apply(osg::Node& node); /** For each Geode visited set the display list usage according to the * _displayListMode. */ virtual void apply(osg::Geode& node); void apply(osg::Drawable& drawable); void apply(osg::StateSet& stateset); protected: typedef std::set DrawableAppliedSet; typedef std::set StatesSetAppliedSet; Mode _mode; osg::RenderInfo _renderInfo; DrawableAppliedSet _drawablesAppliedSet; StatesSetAppliedSet _stateSetAppliedSet; osg::ref_ptr _lastCompiledProgram; }; class OSGUTIL_EXPORT GLObjectsOperation : public osg::GraphicsOperation { public: GLObjectsOperation(GLObjectsVisitor::Mode mode = GLObjectsVisitor::COMPILE_DISPLAY_LISTS|GLObjectsVisitor::COMPILE_STATE_ATTRIBUTES|GLObjectsVisitor::CHECK_BLACK_LISTED_MODES); GLObjectsOperation(osg::Node* subgraph, GLObjectsVisitor::Mode mode = GLObjectsVisitor::COMPILE_DISPLAY_LISTS|GLObjectsVisitor::COMPILE_STATE_ATTRIBUTES|GLObjectsVisitor::CHECK_BLACK_LISTED_MODES); virtual void operator () (osg::GraphicsContext* context); protected: osg::ref_ptr _subgraph; GLObjectsVisitor::Mode _mode; }; class OSGUTIL_EXPORT IncrementalCompileOperation : public osg::GraphicsOperation { public: IncrementalCompileOperation(); typedef std::vector Contexts; void assignContexts(Contexts& contexts); void removeContexts(Contexts& contexts); void addGraphicsContext(osg::GraphicsContext* gc); void removeGraphicsContext(osg::GraphicsContext* gc); /** Merge subgraphs that have been compiled.*/ void mergeCompiledSubgraphs(); virtual void operator () (osg::GraphicsContext* context); struct CompileData : public osg::Referenced { typedef std::list< osg::ref_ptr > Drawables; typedef std::list< osg::ref_ptr > Textures; typedef std::list< osg::ref_ptr > Programs; bool empty() const { return _drawables.empty() && _textures.empty() && _programs.empty(); } Drawables _drawables; Textures _textures; Programs _programs; }; class CompileSet; typedef std::set ContextSet; typedef std::map CompileMap; struct CompileCompletedCallback : public osg::Referenced { virtual bool compileCompleted(CompileSet* compileSet) = 0; }; class CompileSet : public osg::Referenced { public: CompileSet() {} CompileSet(osg::Node*subgraphToCompile): _subgraphToCompile(subgraphToCompile) {} CompileSet(osg::Group* attachmentPoint, osg::Node*subgraphToCompile): _attachmentPoint(attachmentPoint), _subgraphToCompile(subgraphToCompile) {} void buildCompileMap(ContextSet& context, GLObjectsVisitor::Mode mode=GLObjectsVisitor::COMPILE_DISPLAY_LISTS|GLObjectsVisitor::COMPILE_STATE_ATTRIBUTES); bool compileCompleted() const { for(CompileMap::const_iterator itr = _compileMap.begin(); itr != _compileMap.end(); ++itr) { if (!(itr->second.empty())) return false; } return true; } osg::ref_ptr _attachmentPoint; osg::ref_ptr _subgraphToCompile; osg::ref_ptr _compileCompletedCallback; CompileMap _compileMap; // protected: virtual ~CompileSet() {} }; typedef std::list< osg::ref_ptr > CompileSets; /** Add a subgraph to be compiled.*/ void add(osg::Node* subgraphToCompile); /** Add a subgraph to be compiled and add automatically to attachPoint on call to mergeCompiledSubgraphs.*/ void add(osg::Group* attachmentPoint, osg::Node* subgraphToCompile); /** Add a CompileSet to be compiled.*/ void add(CompileSet* compileSet, bool callBuildCompileMap=true); OpenThreads::Mutex* getToCompiledMutex() { return &_toCompileMutex; } CompileSets& getToCompile() { return _compiled; } OpenThreads::Mutex* getCompiledMutex() { return &_compiledMutex; } CompileSets& getCompiled() { return _compiled; } protected: virtual ~IncrementalCompileOperation(); // forward declare to keep within class namespace class CollectStateToCompile; OpenThreads::Mutex _toCompileMutex; CompileSets _toCompile; OpenThreads::Mutex _compiledMutex; CompileSets _compiled; ContextSet _contexts; }; } #endif