//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 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 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 camera. Note, nothing is applied, the camera is just used * used in the State object to pass the current camera to Drawables * during rendering. */ inline void setCamera(Camera* camera) { _camera = camera; } /** Get the camera */ inline const Camera* getCamera() const { return _camera.get(); } private: unsigned int _contextID; ref_ptr _frameStamp; ref_ptr _camera; typedef std::vector ValueVec; 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; }; typedef std::pair AttributePair; typedef std::vector AttributeVec; 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 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) { if (!as.global_default_attribute.valid()) as.global_default_attribute = dynamic_cast(attribute->clone()); as.last_applied_attribute = attribute; attribute->apply(*this); return true; } else return false; } inline const bool apply_global_default_attribute(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