]> git.mxchange.org Git - simgear.git/commitdiff
Use SGExpressions for evaluating a Technique's validity
authortimoore <timoore>
Wed, 15 Jul 2009 23:10:13 +0000 (23:10 +0000)
committerTim Moore <timoore@redhat.com>
Thu, 16 Jul 2009 10:09:44 +0000 (12:09 +0200)
simgear/scene/material/Technique.cxx
simgear/scene/material/Technique.hxx
simgear/scene/material/mat.cxx

index d56d262a6e86c26081361bd03a3ee72d00520edd..5c1d835b683e075a5506b0a8b9d1ba7670862012 100644 (file)
@@ -4,6 +4,7 @@
 #include <boost/bind.hpp>
 #include <boost/foreach.hpp>
 
+#include <vector>
 #include <string>
 
 #include <osg/GLExtensions>
@@ -45,13 +46,15 @@ void ValidateOperation::operator() (GraphicsContext* gc)
 }
 
 Technique::Technique(bool alwaysValid)
-    : _alwaysValid(alwaysValid), _glVersion(1.1f)
+    : _alwaysValid(alwaysValid), _contextIdLocation(-1)
 {
 }
 
 Technique::Technique(const Technique& rhs, const osg::CopyOp& copyop) :
     _contextMap(rhs._contextMap), _alwaysValid(rhs._alwaysValid),
-    _shadowingStateSet(rhs._shadowingStateSet), _glVersion(rhs._glVersion)
+    _shadowingStateSet(rhs._shadowingStateSet),
+    _validExpression(rhs._validExpression),
+    _contextIdLocation(rhs._contextIdLocation)
 {
     using namespace std;
     using namespace boost;
@@ -81,8 +84,12 @@ Technique::Status Technique::valid(osg::RenderInfo* renderInfo)
         return contextInfo.valid();
     }
     ref_ptr<ValidateOperation> validOp = new ValidateOperation(this);
-    renderInfo->getState()->getGraphicsContext()->getGraphicsThread()
-        ->add(validOp.get());
+    GraphicsContext* context = renderInfo->getState()->getGraphicsContext();
+    GraphicsThread* thread = context->getGraphicsThread();
+    if (thread)
+        thread->add(validOp.get());
+    else
+        context->add(validOp.get());
     return newStatus;
 }
 
@@ -96,10 +103,13 @@ Technique::Status Technique::getValidStatus(const RenderInfo* renderInfo) const
 
 void Technique::validateInContext(GraphicsContext* gc)
 {
-    ContextInfo& contextInfo = _contextMap[gc->getState()->getContextID()];
+    unsigned int contextId = gc->getState()->getContextID();
+    ContextInfo& contextInfo = _contextMap[contextId];
     Status oldVal = contextInfo.valid();
     Status newVal = INVALID;
-    if (getGLVersionNumber() >= _glVersion)
+    expression::FixedLengthBinding<1> binding;
+    binding.getBindings()[_contextIdLocation].val.intVal = contextId;
+    if (_validExpression->getValue(&binding))
         newVal = VALID;
     contextInfo.valid.compareAndSwap(oldVal, newVal);
 }
@@ -187,12 +197,90 @@ void Technique::releaseGLObjects(osg::State* state) const
     }
 }
 
