]> git.mxchange.org Git - simgear.git/blobdiff - simgear/scene/material/Effect.cxx
pass SGReaderWriterXMLOptions to effects
[simgear.git] / simgear / scene / material / Effect.cxx
index 940b1f18b15873bd1722f6460287235aaa21683a..3ad9316216fd0904e039f9c8caeb79f76092ab2c 100644 (file)
@@ -51,6 +51,7 @@
 #include <osg/RenderInfo>
 #include <osg/ShadeModel>
 #include <osg/StateSet>
+#include <osg/Stencil>
 #include <osg/TexEnv>
 #include <osg/Texture1D>
 #include <osg/Texture2D>
@@ -65,6 +66,7 @@
 #include <osgDB/ReadFile>
 #include <osgDB/Registry>
 
+#include <simgear/scene/model/SGReaderWriterXMLOptions.hxx>
 #include <simgear/scene/tgdb/userdata.hxx>
 #include <simgear/scene/util/SGSceneFeatures.hxx>
 #include <simgear/scene/util/StateAttributeFactory.hxx>
@@ -142,7 +144,7 @@ Effect::~Effect()
 }
 
 void buildPass(Effect* effect, Technique* tniq, const SGPropertyNode* prop,
-               const osgDB::ReaderWriter::Options* options)
+               const SGReaderWriterXMLOptions* options)
 {
     Pass* pass = new Pass;
     tniq->passes.push_back(pass);
@@ -187,12 +189,12 @@ osg::Vec4f getColor(const SGPropertyNode* prop)
 struct LightingBuilder : public PassAttributeBuilder
 {
     void buildAttribute(Effect* effect, Pass* pass, const SGPropertyNode* prop,
-                        const osgDB::ReaderWriter::Options* options);
+                        const SGReaderWriterXMLOptions* options);
 };
 
 void LightingBuilder::buildAttribute(Effect* effect, Pass* pass,
                                      const SGPropertyNode* prop,
-                                     const osgDB::ReaderWriter::Options* options)
+                                     const SGReaderWriterXMLOptions* options)
 {
     const SGPropertyNode* realProp = getEffectPropertyNode(effect, prop);
     if (!realProp)
@@ -206,7 +208,7 @@ InstallAttributeBuilder<LightingBuilder> installLighting("lighting");
 struct ShadeModelBuilder : public PassAttributeBuilder
 {
     void buildAttribute(Effect* effect, Pass* pass, const SGPropertyNode* prop,
-                        const osgDB::ReaderWriter::Options* options)
+                        const SGReaderWriterXMLOptions* options)
     {
         const SGPropertyNode* realProp = getEffectPropertyNode(effect, prop);
         if (!realProp)
@@ -228,7 +230,7 @@ InstallAttributeBuilder<ShadeModelBuilder> installShadeModel("shade-model");
 struct CullFaceBuilder : PassAttributeBuilder
 {
     void buildAttribute(Effect* effect, Pass* pass, const SGPropertyNode* prop,
-                        const osgDB::ReaderWriter::Options* options)
+                        const SGReaderWriterXMLOptions* options)
     {
         const SGPropertyNode* realProp = getEffectPropertyNode(effect, prop);
         if (!realProp) {
@@ -253,6 +255,24 @@ struct CullFaceBuilder : PassAttributeBuilder
 
 InstallAttributeBuilder<CullFaceBuilder> installCullFace("cull-face");
 
+struct ColorMaskBuilder : PassAttributeBuilder
+{
+    void buildAttribute(Effect* effect, Pass* pass, const SGPropertyNode* prop,
+                        const SGReaderWriterXMLOptions* options)
+    {
+        const SGPropertyNode* realProp = getEffectPropertyNode(effect, prop);
+        if (!realProp)
+            return;
+
+        ColorMask *mask = new ColorMask;
+        Vec4 m = getColor(realProp);
+        mask->setMask(m.r(), m.g(), m.b(), m.a());
+        pass->setAttributeAndModes(mask);
+    }    
+};
+
+InstallAttributeBuilder<ColorMaskBuilder> installColorMask("color-mask");
+
 EffectNameValue<StateSet::RenderingHint> renderingHintInit[] =
 {
     { "default", StateSet::DEFAULT_BIN },
@@ -265,7 +285,7 @@ EffectPropertyMap<StateSet::RenderingHint> renderingHints(renderingHintInit);
 struct HintBuilder : public PassAttributeBuilder
 {
     void buildAttribute(Effect* effect, Pass* pass, const SGPropertyNode* prop,
-                        const osgDB::ReaderWriter::Options* options)
+                        const SGReaderWriterXMLOptions* options)
     {
         const SGPropertyNode* realProp = getEffectPropertyNode(effect, prop);
         if (!realProp)
@@ -281,7 +301,7 @@ InstallAttributeBuilder<HintBuilder> installHint("rendering-hint");
 struct RenderBinBuilder : public PassAttributeBuilder
 {
     void buildAttribute(Effect* effect, Pass* pass, const SGPropertyNode* prop,
-                        const osgDB::ReaderWriter::Options* options)
+                        const SGReaderWriterXMLOptions* options)
     {
         if (!isAttributeActive(effect, prop))
             return;
@@ -308,7 +328,7 @@ InstallAttributeBuilder<RenderBinBuilder> installRenderBin("render-bin");
 struct MaterialBuilder : public PassAttributeBuilder
 {
     void buildAttribute(Effect* effect, Pass* pass, const SGPropertyNode* prop,
-                        const osgDB::ReaderWriter::Options* options);
+                        const SGReaderWriterXMLOptions* options);
 };
 
 EffectNameValue<Material::ColorMode> colorModeInit[] =
@@ -324,7 +344,7 @@ EffectPropertyMap<Material::ColorMode> colorModes(colorModeInit);
 
 void MaterialBuilder::buildAttribute(Effect* effect, Pass* pass,
                                      const SGPropertyNode* prop,
-                                     const osgDB::ReaderWriter::Options* options)
+                                     const SGReaderWriterXMLOptions* options)
 {
     if (!isAttributeActive(effect, prop))
         return;
@@ -394,7 +414,7 @@ EffectPropertyMap<BlendFunc::BlendFuncMode> blendFuncModes(blendFuncModesInit);
 struct BlendBuilder : public PassAttributeBuilder
 {
     void buildAttribute(Effect* effect, Pass* pass, const SGPropertyNode* prop,
-                        const osgDB::ReaderWriter::Options* options)
+                        const SGReaderWriterXMLOptions* options)
     {
         if (!isAttributeActive(effect, prop))
             return;
@@ -475,6 +495,99 @@ struct BlendBuilder : public PassAttributeBuilder
 
 InstallAttributeBuilder<BlendBuilder> installBlend("blend");
 
+
+EffectNameValue<Stencil::Function> stencilFunctionInit[] =
+{
+    {"never", Stencil::NEVER },
+    {"less", Stencil::LESS},
+    {"equal", Stencil::EQUAL},
+    {"less-or-equal", Stencil::LEQUAL},
+    {"greater", Stencil::GREATER},
+    {"not-equal", Stencil::NOTEQUAL},
+    {"greater-or-equal", Stencil::GEQUAL},
+    {"always", Stencil::ALWAYS}
+};
+
+EffectPropertyMap<Stencil::Function> stencilFunction(stencilFunctionInit);
+
+EffectNameValue<Stencil::Operation> stencilOperationInit[] =
+{
+    {"keep", Stencil::KEEP},
+    {"zero", Stencil::ZERO},
+    {"replace", Stencil::REPLACE},
+    {"increase", Stencil::INCR},
+    {"decrease", Stencil::DECR},
+    {"invert", Stencil::INVERT},
+    {"increase-wrap", Stencil::INCR_WRAP},
+    {"decrease-wrap", Stencil::DECR_WRAP}
+};
+
+EffectPropertyMap<Stencil::Operation> stencilOperation(stencilOperationInit);
+
+struct StencilBuilder : public PassAttributeBuilder
+{
+    void buildAttribute(Effect* effect, Pass* pass, const SGPropertyNode* prop,
+                        const SGReaderWriterXMLOptions* options)
+    {
+        if (!isAttributeActive(effect, prop))
+            return;
+
+        const SGPropertyNode* pmode = getEffectPropertyChild(effect, prop,
+                                                             "mode");
+        if (pmode && !pmode->getValue<bool>()) {
+            pass->setMode(GL_STENCIL, StateAttribute::OFF);
+            return;
+        }
+        const SGPropertyNode* pfunction
+            = getEffectPropertyChild(effect, prop, "function");
+        const SGPropertyNode* pvalue
+            = getEffectPropertyChild(effect, prop, "value");
+        const SGPropertyNode* pmask
+            = getEffectPropertyChild(effect, prop, "mask");
+        const SGPropertyNode* psfail
+            = getEffectPropertyChild(effect, prop, "stencil-fail");
+        const SGPropertyNode* pzfail
+            = getEffectPropertyChild(effect, prop, "z-fail");
+        const SGPropertyNode* ppass
+            = getEffectPropertyChild(effect, prop, "pass");
+
+        Stencil::Function func = Stencil::ALWAYS;  // Always pass
+        int ref = 0;
+        unsigned int mask = ~0u;  // All bits on
+        Stencil::Operation sfailop = Stencil::KEEP;  // Keep the old values as default
+        Stencil::Operation zfailop = Stencil::KEEP;
+        Stencil::Operation passop = Stencil::KEEP;
+
+        ref_ptr<Stencil> stencilFunc = new Stencil;
+
+        if (pfunction)
+            findAttr(stencilFunction, pfunction, func);
+        if (pvalue)
+            ref = pvalue->getIntValue();
+        if (pmask) 
+            mask = pmask->getIntValue();
+
+        if (psfail)
+            findAttr(stencilOperation, psfail, sfailop);
+        if (pzfail)
+            findAttr(stencilOperation, pzfail, zfailop);
+        if (ppass)
+            findAttr(stencilOperation, ppass, passop);
+
+        // Set the stencil operation
+        stencilFunc->setFunction(func, ref, mask);
+
+        // Set the operation, s-fail, s-pass/z-fail, s-pass/z-pass
+        stencilFunc->setOperation(sfailop, zfailop, passop);
+
+        // Add the operation to pass
+        pass->setAttributeAndModes(stencilFunc.get());
+    }
+};
+
+InstallAttributeBuilder<StencilBuilder> installStencil("stencil");
+
+
 EffectNameValue<AlphaFunc::ComparisonFunction> alphaComparisonInit[] =
 {
     {"never", AlphaFunc::NEVER},
@@ -492,7 +605,7 @@ alphaComparison(alphaComparisonInit);
 struct AlphaTestBuilder : public PassAttributeBuilder
 {
     void buildAttribute(Effect* effect, Pass* pass, const SGPropertyNode* prop,
-                        const osgDB::ReaderWriter::Options* options)
+                        const SGReaderWriterXMLOptions* options)
     {
         if (!isAttributeActive(effect, prop))
             return;
@@ -603,12 +716,12 @@ void reload_shaders()
 struct ShaderProgramBuilder : PassAttributeBuilder
 {
     void buildAttribute(Effect* effect, Pass* pass, const SGPropertyNode* prop,
-                        const osgDB::ReaderWriter::Options* options);
+                        const SGReaderWriterXMLOptions* options);
 };
 
 void ShaderProgramBuilder::buildAttribute(Effect* effect, Pass* pass,
                                           const SGPropertyNode* prop,
-                                          const osgDB::ReaderWriter::Options*
+                                          const SGReaderWriterXMLOptions*
                                           options)
 {
     using namespace boost;
@@ -703,7 +816,7 @@ EffectPropertyMap<Uniform::Type> uniformTypes(uniformTypesInit);
 struct UniformBuilder :public PassAttributeBuilder
 {
     void buildAttribute(Effect* effect, Pass* pass, const SGPropertyNode* prop,
-                        const osgDB::ReaderWriter::Options* options)
+                        const SGReaderWriterXMLOptions* options)
     {
         if (!isAttributeActive(effect, prop))
             return;
@@ -777,7 +890,7 @@ InstallAttributeBuilder<UniformBuilder> installUniform("uniform");
 struct NameBuilder : public PassAttributeBuilder
 {
     void buildAttribute(Effect* effect, Pass* pass, const SGPropertyNode* prop,
-                        const osgDB::ReaderWriter::Options* options)
+                        const SGReaderWriterXMLOptions* options)
     {
         // name can't use <use>
         string name = prop->getStringValue();
@@ -799,7 +912,7 @@ EffectPropertyMap<PolygonMode::Mode> polygonModeModes(polygonModeModesInit);
 struct PolygonModeBuilder : public PassAttributeBuilder
 {
     void buildAttribute(Effect* effect, Pass* pass, const SGPropertyNode* prop,
-                        const osgDB::ReaderWriter::Options* options)
+                        const SGReaderWriterXMLOptions* options)
     {
         if (!isAttributeActive(effect, prop))
             return;
@@ -827,7 +940,7 @@ InstallAttributeBuilder<PolygonModeBuilder> installPolygonMode("polygon-mode");
 struct VertexProgramTwoSideBuilder : public PassAttributeBuilder
 {
     void buildAttribute(Effect* effect, Pass* pass, const SGPropertyNode* prop,
-                        const osgDB::ReaderWriter::Options* options)
+                        const SGReaderWriterXMLOptions* options)
     {
         const SGPropertyNode* realProp = getEffectPropertyNode(effect, prop);
         if (!realProp)
@@ -844,7 +957,7 @@ installTwoSide("vertex-program-two-side");
 struct VertexProgramPointSizeBuilder : public PassAttributeBuilder
 {
     void buildAttribute(Effect* effect, Pass* pass, const SGPropertyNode* prop,
-                        const osgDB::ReaderWriter::Options* options)
+                        const SGReaderWriterXMLOptions* options)
     {
         const SGPropertyNode* realProp = getEffectPropertyNode(effect, prop);
         if (!realProp)
@@ -874,7 +987,7 @@ EffectPropertyMap<Depth::Function> depthFunction(depthFunctionInit);
 struct DepthBuilder : public PassAttributeBuilder
 {
     void buildAttribute(Effect* effect, Pass* pass, const SGPropertyNode* prop,
-                        const osgDB::ReaderWriter::Options* options)
+                        const SGReaderWriterXMLOptions* options)
     {
         if (!isAttributeActive(effect, prop))
             return;
@@ -905,7 +1018,7 @@ struct DepthBuilder : public PassAttributeBuilder
 InstallAttributeBuilder<DepthBuilder> installDepth("depth");
 
 void buildTechnique(Effect* effect, const SGPropertyNode* prop,
-                    const osgDB::ReaderWriter::Options* options)
+                    const SGReaderWriterXMLOptions* options)
 {
     Technique* tniq = new Technique;
     effect->techniques.push_back(tniq);
@@ -1011,7 +1124,7 @@ bool makeParametersFromStateSet(SGPropertyNode* effectRoot, const StateSet* ss)
 
 // Walk the techniques property tree, building techniques and
 // passes.
-bool Effect::realizeTechniques(const osgDB::ReaderWriter::Options* options)
+bool Effect::realizeTechniques(const SGReaderWriterXMLOptions* options)
 {
     if (_isRealized)
         return true;