2001-10-04 23:12:57 +08:00
|
|
|
//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.
|
|
|
|
|
2001-01-11 00:32:10 +08:00
|
|
|
#ifndef OSG_STATE
|
|
|
|
#define OSG_STATE 1
|
|
|
|
|
|
|
|
#include <osg/Export>
|
2001-09-20 05:08:56 +08:00
|
|
|
#include <osg/StateSet>
|
|
|
|
#include <osg/Matrix>
|
|
|
|
|
2001-09-22 10:42:08 +08:00
|
|
|
#include <osg/FrameStamp>
|
|
|
|
#include <osg/Camera>
|
|
|
|
|
2001-09-20 05:08:56 +08:00
|
|
|
#include <vector>
|
|
|
|
#include <map>
|
2001-01-11 00:32:10 +08:00
|
|
|
|
|
|
|
namespace osg {
|
|
|
|
|
2001-09-20 05:08:56 +08:00
|
|
|
/** 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.
|
2001-10-01 19:15:55 +08:00
|
|
|
* Lazy state updating is used to minimize state changes.
|
2001-09-20 05:08:56 +08:00
|
|
|
*/
|
|
|
|
class SG_EXPORT State : public Referenced
|
2001-01-11 00:32:10 +08:00
|
|
|
{
|
|
|
|
public :
|
2001-09-20 05:08:56 +08:00
|
|
|
|
|
|
|
State();
|
|
|
|
|
|
|
|
virtual ~State();
|
|
|
|
|
|
|
|
/** push stateset onto state stack.*/
|
|
|
|
void pushStateSet(const StateSet* dstate);
|
|
|
|
|
|
|
|
/** pop drawstate off state stack.*/
|
|
|
|
void popStateSet();
|
|
|
|
|
|
|
|
/** reset the state object to an empty stack.*/
|
|
|
|
void reset();
|
|
|
|
|
|
|
|
|
|
|
|
/** apply an OpenGL mode if required. */
|
|
|
|
inline const bool apply_mode(const StateAttribute::GLMode mode,const bool enabled)
|
|
|
|
{
|
|
|
|
return apply_mode(mode,enabled,_modeMap[mode]);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/** apply an attribute if required. */
|
|
|
|
inline const bool apply_attribute(const StateAttribute* attribute)
|
|
|
|
{
|
|
|
|
return apply_attribute(attribute,_attributeMap[attribute->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.
|
2001-10-01 19:15:55 +08:00
|
|
|
Note, it is the application developers responsibility to
|
2001-09-20 05:08:56 +08:00
|
|
|
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; }
|
|
|
|
|
|
|
|
|
2001-09-22 10:42:08 +08:00
|
|
|
/** 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(); }
|
|
|
|
|
2001-09-20 05:08:56 +08:00
|
|
|
|
2001-09-22 10:42:08 +08:00
|
|
|
/** 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; }
|
2001-09-20 05:08:56 +08:00
|
|
|
|
2001-09-22 10:42:08 +08:00
|
|
|
/** Get the camera */
|
|
|
|
inline const Camera* getCamera() const { return _camera.get(); }
|
2001-09-20 05:08:56 +08:00
|
|
|
|
|
|
|
private:
|
|
|
|
|
2001-09-22 10:42:08 +08:00
|
|
|
unsigned int _contextID;
|
|
|
|
ref_ptr<FrameStamp> _frameStamp;
|
|
|
|
ref_ptr<Camera> _camera;
|
2001-09-20 05:08:56 +08:00
|
|
|
|
|
|
|
typedef std::vector<StateAttribute::GLModeValue> ValueVec;
|
|
|
|
|
|
|
|
struct ModeStack
|
|
|
|
{
|
|
|
|
ModeStack()
|
|
|
|
{
|
|
|
|
changed = false;
|
|
|
|
last_applied_value = false;
|
2001-10-15 22:07:54 +08:00
|
|
|
global_default_value = false;
|
2001-09-20 05:08:56 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
bool changed;
|
|
|
|
bool last_applied_value;
|
2001-10-15 22:07:54 +08:00
|
|
|
bool global_default_value;
|
2001-09-20 05:08:56 +08:00
|
|
|
ValueVec valueVec;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
typedef std::pair<const StateAttribute*,StateAttribute::OverrideValue> AttributePair;
|
|
|
|
typedef std::vector<AttributePair> AttributeVec;
|
|
|
|
|
|
|
|
struct AttributeStack
|
|
|
|
{
|
|
|
|
AttributeStack()
|
|
|
|
{
|
|
|
|
changed = false;
|
|
|
|
last_applied_attribute = 0L;
|
2001-10-15 22:07:54 +08:00
|
|
|
global_default_attribute = 0L;
|
2001-09-20 05:08:56 +08:00
|
|
|
}
|
|
|
|
|
2001-10-15 22:07:54 +08:00
|
|
|
/** apply an attribute if required, passing in attribute and appropriate attribute stack */
|
2001-09-20 05:08:56 +08:00
|
|
|
bool changed;
|
|
|
|
const StateAttribute* last_applied_attribute;
|
2001-10-15 22:29:40 +08:00
|
|
|
ref_ptr<StateAttribute> global_default_attribute;
|
2001-09-20 05:08:56 +08:00
|
|
|
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)
|
|
|
|
{
|
2001-10-15 22:29:40 +08:00
|
|
|
if (!as.global_default_attribute.valid()) as.global_default_attribute = dynamic_cast<StateAttribute*>(attribute->clone());
|
2001-10-15 22:07:54 +08:00
|
|
|
|
2001-09-20 05:08:56 +08:00
|
|
|
as.last_applied_attribute = attribute;
|
|
|
|
attribute->apply(*this);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2001-10-15 22:07:54 +08:00
|
|
|
inline const bool apply_global_default_attribute(AttributeStack& as)
|
|
|
|
{
|
2001-10-15 22:29:40 +08:00
|
|
|
if (as.last_applied_attribute != as.global_default_attribute.get())
|
2001-10-15 22:07:54 +08:00
|
|
|
{
|
2001-10-15 22:29:40 +08:00
|
|
|
as.last_applied_attribute = as.global_default_attribute.get();
|
|
|
|
if (as.global_default_attribute.valid()) as.global_default_attribute->apply(*this);
|
2001-10-15 22:07:54 +08:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2001-09-20 05:08:56 +08:00
|
|
|
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;
|
2001-09-22 10:42:08 +08:00
|
|
|
StateSetStack _drawStateStack;
|
|
|
|
|
2001-01-11 00:32:10 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
#endif
|