]> git.mxchange.org Git - simgear.git/commitdiff
Add positioned uniforms and G-buffer textures to Effects
authorFrederic Bouvier <fredfgfs01@free.fr>
Mon, 2 Jan 2012 10:34:11 +0000 (11:34 +0100)
committerFrederic Bouvier <fredfgfs01@free.fr>
Sun, 4 Mar 2012 19:21:16 +0000 (20:21 +0100)
simgear/scene/material/Effect.cxx
simgear/scene/material/EffectBuilder.hxx
simgear/scene/material/EffectCullVisitor.cxx
simgear/scene/material/EffectCullVisitor.hxx
simgear/scene/material/Pass.hxx
simgear/scene/material/Technique.cxx
simgear/scene/material/TextureBuilder.cxx
simgear/scene/material/TextureBuilder.hxx

index 9ca2aceeff184cffad7c9787cca8609061bb524e..3cd6a93b7a6166701c442edb2852d21e1ab3fd02 100644 (file)
@@ -916,6 +916,7 @@ struct UniformBuilder :public PassAttributeBuilder
             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");
         string name;
         Uniform::Type uniformType = Uniform::FLOAT;
@@ -1003,6 +1004,11 @@ struct UniformBuilder :public PassAttributeBuilder
             }
         }
         pass->addUniform(uniform.get());
+        if (positionedProp && positionedProp->getBoolValue() && uniformType == Uniform::FLOAT_VEC4) {
+            osg::Vec4 offset;
+            uniform->get(offset);
+            pass->addPositionedUniform( name, offset );
+        }
     }
 };
 
@@ -1163,7 +1169,10 @@ struct DepthBuilder : public PassAttributeBuilder
             = getEffectPropertyChild(effect, prop, "write-mask");
         if (pmask)
             depth->setWriteMask(pmask->getValue<bool>());
-        pass->setAttribute(depth.get());
+        const SGPropertyNode* penabled
+            = getEffectPropertyChild(effect, prop, "enabled");
+        bool enabled = ( penabled == 0 || penabled->getBoolValue() );
+        pass->setAttributeAndModes(depth.get(), enabled ? osg::StateAttribute::ON : osg::StateAttribute::OFF);
     }
 };
 
index a464071f717b27712e75679a9dadf4d75e1bd6af..a7c35ea13d447e6e9681013eb2cda486d6eaab08 100644 (file)
@@ -58,16 +58,16 @@ class EffectBuilder : public SGReferenced
 {
 public:
     virtual ~EffectBuilder() {}
-    virtual T* build(Effect* effect, const SGPropertyNode*,
+    virtual T* build(Effect* effect, Pass* pass, const SGPropertyNode*,
                      const SGReaderWriterOptions* options) = 0;
-    static T* buildFromType(Effect* effect, const std::string& type,
+    static T* buildFromType(Effect* effect, Pass* pass, const std::string& type,
                             const SGPropertyNode*props,
                             const SGReaderWriterOptions* options)
     {
         BuilderMap& builderMap = getMap();
         typename BuilderMap::iterator iter = builderMap.find(type);
         if (iter != builderMap.end())
-            return iter->second->build(effect, props, options);
+            return iter->second->build(effect, pass, props, options);
         else
             return 0;
     }
index e2d199207dd52293e17b1c5b7f73e8535e0bcdfc..36f85eb4fc99e940326ae74a14997ae7147377ae 100644 (file)
@@ -19,6 +19,7 @@
 #endif
 
 #include <osg/StateSet>
+#include <osg/Texture2D>
 
 #include "EffectCullVisitor.hxx"
 
@@ -78,4 +79,20 @@ void EffectCullVisitor::apply(osg::Geode& node)
         popStateSet();
 
 }
+
+void EffectCullVisitor::clearBufferList()
+{
+    _bufferList.clear();
+}
+
+void EffectCullVisitor::addBuffer(int i, osg::Texture2D* tex)
+{
+    _bufferList.insert(std::make_pair(i,tex));
+}
+
+osg::Texture2D* EffectCullVisitor::getBuffer(int i)
+{
+    return _bufferList[i];
+}
+
 }
index fa752c8f2cc784de4599e71f381a97fa817fb895..4f0054dd7270e94c8c27b2f2976397de9e13a9c8 100644 (file)
 
 #include <osgUtil/CullVisitor>
 
+#include <map>
+
 namespace osg
 {
 class Geode;
+class Texture2D;
 }
 
 namespace simgear
@@ -34,6 +37,13 @@ public:
     virtual osgUtil::CullVisitor* clone() const;
     using osgUtil::CullVisitor::apply;
     virtual void apply(osg::Geode& node);
+
+    void clearBufferList();
+    void addBuffer(int i, osg::Texture2D* tex);
+    osg::Texture2D* getBuffer(int i);
+
+private:
+    std::map<int,osg::ref_ptr<osg::Texture2D> > _bufferList;
 };
 }
 #endif
