diff --git a/include/osg/PointSprite b/include/osg/PointSprite index f60073e8d..83d826fff 100644 --- a/include/osg/PointSprite +++ b/include/osg/PointSprite @@ -46,6 +46,8 @@ public: return true; } + virtual bool checkValididityOfAssociatedModes(osg::State&) const; + virtual bool isTextureAttribute() const { return true; } virtual void apply(osg::State& state) const; diff --git a/include/osg/State b/include/osg/State index cea3d6846..a206ba203 100644 --- a/include/osg/State +++ b/include/osg/State @@ -201,6 +201,22 @@ class OSG_EXPORT State : public Referenced void apply(); + /** Set whether a particular OpenGL mode is valid in the current graphics context. + * Use to disable OpenGL modes that are not supported by current graphics drivers/context.*/ + inline void setModeValidity(StateAttribute::GLMode mode,bool valid) + { + ModeStack& ms = _modeMap[mode]; + ms.valid = valid; + } + + /** Get whether a particular OpenGL mode is valid in the current graphics context. + * Use to disable OpenGL modes that are not supported by current graphics drivers/context.*/ + inline bool getModeValidity(StateAttribute::GLMode mode) + { + ModeStack& ms = _modeMap[mode]; + return ms.valid; + } + inline void setGlobalDefaultModeValue(StateAttribute::GLMode mode,bool enabled) { ModeStack& ms = _modeMap[mode]; @@ -775,11 +791,13 @@ class OSG_EXPORT State : public Referenced ModeStack() { + valid = true; changed = false; last_applied_value = false; global_default_value = false; } + bool valid; bool changed; bool last_applied_value; bool global_default_value; @@ -828,7 +846,7 @@ class OSG_EXPORT State : public Referenced */ inline bool applyMode(StateAttribute::GLMode mode,bool enabled,ModeStack& ms) { - if (ms.last_applied_value != enabled) + if (ms.valid && ms.last_applied_value != enabled) { ms.last_applied_value = enabled; diff --git a/include/osg/StateAttribute b/include/osg/StateAttribute index 771c8af6b..ce147c448 100644 --- a/include/osg/StateAttribute +++ b/include/osg/StateAttribute @@ -270,6 +270,14 @@ class OSG_EXPORT StateAttribute : public Object return false; } + /** Check the modes associated with this StateAttribute are supported by current OpenGL drivers, + * and if not set the associated mode in osg::State to be black listed/invalid. + * Return true if all associated modes are valid.*/ + virtual bool checkValididityOfAssociatedModes(osg::State&) const + { + // default to no black listed GLMode's associated with use of the StateAttribute. + return true; + } struct Callback : public virtual osg::Object { diff --git a/include/osg/StateSet b/include/osg/StateSet index 338a9c94c..e6e31e9c8 100644 --- a/include/osg/StateSet +++ b/include/osg/StateSet @@ -410,6 +410,10 @@ class OSG_EXPORT StateSet : public Object /** Run the event callbacks attached directly to this StateSet or to its children.*/ void runEventCallbacks(osg::NodeVisitor* nv); + /** Check the modes associated with this StateSet are supported by current OpenGL drivers, + * and if not set the associated mode in osg::State to be black listed/invalid. + * Return true if any modes have been black listed.*/ + bool checkValididityOfAssociatedModes(State& state) const; /** call compile on all StateAttributes contained within this StateSet.*/ void compileGLObjects(State& state) const; diff --git a/include/osgUtil/GLObjectsVisitor b/include/osgUtil/GLObjectsVisitor index c7e4a9051..3f616e64c 100644 --- a/include/osgUtil/GLObjectsVisitor +++ b/include/osgUtil/GLObjectsVisitor @@ -40,7 +40,8 @@ class OSGUTIL_EXPORT GLObjectsVisitor : public osg::NodeVisitor RELEASE_DISPLAY_LISTS = 0x10, RELEASE_STATE_ATTRIBUTES = 0x20, SWITCH_ON_VERTEX_BUFFER_OBJECTS = 0x40, - SWITCH_OFF_VERTEX_BUFFER_OBJECTS = 0x80 + SWITCH_OFF_VERTEX_BUFFER_OBJECTS = 0x80, + CHECK_BLACK_LISTED_MODES = 0xA0 }; typedef unsigned int Mode; @@ -50,7 +51,15 @@ class OSGUTIL_EXPORT GLObjectsVisitor : public osg::NodeVisitor * display list/texture objects etc. Default mode is to compile * GL objects. */ - GLObjectsVisitor(Mode mode=COMPILE_DISPLAY_LISTS|COMPILE_STATE_ATTRIBUTES); + GLObjectsVisitor(Mode mode=COMPILE_DISPLAY_LISTS|COMPILE_STATE_ATTRIBUTES|CHECK_BLACK_LISTED_MODES); + + + 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; } @@ -84,9 +93,13 @@ class OSGUTIL_EXPORT GLObjectsVisitor : public osg::NodeVisitor protected: - Mode _mode; + typedef std::set DrawableAppliedSet; + typedef std::set StatesSetAppliedSet; - osg::ref_ptr _state; + Mode _mode; + osg::ref_ptr _state; + DrawableAppliedSet _drawablesAppliedSet; + StatesSetAppliedSet _stateSetAppliedSet; }; diff --git a/src/osg/PointSprite.cpp b/src/osg/PointSprite.cpp index d9fbdd79f..7c6453e6c 100644 --- a/src/osg/PointSprite.cpp +++ b/src/osg/PointSprite.cpp @@ -16,6 +16,7 @@ #include #include #include +#include using namespace osg; @@ -30,6 +31,16 @@ int PointSprite::compare(const StateAttribute& sa) const return 0; // passed all the above comparison macro's, must be equal. } + +bool PointSprite::checkValididityOfAssociatedModes(osg::State& state) const +{ + + bool modeValid = isPointSpriteSupported(state.getContextID()); + state.setModeValidity(GL_POINT_SPRITE_ARB, modeValid); + + return modeValid; +} + void PointSprite::apply(osg::State& state) const { if(!isPointSpriteSupported(state.getContextID())) return; diff --git a/src/osg/State.cpp b/src/osg/State.cpp index 0cb9958a5..22bcc6b73 100644 --- a/src/osg/State.cpp +++ b/src/osg/State.cpp @@ -53,7 +53,7 @@ State::~State() void State::reset() { -/* +#if 1 for(ModeMap::iterator mitr=_modeMap.begin(); mitr!=_modeMap.end(); ++mitr) @@ -63,9 +63,10 @@ void State::reset() ms.last_applied_value = !ms.global_default_value; ms.changed = true; } -*/ - +#else _modeMap.clear(); +#endif + _modeMap[GL_DEPTH_TEST].global_default_value = true; _modeMap[GL_DEPTH_TEST].changed = true; diff --git a/src/osg/StateSet.cpp b/src/osg/StateSet.cpp index f02bf1fb6..99f84789b 100644 --- a/src/osg/StateSet.cpp +++ b/src/osg/StateSet.cpp @@ -1131,6 +1131,32 @@ const StateSet::RefAttributePair* StateSet::getTextureAttributePair(unsigned int return getAttributePair(_textureAttributeList[unit],type,0); } +bool StateSet::checkValididityOfAssociatedModes(osg::State& state) const +{ + + + bool modesValid = true; + for(AttributeList::const_iterator itr = _attributeList.begin(); + itr!=_attributeList.end(); + ++itr) + { + if (!itr->second.first->checkValididityOfAssociatedModes(state)) modesValid = false; + } + + for(TextureAttributeList::const_iterator taitr=_textureAttributeList.begin(); + taitr!=_textureAttributeList.end(); + ++taitr) + { + for(AttributeList::const_iterator itr = taitr->begin(); + itr!=taitr->end(); + ++itr) + { + if (!itr->second.first->checkValididityOfAssociatedModes(state)) modesValid = false; + } + } + + return modesValid; +} void StateSet::compileGLObjects(State& state) const { diff --git a/src/osgUtil/GLObjectsVisitor.cpp b/src/osgUtil/GLObjectsVisitor.cpp index 3214d3387..c0790222a 100644 --- a/src/osgUtil/GLObjectsVisitor.cpp +++ b/src/osgUtil/GLObjectsVisitor.cpp @@ -60,6 +60,10 @@ void GLObjectsVisitor::apply(osg::Geode& node) void GLObjectsVisitor::apply(osg::Drawable& drawable) { + if (_drawablesAppliedSet.count(&drawable)!=0) return; + + _drawablesAppliedSet.insert(&drawable); + if (_mode&SWITCH_OFF_DISPLAY_LISTS) { drawable.setUseDisplayList(false); @@ -93,12 +97,22 @@ void GLObjectsVisitor::apply(osg::Drawable& drawable) void GLObjectsVisitor::apply(osg::StateSet& stateset) { - if (_mode&COMPILE_STATE_ATTRIBUTES && _state.valid()) + if (_stateSetAppliedSet.count(&stateset)!=0) return; + + _stateSetAppliedSet.insert(&stateset); + + if (_mode & COMPILE_STATE_ATTRIBUTES && _state.valid()) { stateset.compileGLObjects(*_state); } - if (_mode&RELEASE_STATE_ATTRIBUTES) + + if (_mode & RELEASE_STATE_ATTRIBUTES) { stateset.releaseGLObjects(_state.get()); } + + if (_mode & CHECK_BLACK_LISTED_MODES) + { + stateset.checkValididityOfAssociatedModes(*_state.get()); + } } diff --git a/src/osgUtil/SceneView.cpp b/src/osgUtil/SceneView.cpp index 4b683a65f..c6e6977ab 100644 --- a/src/osgUtil/SceneView.cpp +++ b/src/osgUtil/SceneView.cpp @@ -163,7 +163,9 @@ void SceneView::setDefaults(unsigned int options) if (options & COMPILE_GLOBJECTS_AT_INIT) { - GLObjectsVisitor::Mode dlvMode = GLObjectsVisitor::COMPILE_DISPLAY_LISTS|GLObjectsVisitor::COMPILE_STATE_ATTRIBUTES; + GLObjectsVisitor::Mode dlvMode = GLObjectsVisitor::COMPILE_DISPLAY_LISTS | + GLObjectsVisitor::COMPILE_STATE_ATTRIBUTES | + GLObjectsVisitor::CHECK_BLACK_LISTED_MODES; #ifdef __sgi dlvMode = GLObjectsVisitor::COMPILE_STATE_ATTRIBUTES;