+void Technique::setValidExpression(SGExpressionb* exp,
+                                   const simgear::expression
+                                   ::BindingLayout& layout)
+{
+    using namespace simgear::expression;
+    _validExpression = exp;
+    VariableBinding binding;
+    if (layout.findBinding("__contextId", binding))
+        _contextIdLocation = binding.location;
+}
+
+class GLVersionExpression : public SGExpression<float>
+{
+public:
+    void eval(float& value, const expression::Binding*) const
+    {
+        value = getGLVersionNumber();
+    }
+};
+
+class ExtensionSupportedExpression
+    : public GeneralNaryExpression<bool, int>
+{
+public:
+    ExtensionSupportedExpression() {}
+    ExtensionSupportedExpression(const string& extString)
+        : _extString(extString)
+    {
+    }
+    const string& getExtensionString() { return _extString; }
+    void setExtensionString(const 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;
+};
+
+void Technique::setGLExtensionsPred(float glVersion,
+                                    const std::vector<std::string>& extensions)
+{
+    using namespace std;
+    using namespace expression;
+    BindingLayout layout;
+    int contextLoc = layout.addBinding("__contextId", INT);
+    VariableExpression<int>* contextExp
+        = new VariableExpression<int>(contextLoc);
+    LessEqualExpression<float>* versionTest
+        = new LessEqualExpression<float>(new SGConstExpression<float>(glVersion),
+                                         new GLVersionExpression);
+    AndExpression* extensionsExp = 0;
+    for (vector<string>::const_iterator itr = extensions.begin(),
+             e = extensions.end();
+         itr != e;
+         ++itr) {
+        if (!extensionsExp)
+            extensionsExp = new AndExpression;
+        ExtensionSupportedExpression* supported
+            = new ExtensionSupportedExpression(*itr);
+        supported->addOperand(contextExp);
+        extensionsExp->addOperand(supported);
+    }
+    SGExpressionb* predicate = 0;
+    if (extensionsExp) {
+        OrExpression* orExp = new OrExpression;
+        orExp->addOperand(versionTest);
+        orExp->addOperand(extensionsExp);
+        predicate = orExp;
+    } else {
+        predicate = versionTest;
+    }
+    setValidExpression(predicate, layout);
+}
+
 bool Technique_writeLocalData(const Object& obj, osgDB::Output& fw)
 {
     const Technique& tniq = static_cast<const Technique&>(obj);
     fw.indent() << "alwaysValid "
                 << (tniq.getAlwaysValid() ? "TRUE\n" : "FALSE\n");
+#if 0
     fw.indent() << "glVersion " << tniq.getGLVersion() << "\n";
+#endif
     if (tniq.getShadowingStateSet()) {
         fw.indent() << "shadowingStateSet\n";
         fw.writeObject(*tniq.getShadowingStateSet());
index 455ee35d5acb6a0096955ba32791dc332ae3ac28..9ada783c1192fa7cdcec6c5aa3a6fe4c33a41ae7 100644 (file)
@@ -20,6 +20,7 @@
 #include "EffectGeode.hxx"
 
 #include <simgear/structure/SGAtomic.hxx>
+#include <simgear/structure/SGExpression.hxx>
 
 #include <map>
 #include <vector>
@@ -90,13 +91,12 @@ public:
     void setShadowingStateSet(osg::StateSet* ss) { _shadowingStateSet = ss; }
     virtual void resizeGLObjectBuffers(unsigned int maxSize);
     virtual void releaseGLObjects(osg::State* state = 0) const;
-    // Initial validity testing. Either the minimum OpenGL version
-    // must be supported, or the list of extensions must be supported.
-    float getGLVersion() const { return _glVersion; }
-    void setGLVersion(float glVersion) { _glVersion = glVersion; }
-    std::vector<std::string> glExtensions;
     bool getAlwaysValid() const { return _alwaysValid; }
     void setAlwaysValid(bool val) { _alwaysValid = val; }
+    void setValidExpression(SGExpressionb* exp,
+                            const simgear::expression::BindingLayout&);
+    void setGLExtensionsPred(float glVersion,
+                             const std::vector<std::string>& extensions);
 protected:
     // Validity of technique in a graphics context.
     struct ContextInfo : public osg::Referenced
@@ -113,7 +113,8 @@ protected:
     mutable ContextMap _contextMap;
     bool _alwaysValid;
     osg::ref_ptr<osg::StateSet> _shadowingStateSet;
-    float _glVersion;
+    SGSharedPtr<SGExpressionb> _validExpression;
+    int _contextIdLocation;
 };
 }
 #endif
index d65893a97a55918ad0b38396c4d63ef67c4fda97..2c97551a31569f117803eeea46b8e52e723dc505 100644 (file)
@@ -29,6 +29,8 @@
 
 #include <string.h>
 #include <map>
+#include <vector>
+#include<string>
 
 #include "mat.hxx"
 
@@ -312,7 +314,8 @@ SGMaterial::build_state( bool defer_tex_load )
         }
 
         _status[i].state = pass;
-        Technique* tniq = new Technique(true);
+        Technique* tniq = new Technique();
+        tniq->setGLExtensionsPred(1.1, std::vector<std::string>());
         tniq->passes.push_back(pass);
         Effect* effect = new Effect;
         effect->techniques.push_back(tniq);