getStateAttribute utility function

This provides a concise, typesafe way to get attributes from osg::StateSet.

Also, blew away BackRefInserter.
This commit is contained in:
Tim Moore
2009-09-08 12:53:33 +02:00
parent 23d0601d82
commit e7e81c6639
2 changed files with 275 additions and 59 deletions

View File

@@ -881,9 +881,7 @@ bool makeParametersFromStateSet(SGPropertyNode* paramRoot, const StateSet* ss)
SGPropertyNode* matNode = paramRoot->getChild("material", 0, true);
Vec4f ambVal, difVal, specVal, emisVal;
float shininess = 0.0f;
const Material* mat
= static_cast<const Material*>(ss->getAttribute(StateAttribute
::MATERIAL));
const Material* mat = getStateAttribute<Material>(ss);
if (mat) {
ambVal = mat->getAmbient(Material::FRONT_AND_BACK);
difVal = mat->getDiffuse(Material::FRONT_AND_BACK);
@@ -897,9 +895,7 @@ bool makeParametersFromStateSet(SGPropertyNode* paramRoot, const StateSet* ss)
matNode->getChild("emissive", 0, true)->setValue(toVec4d(toSG(emisVal)));
matNode->getChild("shininess", 0, true)->setValue(shininess);
matNode->getChild("color-mode", 0, true)->setStringValue("diffuse");
const ShadeModel* sm
= static_cast<const ShadeModel*>(ss->getAttribute(StateAttribute
::SHADEMODEL));
const ShadeModel* sm = getStateAttribute<ShadeModel>(ss);
string shadeModelString("smooth");
if (sm) {
ShadeModel::Mode smMode = sm->getMode();
@@ -909,9 +905,7 @@ bool makeParametersFromStateSet(SGPropertyNode* paramRoot, const StateSet* ss)
paramRoot->getChild("shade-model", 0, true)
->setStringValue(shadeModelString);
string cullFaceString("off");
const CullFace* cullFace
= static_cast<const CullFace*>(ss->getAttribute(StateAttribute
::CULLFACE));
const CullFace* cullFace = getStateAttribute<CullFace>(ss);
if (cullFace) {
switch (cullFace->getMode()) {
case CullFace::FRONT:

View File

@@ -20,8 +20,9 @@
#ifndef SIMGEAR_OSGUTILS_HXX
#define SIMGEAR_OSGUTILS_HXX 1
#include <boost/iterator/iterator_facade.hpp>
#include <osg/CopyOp>
#include <osg/StateAttribute>
#include <osg/StateSet>
namespace simgear
{
@@ -99,59 +100,280 @@ T* clone_ref(const osg::ref_ptr<T>& object,
return static_cast<T*>(object->clone(copyop));
}
template<typename Container>
class BackRefInsertIterator
: public boost::iterator_facade<BackRefInsertIterator<Container>,
BackRefInsertIterator<Container>,
boost::incrementable_traversal_tag
>
}
namespace osg
{
public:
typedef typename Container::value_type::element_type* PtrType;
BackRefInsertIterator() : _container(0) {}
explicit BackRefInsertIterator(Container& container)
: _container(&container)
{
}
class AlphaFunc;
class BlendColor;
class BlendEquation;
class BlendFunc;
class ClampColor;
class ColorMask;
class ColorMatrix;
class CullFace;
class Depth;
class Fog;
class FragmentProgram;
class FrontFace;
class LightModel;
class LineStipple;
class LineWidth;
class LogicOp;
class Material;
class Multisample;
class Point;
class PointSprite;
class PolygonMode;
class PolygonOffset;
class PolygonStipple;
class Program;
class Scissor;
class ShadeModel;
class Stencil;
class StencilTwoSided;
class TexEnv;
class TexEnvCombine;
class TexEnvFilter;
class TexGen;
class TexMat;
class Texture1D;
class Texture2D;
class Texture2DArray;
class Texture3D;
class TextureCubeMap;
class TextureRectangle;
class VertexProgram;
class Viewport;
}
BackRefInsertIterator&
operator=(const PtrType ptr)
{
_container->push_back(ptr);
return *this;
}
private:
friend class boost::iterator_core_access;
namespace simgear
{
namespace osgutils
{
using namespace osg;
void increment()
{
}
BackRefInsertIterator& dereference()
{
return *this;
}
BackRefInsertIterator& dereference() const
{
return const_cast<BackRefInsertIterator&>(*this);
}
bool equal(const BackRefInsertIterator& rhs)
{
return _container == rhs._container;
}
Container* _container;
template<StateAttribute::Type T>
struct TypeHolder
{
static const StateAttribute::Type type = T;
};
template<typename AT> struct AttributeType;
template<typename AT> struct TexAttributeType;
template<>
struct AttributeType<AlphaFunc>
: public TypeHolder<StateAttribute::ALPHAFUNC>
{};
template<>
struct AttributeType<BlendColor>
: public TypeHolder<StateAttribute::BLENDCOLOR>
{};
template<>
struct AttributeType<BlendEquation>
: public TypeHolder<StateAttribute::BLENDEQUATION>
{};
template<>
struct AttributeType<BlendFunc>
: public TypeHolder<StateAttribute::BLENDFUNC>
{};
template<>
struct AttributeType<ClampColor>
: public TypeHolder<StateAttribute::CLAMPCOLOR>
{};
template<>
struct AttributeType<ColorMask>
: public TypeHolder<StateAttribute::COLORMASK>
{};
template<>
struct AttributeType<ColorMatrix>
: public TypeHolder<StateAttribute::COLORMATRIX>
{};
template<>
struct AttributeType<CullFace>
: public TypeHolder<StateAttribute::CULLFACE>
{};
template<>
struct AttributeType<osg::Depth> // Conflicts with Xlib
: public TypeHolder<StateAttribute::DEPTH>
{};
template<>
struct AttributeType<Fog>
: public TypeHolder<StateAttribute::FOG>
{};
template<>
struct AttributeType<FragmentProgram>
: public TypeHolder<StateAttribute::FRAGMENTPROGRAM>
{};
template<>
struct AttributeType<FrontFace>
: public TypeHolder<StateAttribute::FRONTFACE>
{};
template<>
struct AttributeType<LightModel>
: public TypeHolder<StateAttribute::LIGHTMODEL>
{};
template<>
struct AttributeType<LineStipple>
: public TypeHolder<StateAttribute::LINESTIPPLE>
{};
template<>
struct AttributeType<LineWidth>
: public TypeHolder<StateAttribute::LINEWIDTH>
{};
template<>
struct AttributeType<LogicOp>
: public TypeHolder<StateAttribute::LOGICOP>
{};
template<>
struct AttributeType<Material>
: public TypeHolder<StateAttribute::MATERIAL>
{};
template<>
struct AttributeType<Multisample>
: public TypeHolder<StateAttribute::MULTISAMPLE>
{};
template<>
struct AttributeType<Point>
: public TypeHolder<StateAttribute::POINT>
{};
template<>
struct TexAttributeType<PointSprite>
: public TypeHolder<StateAttribute::POINTSPRITE>
{};
template<>
struct AttributeType<PolygonMode>
: public TypeHolder<StateAttribute::POLYGONMODE>
{};
template<>
struct AttributeType<PolygonOffset>
: public TypeHolder<StateAttribute::POLYGONOFFSET>
{};
template<>
struct AttributeType<PolygonStipple>
: public TypeHolder<StateAttribute::POLYGONSTIPPLE>
{};
template<>
struct AttributeType<Program>
: public TypeHolder<StateAttribute::PROGRAM>
{};
template<>
struct AttributeType<Scissor>
: public TypeHolder<StateAttribute::SCISSOR>
{};
template<>
struct AttributeType<ShadeModel>
: public TypeHolder<StateAttribute::SHADEMODEL>
{};
template<>
struct AttributeType<Stencil>
: public TypeHolder<StateAttribute::STENCIL>
{};
template<>
struct AttributeType<StencilTwoSided>
: public TypeHolder<StateAttribute::STENCIL>
{};
// TexEnvCombine is not a subclass of TexEnv, so we can't do a
// typesafe access of the attribute.
#if 0
template<>
struct TexAttributeType<TexEnv>
: public TypeHolder<StateAttribute::TEXENV>
{};
template<>
struct TexAttributeType<TexEnvCombine>
: public TypeHolder<StateAttribute::TEXENV>
{};
#endif
template<>
struct TexAttributeType<TexEnvFilter>
: public TypeHolder<StateAttribute::TEXENVFILTER>
{};
template<>
struct TexAttributeType<TexGen>
: public TypeHolder<StateAttribute::TEXGEN>
{};
template<>
struct TexAttributeType<TexMat>
: public TypeHolder<StateAttribute::TEXMAT>
{};
template<>
struct TexAttributeType<Texture>
: public TypeHolder<StateAttribute::TEXTURE>
{};
template<>
struct AttributeType<VertexProgram>
: public TypeHolder<StateAttribute::VERTEXPROGRAM>
{};
template<>
struct AttributeType<Viewport>
: public TypeHolder<StateAttribute::VIEWPORT>
{};
} // namespace osgutils
template<typename AT>
inline AT* getStateAttribute(osg::StateSet* ss)
{
return static_cast<AT*>(ss->getAttribute(osgutils::AttributeType<AT>::type));
}
template<typename AT>
inline const AT* getStateAttribute(const osg::StateSet* ss)
{
return static_cast<const AT*>(ss->getAttribute(osgutils::AttributeType<AT>::type));
}
template<typename AT>
inline AT* getStateAttribute(unsigned int unit, osg::StateSet* ss)
{
return static_cast<AT*>(ss->getTextureAttribute(unit, osgutils::TexAttributeType<AT>
::type));
}
template<typename AT>
inline const AT* getStateAttribute(unsigned int unit, const osg::StateSet* ss)
{
return static_cast<const AT*>(ss->getTextureAttribute(unit,
osgutils::TexAttributeType<AT>
::type));
}
} // namespace simgear
template<typename Container>
inline BackRefInsertIterator<Container>
backRefInsertIterator(Container& container)
{
return BackRefInsertIterator<Container>(container);
}
}
#endif