//C++ header - Open Scene Graph - Copyright (C) 1998-2001 Robert Osfield //Distributed under the terms of the GNU Library General Public License (LGPL) //as published by the Free Software Foundation. #ifndef OSG_STATE #define OSG_STATE 1 #include #include #include #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()]); } inline void applyProjectionMatrix(const osg::Matrix* matrix) { if (_projection!=matrix) { glMatrixMode( GL_PROJECTION ); if (matrix) { _projection=matrix; glLoadMatrixf(matrix->ptr()); } else { _projection=_identity; glLoadIdentity(); } glMatrixMode( GL_MODELVIEW ); } } const osg::Matrix& getProjectionMatrix() const { return *_projection; } inline void applyModelViewMatrix(const osg::Matrix* matrix) { if (_modelView!=matrix) { if (matrix) { _modelView=matrix; glLoadMatrixf(matrix->ptr()); } else { _modelView=_identity; glLoadIdentity(); } } } const osg::Matrix& getModelViewMatrix() const { return *_modelView; } ClippingVolume getClippingVolume() const; /** apply stateset.*/ void apply(const StateSet* dstate); /** apply the state.*/ void apply(); /** mode has been set externally, update state to reflect this setting.*/ void haveAppliedMode(const StateAttribute::GLMode mode,const StateAttribute::GLModeValue value); /** mode has been set externally, therefore dirty the associated mode in osg::State * so it is applied on next call to osg::State::apply(..)*/ void haveAppliedMode(const StateAttribute::GLMode mode); /** attribute has been applied externally, update state to reflect this setting.*/ void haveAppliedAttribute(const StateAttribute* attribute); /** attribute has been applied externally, * and therefore this attribute type has been dirtied * and will need to be re-appplied on next osg::State.apply(..). * note, if you have an osg::StateAttribute which you have applied externally * then use the have_applied(attribute) method as this will the osg::State to * track the current state more accuratly and enable lazy state updating such * that only changed state will be applied.*/ void haveAppliedAttribute(const StateAttribute::Type type); /** Set the current OpenGL context uniqueID. Note, it is the application developers responsibility 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 stamp for the current frame.*/ inline void setFrameStamp(FrameStamp* fs) { _frameStamp = fs; } /** Set the frame stamp for the current frame.*/ inline const FrameStamp* getFrameStamp() const { return _frameStamp.get(); } /** Set the DisplaySettings. Note, nothing is applied, the visual settings are just used * used in the State object to pass the current visual settings to Drawables * during rendering. */ inline void setDisplaySettings(DisplaySettings* vs) { _displaySettings = vs; } /** Get the DisplaySettings */ inline const DisplaySettings* getDisplaySettings() const { return _displaySettings.get(); } typedef std::pair AttributePair; typedef std::vector AttributeVec; typedef std::vector ValueVec; private: unsigned int _contextID; ref_ptr _frameStamp; ref_ptr _identity; ref_ptr _projection; ref_ptr _modelView; ref_ptr _displaySettings; struct ModeStack { ModeStack() { changed = false; last_applied_value = false; global_default_value = false; } bool changed; bool last_applied_value; bool global_default_value; ValueVec valueVec; }; struct AttributeStack { AttributeStack() { changed = false; last_applied_attribute = 0L; global_default_attribute = 0L; } /** apply an attribute if required, passing in attribute and appropriate attribute stack */ bool changed; const StateAttribute* last_applied_attribute; ref_ptr global_default_attribute; AttributeVec attributeVec; }; /** apply an OpenGL mode if required, passing in mode, enable flag and appropriate mode stack */ inline const bool applyMode(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 applyAttribute(const StateAttribute* attribute,AttributeStack& as) { if (as.last_applied_attribute != attribute) { if (!as.global_default_attribute.valid()) as.global_default_attribute = dynamic_cast(attribute->cloneType()); as.last_applied_attribute = attribute; attribute->apply(*this); return true; } else return false; } inline const bool applyGlobalDefaultAttribute(AttributeStack& as) { if (as.last_applied_attribute != as.global_default_attribute.get()) { as.last_applied_attribute = as.global_default_attribute.get(); if (as.global_default_attribute.valid()) as.global_default_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; }; } #endif