From 46bed67cceb0c80d674729678981dfaf306aa5b8 Mon Sep 17 00:00:00 2001 From: Torsten Dreyer Date: Fri, 5 Sep 2014 11:16:28 +0200 Subject: [PATCH] first stab at UniformFactory --- simgear/scene/material/Effect.cxx | 132 +++++++++++++++-------- simgear/scene/material/EffectBuilder.hxx | 1 + 2 files changed, 87 insertions(+), 46 deletions(-) diff --git a/simgear/scene/material/Effect.cxx b/simgear/scene/material/Effect.cxx index 7d961af4..6fbc55bd 100644 --- a/simgear/scene/material/Effect.cxx +++ b/simgear/scene/material/Effect.cxx @@ -87,6 +87,85 @@ using namespace osgUtil; using namespace effect; +class UniformFactoryImpl { +public: + ref_ptr getUniform( Effect * effect, + const string & name, + Uniform::Type uniformType, + SGConstPropertyNode_ptr valProp, + const SGReaderWriterOptions* options ); +private: + // Default names for vector property components + static const char* vec3Names[]; + static const char* vec4Names[]; + + std::map > uniformCache; +}; + +const char* UniformFactoryImpl::vec3Names[] = {"x", "y", "z"}; +const char* UniformFactoryImpl::vec4Names[] = {"x", "y", "z", "w"}; + +ref_ptr UniformFactoryImpl::getUniform( Effect * effect, + const string & name, + Uniform::Type uniformType, + SGConstPropertyNode_ptr valProp, + const SGReaderWriterOptions* options ) +{ + + ref_ptr uniform = uniformCache[name]; + if( !uniform.valid() ) { + SG_LOG(SG_ALL,SG_ALERT,"new uniform '" << name << "'"); + uniformCache[name] = uniform = new Uniform; + } else { + SG_LOG(SG_ALL,SG_ALERT,"reusing uniform '" << name << "'"); + return uniform; + } + + uniform->setName(name); + uniform->setType(uniformType); + switch (uniformType) { + case Uniform::BOOL: + initFromParameters(effect, valProp, uniform.get(), + static_cast(&Uniform::set), + options); + break; + case Uniform::FLOAT: + initFromParameters(effect, valProp, uniform.get(), + static_cast(&Uniform::set), + options); + break; + case Uniform::FLOAT_VEC3: + initFromParameters(effect, valProp, uniform.get(), + static_cast(&Uniform::set), + vec3Names, options); + break; + case Uniform::FLOAT_VEC4: + initFromParameters(effect, valProp, uniform.get(), + static_cast(&Uniform::set), + vec4Names, options); + break; + case Uniform::INT: + case Uniform::SAMPLER_1D: + case Uniform::SAMPLER_2D: + case Uniform::SAMPLER_3D: + case Uniform::SAMPLER_1D_SHADOW: + case Uniform::SAMPLER_2D_SHADOW: + case Uniform::SAMPLER_CUBE: + initFromParameters(effect, valProp, uniform.get(), + static_cast(&Uniform::set), + options); + break; + default: // avoid compiler warning + break; + } + + return uniform; +} + + +typedef Singleton UniformFactory; + + Effect::Effect() : _cache(0), _isRealized(false) { @@ -173,10 +252,6 @@ void buildPass(Effect* effect, Technique* tniq, const SGPropertyNode* prop, } } -// Default names for vector property components -const char* vec3Names[] = {"x", "y", "z"}; -const char* vec4Names[] = {"x", "y", "z", "w"}; - osg::Vec4f getColor(const SGPropertyNode* prop) { if (prop->nChildren() == 0) { @@ -898,10 +973,10 @@ struct UniformBuilder :public PassAttributeBuilder } if (!isAttributeActive(effect, prop)) return; - const SGPropertyNode* nameProp = prop->getChild("name"); - const SGPropertyNode* typeProp = prop->getChild("type"); - const SGPropertyNode* positionedProp = prop->getChild("positioned"); - const SGPropertyNode* valProp = prop->getChild("value"); + SGConstPropertyNode_ptr nameProp = prop->getChild("name"); + SGConstPropertyNode_ptr typeProp = prop->getChild("type"); + SGConstPropertyNode_ptr positionedProp = prop->getChild("positioned"); + SGConstPropertyNode_ptr valProp = prop->getChild("value"); string name; Uniform::Type uniformType = Uniform::FLOAT; if (nameProp) { @@ -941,44 +1016,9 @@ struct UniformBuilder :public PassAttributeBuilder } else { findAttr(uniformTypes, typeProp, uniformType); } - ref_ptr uniform = new Uniform; - uniform->setName(name); - uniform->setType(uniformType); - switch (uniformType) { - case Uniform::BOOL: - initFromParameters(effect, valProp, uniform.get(), - static_cast(&Uniform::set), - options); - break; - case Uniform::FLOAT: - initFromParameters(effect, valProp, uniform.get(), - static_cast(&Uniform::set), - options); - break; - case Uniform::FLOAT_VEC3: - initFromParameters(effect, valProp, uniform.get(), - static_cast(&Uniform::set), - vec3Names, options); - break; - case Uniform::FLOAT_VEC4: - initFromParameters(effect, valProp, uniform.get(), - static_cast(&Uniform::set), - vec4Names, options); - break; - case Uniform::INT: - case Uniform::SAMPLER_1D: - case Uniform::SAMPLER_2D: - case Uniform::SAMPLER_3D: - case Uniform::SAMPLER_1D_SHADOW: - case Uniform::SAMPLER_2D_SHADOW: - case Uniform::SAMPLER_CUBE: - initFromParameters(effect, valProp, uniform.get(), - static_cast(&Uniform::set), - options); - break; - default: // avoid compiler warning - break; - } + ref_ptr uniform = UniformFactory::instance()-> + getUniform( effect, name, uniformType, valProp, options ); + // optimize common uniforms if (uniformType == Uniform::SAMPLER_2D || uniformType == Uniform::INT) { diff --git a/simgear/scene/material/EffectBuilder.hxx b/simgear/scene/material/EffectBuilder.hxx index a919f10b..3c9c03d1 100644 --- a/simgear/scene/material/EffectBuilder.hxx +++ b/simgear/scene/material/EffectBuilder.hxx @@ -516,6 +516,7 @@ public: } void initOnAddImpl(Effect* effect, SGPropertyNode* propRoot) { + SG_LOG(SG_ALL,SG_ALERT,"Adding change listener to " << *_propName ); SGPropertyNode* listenProp = makeNode(propRoot, *_propName); delete _propName; _propName = 0;