]> git.mxchange.org Git - simgear.git/blobdiff - simgear/scene/material/Technique.cxx
Work around apparent OSG 3.2.0 normal binding bug.
[simgear.git] / simgear / scene / material / Technique.cxx
index b8093f353088017104fb5fc1738d9a2897dd2131..4caa9d0cd3b91485239b98df54272196c7a6ed07 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>
@@ -58,8 +61,9 @@ Technique::Technique(bool alwaysValid)
 }
 
 Technique::Technique(const Technique& rhs, const osg::CopyOp& copyop) :
+    osg::Object(rhs,copyop),
     _contextMap(rhs._contextMap), _alwaysValid(rhs._alwaysValid),
-    _shadowingStateSet(copyop(rhs._shadowingStateSet)),
+    _shadowingStateSet(copyop(rhs._shadowingStateSet.get())),
     _validExpression(rhs._validExpression),
     _contextIdLocation(rhs._contextIdLocation)
 {
@@ -158,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().empty() || ! pass->getPositionedUniformMap().empty() ) ) {
+            ss = static_cast<osg::StateSet*>(
+                pass->clone( osg::CopyOp( ( ! pass->getBufferUnitList().empty() ?
+                                                        osg::CopyOp::DEEP_COPY_TEXTURES :
+                                                        osg::CopyOp::SHALLOW_COPY ) |
+                                           ( ! pass->getPositionedUniformMap().empty() ?
+                                                        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)
@@ -240,19 +271,19 @@ class ExtensionSupportedExpression
 {
 public:
     ExtensionSupportedExpression() {}
-    ExtensionSupportedExpression(const string& extString)
+    ExtensionSupportedExpression(const std::string& extString)
         : _extString(extString)
     {
     }
-    const string& getExtensionString() { return _extString; }
-    void setExtensionString(const string& extString) { _extString = extString; }
+    const std::string& getExtensionString() { return _extString; }
+    void setExtensionString(const std::string& extString) { _extString = extString; }
     void eval(bool&value, const expression::Binding* b) const
     {
         int contextId = getOperand(0)->getValue(b);
         value = isGLExtensionSupported((unsigned)contextId, _extString.c_str());
     }
 protected:
-    string _extString;
+    std::string _extString;
 };
 
 Expression* extensionSupportedParser(const SGPropertyNode* exp,