index 869dabd9df0107bf99bb1bd5d4b6f26d4014223e..a2c901ddacb8f84ed40cb38c5303c5c0948de548 100644 (file)
@@ -26,10 +26,23 @@ namespace simgear
 class Pass : public osg::StateSet
 {
 public:
+    typedef std::list<std::pair<int,int> > BufferUnitList;
+    typedef std::map<std::string,osg::Vec4> PositionedUniformMap;
+
     META_Object(simgear,Pass);
     Pass() {}
     Pass(const Pass& rhs,
          const osg::CopyOp& copyop = osg::CopyOp::SHALLOW_COPY);
+
+    void setBufferUnit( int unit, int buffer ) { _bufferUnitList.push_back( std::make_pair(unit,buffer) ); }
+    const BufferUnitList& getBufferUnitList() const { return _bufferUnitList; }
+
+    void addPositionedUniform( const std::string& name, const osg::Vec4& offset ) { _positionedUniforms[name] = offset; }
+    const PositionedUniformMap& getPositionedUniformMap() const { return _positionedUniforms; }
+
+private:
+    BufferUnitList _bufferUnitList;
+    PositionedUniformMap _positionedUniforms;
 };
 
 }
index a540fb2f67b496c8eff69ffdf52a1618900f220a..3a09dfead0b64bfb43b27b1013f4fbbe5994f475 100644 (file)
@@ -5,6 +5,7 @@
 
 #include "Technique.hxx"
 #include "Pass.hxx"
+#include "EffectCullVisitor.hxx"
 
 #include <boost/foreach.hpp>
 
@@ -15,6 +16,8 @@
 #include <osg/GLExtensions>
 #include <osg/GL2Extensions>
 #include <osg/Math>
+#include <osg/Texture2D>
+#include <osg/CopyOp>
 #include <osgUtil/CullVisitor>
 
 #include <osgDB/Registry>
@@ -159,10 +162,37 @@ Technique::processDrawables(const EffectGeode::DrawablesIterator& begin,
         if (isNaN(depth[i]))
             depth[i] = FLT_MAX;
     }
