]> git.mxchange.org Git - simgear.git/commitdiff
Move Texture unit builder into TexBuilder.cxx
authorTim Moore <timoore@redhat.com>
Fri, 16 Oct 2009 10:55:44 +0000 (12:55 +0200)
committerTim Moore <timoore@redhat.com>
Fri, 13 Nov 2009 21:41:11 +0000 (22:41 +0100)
Do the refactoring necessary to make that work.

simgear/scene/material/Effect.cxx
simgear/scene/material/EffectBuilder.cxx
simgear/scene/material/EffectBuilder.hxx
simgear/scene/material/TextureBuilder.cxx
simgear/scene/material/TextureBuilder.hxx

index a94267fc6439d9e3071cb66ed0bec874be02a10f..0ec20275611edb7a59e3ab09b3fe1c8d669252cd 100644 (file)
@@ -31,7 +31,6 @@
 #include <utility>
 
 #include <boost/foreach.hpp>
-#include <boost/lexical_cast.hpp>
 #include <boost/tuple/tuple.hpp>
 #include <boost/tuple/tuple_comparison.hpp>
 
@@ -134,27 +133,6 @@ Effect::~Effect()
 {
 }
 
-class PassAttributeBuilder : public Referenced
-{
-public:
-    virtual void buildAttribute(Effect* effect, Pass* pass,
-                                const SGPropertyNode* prop,
-                                const osgDB::ReaderWriter::Options* options)
-    = 0;
-};
-
-typedef map<const string, ref_ptr<PassAttributeBuilder> > PassAttrMap;
-PassAttrMap passAttrMap;
-
-template<typename T>
-struct InstallAttributeBuilder
-{
-    InstallAttributeBuilder(const string& name)
-    {
-        passAttrMap.insert(make_pair(name, new T));
-    }
-};
-
 void buildPass(Effect* effect, Technique* tniq, const SGPropertyNode* prop,
                const osgDB::ReaderWriter::Options* options)
 {
@@ -162,9 +140,10 @@ void buildPass(Effect* effect, Technique* tniq, const SGPropertyNode* prop,
     tniq->passes.push_back(pass);
     for (int i = 0; i < prop->nChildren(); ++i) {
         const SGPropertyNode* attrProp = prop->getChild(i);
-        PassAttrMap::iterator itr = passAttrMap.find(attrProp->getName());
-        if (itr != passAttrMap.end())
-            itr->second->buildAttribute(effect, pass, attrProp, options);
+        PassAttributeBuilder* builder
+            = PassAttributeBuilder::find(attrProp->getNameString());
+        if (builder)
+            builder->buildAttribute(effect, pass, attrProp, options);
         else
             SG_LOG(SG_INPUT, SG_ALERT,
                    "skipping unknown pass attribute " << attrProp->getName());
@@ -197,19 +176,6 @@ osg::Vec4f getColor(const SGPropertyNode* prop)
     }
 }
 
-// The description of an attribute may exist in a pass' XML, but a
-// derived effect might want to disable the attribute altogether. So,
-// some attributes have an "active" property; if it exists and is
-// false, the OSG attribute is not built at all. This is different
-// from any OSG mode settings that might be around.
-
-bool isAttributeActive(Effect* effect, const SGPropertyNode* prop)
-{
-    const SGPropertyNode* activeProp
-        = getEffectPropertyChild(effect, prop, "active");
-    return !activeProp || activeProp->getValue<bool>();
-}
-
 struct LightingBuilder : public PassAttributeBuilder
 {
     void buildAttribute(Effect* effect, Pass* pass, const SGPropertyNode* prop,
@@ -566,89 +532,6 @@ struct AlphaTestBuilder : public PassAttributeBuilder
 
 InstallAttributeBuilder<AlphaTestBuilder> installAlphaTest("alpha-test");
 
-EffectNameValue<TexEnv::Mode> texEnvModesInit[] =
-{
-    {"add", TexEnv::ADD},
-    {"blend", TexEnv::BLEND},
-    {"decal", TexEnv::DECAL},
-    {"modulate", TexEnv::MODULATE},
-    {"replace", TexEnv::REPLACE}
-};
-EffectPropertyMap<TexEnv::Mode> texEnvModes(texEnvModesInit);
-
-TexEnv* buildTexEnv(Effect* effect, const SGPropertyNode* prop)
-{
-    const SGPropertyNode* modeProp = getEffectPropertyChild(effect, prop,
-                                                            "mode");
-    const SGPropertyNode* colorProp = getEffectPropertyChild(effect, prop,
-                                                             "color");
-    if (!modeProp)
-        return 0;
-    TexEnv::Mode mode = TexEnv::MODULATE;
-    findAttr(texEnvModes, modeProp, mode);
-    if (mode == TexEnv::MODULATE) {
-        return StateAttributeFactory::instance()->getStandardTexEnv();
-    }
-    TexEnv* env = new TexEnv(mode);
-    if (colorProp)
-        env->setColor(toOsg(colorProp->getValue<SGVec4d>()));
-    return env;
- }
-
-
-struct TextureUnitBuilder : PassAttributeBuilder
-{
-    void buildAttribute(Effect* effect, Pass* pass, const SGPropertyNode* prop,
-                        const osgDB::ReaderWriter::Options* options);
-};
-
-void TextureUnitBuilder::buildAttribute(Effect* effect, Pass* pass,
-                                        const SGPropertyNode* prop,
-                                        const osgDB::ReaderWriter::Options* options)
-{
-    if (!isAttributeActive(effect, prop))
-        return;
-    // Decode the texture unit
-    int unit = 0;
-    const SGPropertyNode* pUnit = prop->getChild("unit");
-    if (pUnit) {
-        unit = pUnit->getValue<int>();
-    } else {
-        const SGPropertyNode* pName = prop->getChild("name");
-        if (pName)
-            try {
-                unit = boost::lexical_cast<int>(pName->getStringValue());
-            } catch (boost::bad_lexical_cast& lex) {
-                SG_LOG(SG_INPUT, SG_ALERT, "can't decode name as texture unit "
-                       << lex.what());
-            }
-    }
-    const SGPropertyNode* pType = getEffectPropertyChild(effect, prop, "type");
-    string type;
-    if (!pType)
-        type = "2d";
-    else
-        type = pType->getStringValue();
-    Texture* texture = 0;
-    try {
-        texture = TextureBuilder::buildFromType(effect, type, prop,
-                                                options);
-    }
-    catch (BuilderException& e) {
-        SG_LOG(SG_INPUT, SG_ALERT, "No image file for texture, using white ");
-        texture = StateAttributeFactory::instance()->getWhiteTexture();
-    }
-    pass->setTextureAttributeAndModes(unit, texture);
-    const SGPropertyNode* envProp = prop->getChild("environment");
-    if (envProp) {
-        TexEnv* env = buildTexEnv(effect, envProp);
-        if (env)
-            pass->setTextureAttributeAndModes(unit, env);
-    }
-}
-
-
-
 InstallAttributeBuilder<TextureUnitBuilder> textureUnitBuilder("texture-unit");
 
 typedef map<string, ref_ptr<Program> > ProgramMap;
index 32168a9c9562b46593175c7b245171ec24233213..a485f110ed27261bba4d9498960c4070f647caa4 100644 (file)
@@ -56,5 +56,14 @@ BuilderException::BuilderException(const std::string& message,
 
 BuilderException::~BuilderException() throw()
 {
+
 }
+
+bool isAttributeActive(Effect* effect, const SGPropertyNode* prop)
+{
+    const SGPropertyNode* activeProp
+        = getEffectPropertyChild(effect, prop, "active");
+    return !activeProp || activeProp->getValue<bool>();
+}
+
 }
index e263f6efb2fb01f3a8188fc56d0a0ae452370935..4b2ebad3eb029791deceb23f1f43b672e3bd31ca 100644 (file)
@@ -40,6 +40,7 @@
 namespace simgear
 {
 class Effect;
+class Pass;
 
 /**
  * Builder that returns an object, probably an OSG object.
@@ -212,5 +213,49 @@ public:
     BuilderException(const std::string& message, const std::string& = "");
     virtual ~BuilderException() throw();
 };
+
+class PassAttributeBuilder : public SGReferenced
+{
+protected:
+    typedef std::map<const std::string, SGSharedPtr<PassAttributeBuilder> >
+    PassAttrMap;
+
+    struct PassAttrMapSingleton : public simgear::Singleton<PassAttrMapSingleton>
+    {
+        PassAttrMap passAttrMap;
+    };
+public:
+    virtual void buildAttribute(Effect* effect, Pass* pass,
+                                const SGPropertyNode* prop,
+                                const osgDB::ReaderWriter::Options* options)
+    = 0;
+    static PassAttributeBuilder* find(const std::string& str)
+    {
+        PassAttrMap::iterator itr
+            = PassAttrMapSingleton::instance()->passAttrMap.find(str);
+        if (itr == PassAttrMapSingleton::instance()->passAttrMap.end())
+            return 0;
+        else
+            return itr->second.ptr();
+    }
+    template<typename T> friend class InstallAttributeBuilder;
+};
+
+template<typename T>
+struct InstallAttributeBuilder
+{
+    InstallAttributeBuilder(const string& name)
+    {
+        PassAttributeBuilder::PassAttrMapSingleton::instance()
+            ->passAttrMap.insert(make_pair(name, new T));
+    }
+};
+
+// The description of an attribute may exist in a pass' XML, but a
+// derived effect might want to disable the attribute altogether. So,
+// some attributes have an "active" property; if it exists and is
+// false, the OSG attribute is not built at all. This is different
+// from any OSG mode settings that might be around.
+bool isAttributeActive(Effect* effect, const SGPropertyNode* prop);
 }
 #endif
index 2623c4a73a2b76458b9e2db98fae420fa48dacc4..0db435de0835e04e4d491d7c2797ca9d49c424ce 100644 (file)
 
 #include "TextureBuilder.hxx"
 
+#include "Pass.hxx"
+
+#include <osg/TexEnv>
+#include <osg/TexEnvCombine>
 #include <osg/Texture1D>
 #include <osg/Texture2D>
 #include <osg/Texture3D>
 #include <osg/TextureRectangle>
 #include <osgDB/FileUtils>
 
+#include <boost/lexical_cast.hpp>
 #include <boost/tuple/tuple.hpp>
 #include <boost/tuple/tuple_comparison.hpp>
 
@@ -56,6 +61,84 @@ typedef boost::tuple<string, Texture::FilterMode, Texture::FilterMode,
                      Texture::WrapMode, Texture::WrapMode, Texture::WrapMode,
                      string> TexTuple;
 
+EffectNameValue<TexEnv::Mode> texEnvModesInit[] =
+{
+    {"add", TexEnv::ADD},
+    {"blend", TexEnv::BLEND},
+    {"decal", TexEnv::DECAL},
+    {"modulate", TexEnv::MODULATE},
+    {"replace", TexEnv::REPLACE}
+};
+EffectPropertyMap<TexEnv::Mode> texEnvModes(texEnvModesInit);
+
+TexEnv* buildTexEnv(Effect* effect, const SGPropertyNode* prop)
+{
+    const SGPropertyNode* modeProp = getEffectPropertyChild(effect, prop,
+                                                            "mode");
+    const SGPropertyNode* colorProp = getEffectPropertyChild(effect, prop,
+                                                             "color");
+    if (!modeProp)
+        return 0;
+    TexEnv::Mode mode = TexEnv::MODULATE;
+    findAttr(texEnvModes, modeProp, mode);
+    if (mode == TexEnv::MODULATE) {
+        return StateAttributeFactory::instance()->getStandardTexEnv();
+    }
+    TexEnv* env = new TexEnv(mode);
+    if (colorProp)
+        env->setColor(toOsg(colorProp->getValue<SGVec4d>()));
+    return env;
+ }
+
+
+void TextureUnitBuilder::buildAttribute(Effect* effect, Pass* pass,
+                                        const SGPropertyNode* prop,
+                                        const osgDB::ReaderWriter::Options* options)
+{
+    if (!isAttributeActive(effect, prop))
+        return;
+    // Decode the texture unit
+    int unit = 0;
+    const SGPropertyNode* pUnit = prop->getChild("unit");
+    if (pUnit) {
+        unit = pUnit->getValue<int>();
+    } else {
+        const SGPropertyNode* pName = prop->getChild("name");
+        if (pName)
+            try {
+                unit = boost::lexical_cast<int>(pName->getStringValue());
+            } catch (boost::bad_lexical_cast& lex) {
+                SG_LOG(SG_INPUT, SG_ALERT, "can't decode name as texture unit "
+                       << lex.what());
+            }
+    }
+    const SGPropertyNode* pType = getEffectPropertyChild(effect, prop, "type");
+    string type;
+    if (!pType)
+        type = "2d";
+    else
+        type = pType->getStringValue();
+    Texture* texture = 0;
+    try {
+        texture = TextureBuilder::buildFromType(effect, type, prop,
+                                                options);
+    }
+    catch (BuilderException& e) {
+        SG_LOG(SG_INPUT, SG_ALERT, "No image file for texture, using white ");
+        texture = StateAttributeFactory::instance()->getWhiteTexture();
+    }
+    pass->setTextureAttributeAndModes(unit, texture);
+    const SGPropertyNode* envProp = prop->getChild("environment");
+    if (envProp) {
+        TexEnv* env = buildTexEnv(effect, envProp);
+        if (env)
+            pass->setTextureAttributeAndModes(unit, env);
+    }
+}
+
+// InstallAttributeBuilder call is in Effect.cxx to force this file to
+// be linked in.
+
 namespace
 {
 EffectNameValue<Texture::FilterMode> filterModesInit[] =
index 395ca38260b8fb9a4bb4aa7c8cb2c1400061324d..ca6c54945f3eb902a88eeb5f10e14e1b1c5fd066 100644 (file)
@@ -32,6 +32,13 @@ public:
                                        const osgDB::ReaderWriter::Options* options);
 };
 
+struct TextureUnitBuilder : public PassAttributeBuilder
+{
+    void buildAttribute(Effect* effect, Pass* pass, const SGPropertyNode* prop,
+                        const osgDB::ReaderWriter::Options* options);
+};
+
+
 bool makeTextureParameters(SGPropertyNode* paramRoot, const osg::StateSet* ss);
 }
 #endif