#ifndef OSG_STATE #define OSG_STATE 1 #include #include #include #include #include namespace osg { /** macro for use with osg::StateAttrbiute::apply methods for detected and * reporting OpenGL error messages.*/ #define OSG_GL_DEBUG(message) \ if (state.getFineGrainedErrorDetection()) \ { \ GLenum errorNo = glGetError(); \ if (errorNo!=GL_NO_ERROR) \ { \ osg::notify(WARN)<<"Warning: detected OpenGL error '"<getType()]); } /** apply stateset.*/ void apply(const StateSet* dstate); /** apply the state.*/ void apply(); /** mode has been set externally, update state to reflect this setting.*/ void have_applied(const StateAttribute::GLMode mode,const StateAttribute::GLModeValue value); /** attribute has been applied externally, update state to reflect this setting.*/ void have_applied(const StateAttribute* attribute); /** Set the current OpenGL context uniqueID. Note, it is the application developers responsiblity to set up unique ID for each OpenGL context. This value is then used by osg::StateAttribure's and osg::Drawable's to help manage OpenGL display list and texture binds appropriate for each context.*/ inline void setContextID(unsigned int contextID) { _contextID=contextID; } /** Get the current OpenGL context unique ID.*/ inline const unsigned int getContextID() const { return _contextID; } /** Set the frame number.*/ inline void setFrameNumber(unsigned int fn) { _frameNumber = fn; } /** Get the frame number.*/ inline unsigned int getFrameNumber() const { return _frameNumber; } /** Increment the frame number. Done once per frame.*/ inline void incrementFrameNumber() { ++_frameNumber; } /** Set the hint to OpenGL routines to do fine grained OpenGL error checking.*/ void setFineGrainedErrorDetection(const bool flag) { _fineGrainedErrorDetection = flag; } /** Get the hint to OpenGL routines to do fine grained OpenGL error checking.*/ const bool getFineGrainedErrorDetection() const { return _fineGrainedErrorDetection; } private: unsigned int _contextID; unsigned int _frameNumber; typedef std::vector ValueVec; struct ModeStack { ModeStack() { changed = false; last_applied_value = false; } bool changed; bool last_applied_value; ValueVec valueVec; }; typedef std::pair AttributePair; typedef std::vector AttributeVec; struct AttributeStack { AttributeStack() { changed = false; last_applied_attribute = 0L; } bool changed; const StateAttribute* last_applied_attribute; AttributeVec attributeVec; }; /** apply an OpenGL mode if required, passing in mode, enable flag and appropriate mode stack */ inline const bool apply_mode(const StateAttribute::GLMode mode,const bool enabled,ModeStack& ms) { if (ms.last_applied_value != enabled) { ms.last_applied_value = enabled; if (enabled) glEnable(mode); else glDisable(mode); return true; } else return false; } /** apply an attribute if required, passing in attribute and appropriate attribute stack */ inline const bool apply_attribute(const StateAttribute* attribute,AttributeStack& as) { if (as.last_applied_attribute != attribute) { as.last_applied_attribute = attribute; attribute->apply(*this); return true; } else return false; } typedef std::map ModeMap; typedef std::map AttributeMap; typedef std::vector > StateSetStack; typedef std::vector > MatrixStack; ModeMap _modeMap; AttributeMap _attributeMap; StateSetStack _drawStateStack; bool _fineGrainedErrorDetection; }; }; #endif