+    EffectCullVisitor* ecv = dynamic_cast<EffectCullVisitor*>( cv );
     EffectGeode::DrawablesIterator drawablesEnd = itr;
     BOOST_FOREACH(ref_ptr<Pass>& pass, passes)
     {
-        cv->pushStateSet(pass.get());
+        osg::ref_ptr<osg::StateSet> ss = pass;
+        if (ecv && ( pass->getBufferUnitList().size() != 0 || pass->getPositionedUniformMap().size() != 0 ) ) {
+            ss = static_cast<osg::StateSet*>(
+                pass->clone( osg::CopyOp( ( pass->getBufferUnitList().size() != 0 ?
+                                                        osg::CopyOp::DEEP_COPY_TEXTURES :
+                                                        osg::CopyOp::SHALLOW_COPY ) |
+                                           ( pass->getPositionedUniformMap().size() != 0 ?
+                                                        osg::CopyOp::DEEP_COPY_UNIFORMS :
+                                                        osg::CopyOp::SHALLOW_COPY ) )
+                )
+            );
+            for (Pass::BufferUnitList::const_iterator ii = pass->getBufferUnitList().begin();
+                    ii != pass->getBufferUnitList().end();
+                    ++ii) {
+                osg::Texture2D* tex = ecv->getBuffer(ii->second);
+                if (tex != 0)
+                    ss->setTextureAttributeAndModes( ii->first, tex );
+            }
+            for (Pass::PositionedUniformMap::const_iterator ii = pass->getPositionedUniformMap().begin();
+                    ii != pass->getPositionedUniformMap().end();
+                    ++ii) {
+                osg::RefMatrix* mv = cv->getModelViewMatrix();
+                osg::Vec4 v = ii->second * *mv;
+                ss->getUniform(ii->first)->set( v );
+            }
+        }
+        cv->pushStateSet(ss);
         int i = 0;
         for (itr = begin; itr != drawablesEnd; ++itr, ++i) {
             if (depth[i] != FLT_MAX)
index d191ef33c1c57d2886e6b57b4229f54fe1533af9..f4523c9bb534b3b152e5420b1b4931af1ae6022a 100644 (file)
@@ -59,12 +59,12 @@ TexEnvCombine* buildTexEnvCombine(Effect* effect,
 TexGen* buildTexGen(Effect* Effect, const SGPropertyNode* tgenProp);
 
 // Hack to force inclusion of TextureBuilder.cxx in library
-osg::Texture* TextureBuilder::buildFromType(Effect* effect, const string& type,
+osg::Texture* TextureBuilder::buildFromType(Effect* effect, Pass* pass, const string& type,
                                             const SGPropertyNode*props,
                                             const SGReaderWriterOptions*
                                             options)
 {
-    return EffectBuilder<Texture>::buildFromType(effect, type, props, options);
+    return EffectBuilder<Texture>::buildFromType(effect, pass, type, props, options);
 }
 
 typedef boost::tuple<string, Texture::FilterMode, Texture::FilterMode,
@@ -130,7 +130,7 @@ void TextureUnitBuilder::buildAttribute(Effect* effect, Pass* pass,
         type = pType->getStringValue();
     Texture* texture = 0;
     try {
-        texture = TextureBuilder::buildFromType(effect, type, prop,
+        texture = TextureBuilder::buildFromType(effect, pass, type, prop,
                                                 options);
     }
     catch (BuilderException& e) {
@@ -278,7 +278,7 @@ class TexBuilder : public TextureBuilder
 {
 public:
     TexBuilder(const string& texType) : _type(texType) {}
-    Texture* build(Effect* effect, const SGPropertyNode*,
+    Texture* build(Effect* effect, Pass* pass, const SGPropertyNode*,
                    const SGReaderWriterOptions* options);
 protected:
     typedef map<TexTuple, ref_ptr<T> > TexMap;
@@ -287,7 +287,7 @@ protected:
 };
 
 template<typename T>
-Texture* TexBuilder<T>::build(Effect* effect, const SGPropertyNode* props,
+Texture* TexBuilder<T>::build(Effect* effect, Pass* pass, const SGPropertyNode* props,
                               const SGReaderWriterOptions* options)
 {
     TexTuple attrs = makeTexTuple(effect, props, options, _type);
@@ -311,11 +311,11 @@ TextureBuilder::Registrar install3D("3d", new TexBuilder<Texture3D>("3d"));
 class WhiteTextureBuilder : public TextureBuilder
 {
 public:
-    Texture* build(Effect* effect, const SGPropertyNode*,
+    Texture* build(Effect* effect, Pass* pass, const SGPropertyNode*,
                    const SGReaderWriterOptions* options);
 };
 
-Texture* WhiteTextureBuilder::build(Effect* effect, const SGPropertyNode*,
+Texture* WhiteTextureBuilder::build(Effect* effect, Pass* pass, const SGPropertyNode*,
                                     const SGReaderWriterOptions* options)
 {
     return StateAttributeFactory::instance()->getWhiteTexture();
@@ -329,11 +329,11 @@ TextureBuilder::Registrar installWhite("white", new WhiteTextureBuilder);
 class TransparentTextureBuilder : public TextureBuilder
 {
 public:
-    Texture* build(Effect* effect, const SGPropertyNode*,
+    Texture* build(Effect* effect, Pass* pass, const SGPropertyNode*,
                    const SGReaderWriterOptions* options);
 };
 
-Texture* TransparentTextureBuilder::build(Effect* effect, const SGPropertyNode*,
+Texture* TransparentTextureBuilder::build(Effect* effect, Pass* pass, const SGPropertyNode*,
                                     const SGReaderWriterOptions* options)
 {
     return StateAttributeFactory::instance()->getTransparentTexture();
@@ -393,14 +393,14 @@ osg::Image* make3DNoiseImage(int texSize)
 class NoiseBuilder : public TextureBuilder
 {
 public:
-    Texture* build(Effect* effect, const SGPropertyNode*,
+    Texture* build(Effect* effect, Pass* pass, const SGPropertyNode*,
                    const SGReaderWriterOptions* options);
 protected:
     typedef map<int, ref_ptr<Texture3D> > NoiseMap;
     NoiseMap _noises;
 };
 
-Texture* NoiseBuilder::build(Effect* effect, const SGPropertyNode* props,
+Texture* NoiseBuilder::build(Effect* effect, Pass* pass, const SGPropertyNode* props,
                              const SGReaderWriterOptions* options)
 {
     int texSize = 64;
@@ -461,7 +461,7 @@ CubeMapTuple makeCubeMapTuple(Effect* effect, const SGPropertyNode* props)
 class CubeMapBuilder : public TextureBuilder
 {
 public:
-    Texture* build(Effect* effect, const SGPropertyNode*,
+    Texture* build(Effect* effect, Pass* pass, const SGPropertyNode*,
                    const SGReaderWriterOptions* options);
 protected:
     typedef map<CubeMapTuple, ref_ptr<TextureCubeMap> > CubeMap;
@@ -484,7 +484,7 @@ void copySubImage(const osg::Image* srcImage, int src_s, int src_t, int width, i
 }
 
 
-Texture* CubeMapBuilder::build(Effect* effect, const SGPropertyNode* props,
+Texture* CubeMapBuilder::build(Effect* effect, Pass* pass, const SGPropertyNode* props,
                                const SGReaderWriterOptions* options)
 {
     // First check that there is a <images> tag
@@ -876,4 +876,45 @@ bool makeTextureParameters(SGPropertyNode* paramRoot, const StateSet* ss)
     return true;
 }
 
+class GBufferBuilder : public TextureBuilder
+{
+public:
+    GBufferBuilder(int b) : buffer(b) {}
+    Texture* build(Effect* effect, Pass* pass, const SGPropertyNode*,
+                   const SGReaderWriterOptions* options);
+private:
+    int buffer;
+};
+
+Texture* GBufferBuilder::build(Effect* effect, Pass* pass, const SGPropertyNode* prop,
+                                    const SGReaderWriterOptions* options)
+{
+    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());
+            }
+    }
+    pass->setBufferUnit( unit, buffer );
+
+    // Return white for now. Would be overridden in Technique::ProcessDrawable
+    return StateAttributeFactory::instance()->getWhiteTexture();
+}
+
+namespace
+{
+TextureBuilder::Registrar installDepthBuffer("depth-buffer", new GBufferBuilder(0));
+TextureBuilder::Registrar installNormalBuffer("normal-buffer", new GBufferBuilder(1));
+TextureBuilder::Registrar installDiffuseBuffer("diffuse-buffer", new GBufferBuilder(2));
+TextureBuilder::Registrar installSpecularBuffer("specular-buffer", new GBufferBuilder(3));
+}
+
 }
index c8105e750b58385b571be804a3e402a55bab7adb..c4225a212cfd8c5e861c8bf72c9d01efb4cbf0b8 100644 (file)
@@ -27,7 +27,7 @@ class TextureBuilder : public EffectBuilder<osg::Texture>
 {
 public:
     // Hack to force inclusion of TextureBuilder.cxx in library
-    static osg::Texture* buildFromType(Effect* effect, const std::string& type,
+    static osg::Texture* buildFromType(Effect* effect, Pass* pass, const std::string& type,
                                        const SGPropertyNode*props,
                                        const SGReaderWriterOptions* options);
 };