OpenSceneGraph/include/osg/State
Robert Osfield 341ffb2361 Further work on cleaning up SceneView and Camera, in particular moving strereo
support out of Camera and into SceneView. Also enabled the option to set the
projection and modelview matrices directly on SceneView thereby removing the
dependance on osg::Camrea to control the view of the scene.
2002-04-12 18:06:13 +00:00

280 lines
9.2 KiB
Plaintext

//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 <osg/Export>
#include <osg/StateSet>
#include <osg/Matrix>
#include <osg/FrameStamp>
#include <osg/DisplaySettings>
#include <osg/ClippingVolume>
#include <vector>
#include <map>
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 '"<<gluErrorString(errorNo)<<" "<<message<<endl; \
}\
}
/** State class for managing a state stack.
* Lazy state updating is used to minimize state changes.
*/
class SG_EXPORT State : public Referenced
{
public :
State();
virtual ~State();
/** push stateset onto state stack.*/
void pushStateSet(const StateSet* dstate);
/** pop drawstate off state stack.*/
void popStateSet();
/** copy the modes and attributes which captures the current state.*/
void captureCurrentState(StateSet& stateset) const;
/** reset the state object to an empty stack.*/
void reset();
/** apply an OpenGL mode if required. */
inline const bool applyMode(const StateAttribute::GLMode mode,const bool enabled)
{
return applyMode(mode,enabled,_modeMap[mode]);
}
/** apply an attribute if required. */
inline const bool applyAttribute(const StateAttribute* attribute)
{
return applyAttribute(attribute,_attributeMap[attribute->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<const StateAttribute*,StateAttribute::OverrideValue> AttributePair;
typedef std::vector<AttributePair> AttributeVec;
typedef std::vector<StateAttribute::GLModeValue> ValueVec;
private:
unsigned int _contextID;
ref_ptr<FrameStamp> _frameStamp;
ref_ptr<const Matrix> _identity;
ref_ptr<const Matrix> _projection;
ref_ptr<const Matrix> _modelView;
ref_ptr<DisplaySettings> _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<StateAttribute> 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<StateAttribute*>(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<StateAttribute::GLMode,ModeStack> ModeMap;
typedef std::map<StateAttribute::Type,AttributeStack> AttributeMap;
typedef std::vector<ref_ptr<const StateSet> > StateSetStack;
typedef std::vector<ref_ptr<const Matrix> > MatrixStack;
ModeMap _modeMap;
AttributeMap _attributeMap;
StateSetStack _drawStateStack;
};
}
#endif