]> git.mxchange.org Git - simgear.git/commitdiff
more effects features
authortimoore <timoore>
Wed, 15 Jul 2009 23:11:44 +0000 (23:11 +0000)
committerTim Moore <timoore@redhat.com>
Thu, 16 Jul 2009 10:09:44 +0000 (12:09 +0200)
Materials can specify an effect.

Add support for PolygonMode and initial support for Uniform.

simgear/scene/material/Effect.cxx
simgear/scene/material/mat.cxx
simgear/scene/material/mat.hxx

index c1db1d73e59a300328f4fa4a0b0b6059847d500a..3969419dac8b87bb6188c493c5ae6dcd098a4198 100644 (file)
@@ -33,6 +33,7 @@
 #include <osg/CullFace>
 #include <osg/Drawable>
 #include <osg/Material>
+#include <osg/PolygonMode>
 #include <osg/Program>
 #include <osg/Referenced>
 #include <osg/RenderInfo>
@@ -40,6 +41,7 @@
 #include <osg/StateSet>
 #include <osg/TexEnv>
 #include <osg/Texture2D>
+#include <osg/Uniform>
 #include <osg/Vec4d>
 #include <osgUtil/CullVisitor>
 #include <osgDB/FileUtils>
@@ -667,7 +669,9 @@ void ShaderProgramBuilder::buildAttribute(Effect* effect, Pass* pass,
                 if (sitr != shaderMap.end()) {
                     program->addShader(sitr->second.get());
                 } else {
-                    string fileName = osgDB::findDataFile(shaderName, options);
+                    string fileName = osgDB::Registry::instance()
+                        ->findDataFile(shaderName, options,
+                                       osgDB::CASE_SENSITIVE);
                     if (!fileName.empty()) {
                         ref_ptr<Shader> shader = new Shader(stype);
                         if (shader->loadShaderSourceFromFile(fileName)) {
@@ -685,6 +689,86 @@ void ShaderProgramBuilder::buildAttribute(Effect* effect, Pass* pass,
     pass->setAttributeAndModes(program);
 }
 
+InstallAttributeBuilder<ShaderProgramBuilder> installShaderProgram("program");
+
+EffectNameValue<Uniform::Type> uniformTypes[] =
+{
+    {"float", Uniform::FLOAT},
+    {"float-vec3", Uniform::FLOAT_VEC3},
+    {"float-vec4", Uniform::FLOAT_VEC4},
+    {"sampler-1d", Uniform::SAMPLER_1D},
+    {"sampler-2d", Uniform::SAMPLER_2D},
+    {"sampler-3d", Uniform::SAMPLER_3D}
+};
+
+struct UniformBuilder :public PassAttributeBuilder
+{
+    void buildAttribute(Effect* effect, Pass* pass, const SGPropertyNode* prop,
+                        const osgDB::ReaderWriter::Options* options)
+    {
+        using namespace simgear::props;
+        const SGPropertyNode* nameProp = prop->getChild("name");
+        const SGPropertyNode* typeProp = prop->getChild("type");
+        const SGPropertyNode* valProp
+            = getEffectPropertyChild(effect, prop, "value");
+        string name;
+        Uniform::Type uniformType = Uniform::FLOAT;
+        if (nameProp) {
+            name = nameProp->getStringValue();
+        } else {
+            SG_LOG(SG_INPUT, SG_ALERT, "No name for uniform property ");
+            return;
+        }
+        if (!valProp) {
+            SG_LOG(SG_INPUT, SG_ALERT, "No value for uniform property "
+                   << name);
+            return;
+        }
+        if (!typeProp) {
+            props::Type propType = valProp->getType();
+            switch (propType) {
+            case FLOAT:
+            case DOUBLE:
+                break;          // default float type;
+            case VEC3D:
+                uniformType = Uniform::FLOAT_VEC3;
+                break;
+            case VEC4D:
+                uniformType = Uniform::FLOAT_VEC4;
+                break;
+            default:
+                SG_LOG(SG_INPUT, SG_ALERT, "Can't deduce type of uniform "
+                       << name);
+                return;
+            }
+        } else {
+            findAttr(uniformTypes, typeProp, uniformType);
+        }
+        ref_ptr<Uniform> uniform = new Uniform;
+        uniform->setName(name);
+        uniform->setType(uniformType);
+        switch (uniformType) {
+        case Uniform::FLOAT:
+            uniform->set(valProp->getValue<float>());
+            break;
+        case Uniform::FLOAT_VEC3:
+            uniform->set(Vec3f(valProp->getValue<SGVec3d>().osg()));
+            break;
+        case Uniform::FLOAT_VEC4:
+            uniform->set(Vec4f(valProp->getValue<SGVec4d>().osg()));
+            break;
+        case Uniform::SAMPLER_1D:
+        case Uniform::SAMPLER_2D:
+        case Uniform::SAMPLER_3D:
+            uniform->set(valProp->getValue<int>());
+            break;
+        }
+        pass->addUniform(uniform.get());
+    }
+};
+
+InstallAttributeBuilder<UniformBuilder> installUniform("uniform");
+
 // Not sure what to do with "name". At one point I wanted to use it to
 // order the passes, but I do support render bin and stuff too...
 
@@ -702,6 +786,38 @@ struct NameBuilder : public PassAttributeBuilder
 
 InstallAttributeBuilder<NameBuilder> installName("name");
 
+EffectNameValue<PolygonMode::Mode> polygonModeModes[] =
+{
+    {"fill", PolygonMode::FILL},
+    {"line", PolygonMode::LINE},
+    {"point", PolygonMode::POINT}
+};
+
+struct PolygonModeBuilder : public PassAttributeBuilder
+{
+    void buildAttribute(Effect* effect, Pass* pass, const SGPropertyNode* prop,
+                        const osgDB::ReaderWriter::Options* options)
+    {
+        const SGPropertyNode* frontProp
+            = getEffectPropertyChild(effect, prop, "front");
+        const SGPropertyNode* backProp
+            = getEffectPropertyChild(effect, prop, "back");
+        ref_ptr<PolygonMode> pmode = new PolygonMode;
+        PolygonMode::Mode frontMode = PolygonMode::FILL;
+        PolygonMode::Mode backMode = PolygonMode::FILL;
+        if (frontProp) {
+            findAttr(polygonModeModes, frontProp, frontMode);
+            pmode->setMode(PolygonMode::FRONT, frontMode);
+        }
+        if (backProp) {
+            findAttr(polygonModeModes, backProp, backMode);
+            pmode->setMode(PolygonMode::BACK, backMode);
+        }
+        pass->setAttribute(pmode.get());
+    }
+};
+
+InstallAttributeBuilder<PolygonModeBuilder> installPolygonMode("polygon-mode");
 void buildTechnique(Effect* effect, const SGPropertyNode* prop,
                     const osgDB::ReaderWriter::Options* options)
 {
index 1484c4208e04d8a5f88882e35cfc884378334222..63b8aebd06239632a1266d9acc1a5b67f31516b8 100644 (file)
@@ -176,6 +176,9 @@ SGMaterial::read_properties(const osgDB::Options* options,
 
   shininess = props->getDoubleValue("shininess", 1.0);
 
+  if (props->hasChild("effect"))
+      effect = props->getStringValue("effect");
+  
   vector<SGPropertyNode_ptr> object_group_nodes =
     ((SGPropertyNode *)props)->getChildren("object-group");
   for (unsigned int i = 0; i < object_group_nodes.size(); i++)
@@ -222,6 +225,7 @@ SGMaterial::init ()
         diffuse[i]  = (i < 3) ? 0.8 : 1.0;
         emission[i] = (i < 3) ? 0.0 : 1.0;
     }
+    effect = "Effects/terrain-default";
 }
 
 Effect* SGMaterial::get_effect(int n)
@@ -246,8 +250,7 @@ void SGMaterial::buildEffectProperties(const osgDB::Options* options)
 {
     using namespace osg;
     SGPropertyNode_ptr propRoot = new SGPropertyNode();
-    makeChild(propRoot, "inherits-from")
-        ->setStringValue("Effects/terrain-default");
+    makeChild(propRoot, "inherits-from")->setStringValue(effect);
     SGPropertyNode* paramProp = makeChild(propRoot, "parameters");
     SGPropertyNode* materialProp = makeChild(paramProp, "material");
     makeChild(materialProp, "ambient")->setValue(SGVec4d(ambient));    
index 1317072a6d9737b3398c29ad0a57fcc3e5fa6f44..ae246ad57e943ed0ca7b5e41890d22c3a93ab448 100644 (file)
@@ -326,6 +326,9 @@ private:
   SGVec4f ambient, diffuse, specular, emission;
   double shininess;
 
+  // effect for this material
+  std::string effect;
+
   // the list of names for this material. May be empty.
   std::vector<std::string> _names;