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-12-22 06:48:19 +08:00
|
|
|
#include <osg/DisplaySettings>
|
2001-09-22 10:42:08 +08:00
|
|
|
|
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();
|
|
|
|
|
2001-10-23 06:02:47 +08:00
|
|
|
/** copy the modes and attributes which captures the current state.*/
|
|
|
|
void captureCurrentState(StateSet& stateset) const;
|
|
|
|
|
2001-09-20 05:08:56 +08:00
|
|
|
/** 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
|
|
|
|
2001-12-22 06:48:19 +08:00
|
|
|
/** Set the DisplaySettings. Note, nothing is applied, the visual settings are just used
|
2001-12-19 08:38:23 +08:00
|
|
|
* used in the State object to pass the current visual settings to Drawables
|
|
|
|
* during rendering. */
|
2001-12-22 06:48:19 +08:00
|
|
|
inline void setDisplaySettings(DisplaySettings* vs) { _displaySettings = vs; }
|
2001-12-19 08:38:23 +08:00
|
|
|
|
2001-12-22 06:48:19 +08:00
|
|
|
/** Get the DisplaySettings */
|
|
|
|
inline const DisplaySettings* getDisplaySettings() const { return _displaySettings.get(); }
|
2001-12-19 08:38:23 +08:00
|
|
|
|
2001-09-20 05:08:56 +08:00
|
|
|
private:
|
|
|
|
|
2001-12-19 08:38:23 +08:00
|
|
|
unsigned int _contextID;
|
|
|
|
ref_ptr<FrameStamp> _frameStamp;
|
|
|
|
ref_ptr<Camera> _camera;
|
2001-12-22 06:48:19 +08:00
|
|
|
ref_ptr<DisplaySettings> _displaySettings;
|
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)
|
|
|
|
{
|
Added support for shallow and deep copy of nodes, drawables and state, via a
copy constructor which takes an optional Cloner object, and the old
osg::Object::clone() has changed so that it now requires a Cloner as paramter.
This is passed on to the copy constructor to help control the shallow vs
deep copying. The old functionality of clone() which was clone of type has
been renamed to cloneType().
Updated all of the OSG to work with these new conventions, implemention all
the required copy constructors etc. A couple of areas will do shallow
copies by design, a couple of other still need to be updated to do either
shallow or deep.
Neither of the shallow or deep copy operations have been tested yet, only
the old functionality of the OSG has been checked so far, such running the
viewer on various demo datasets.
Also fixed a problem in osg::Optimize::RemoveRendundentNodesVisitor which
was not checking that Group didn't have have any attached StateSet's, Callbacks
or UserData. These checks have now been added, which fixes a bug which was
revealled by the new osgscribe demo, this related to removal of group acting
as state decorator.
method
2002-01-29 05:17:01 +08:00
|
|
|
if (!as.global_default_attribute.valid()) as.global_default_attribute = dynamic_cast<StateAttribute*>(attribute->cloneType());
|
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
|
|
|
};
|
|
|
|
|
2002-02-03 20:33:41 +08:00
|
|
|
}
|
2001-01-11 00:32:10 +08:00
|
|
|
|
|
|
|
#endif
|