From a5a6600e745d763fc2b933141ebf090879c700bb Mon Sep 17 00:00:00 2001 From: timoore Date: Wed, 15 Jul 2009 23:10:13 +0000 Subject: [PATCH] Use SGExpressions for evaluating a Technique's validity --- simgear/scene/material/Technique.cxx | 100 +++++++++++++++++++++++++-- simgear/scene/material/Technique.hxx | 13 ++-- simgear/scene/material/mat.cxx | 5 +- 3 files changed, 105 insertions(+), 13 deletions(-) diff --git a/simgear/scene/material/Technique.cxx b/simgear/scene/material/Technique.cxx index d56d262a..5c1d835b 100644 --- a/simgear/scene/material/Technique.cxx +++ b/simgear/scene/material/Technique.cxx @@ -4,6 +4,7 @@ #include #include +#include #include #include @@ -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 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 +{ +public: + void eval(float& value, const expression::Binding*) const + { + value = getGLVersionNumber(); + } +}; + +class ExtensionSupportedExpression + : public GeneralNaryExpression +{ +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& extensions) +{ + using namespace std; + using namespace expression; + BindingLayout layout; + int contextLoc = layout.addBinding("__contextId", INT); + VariableExpression* contextExp + = new VariableExpression(contextLoc); + LessEqualExpression* versionTest + = new LessEqualExpression(new SGConstExpression(glVersion), + new GLVersionExpression); + AndExpression* extensionsExp = 0; + for (vector::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(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()); diff --git a/simgear/scene/material/Technique.hxx b/simgear/scene/material/Technique.hxx index 455ee35d..9ada783c 100644 --- a/simgear/scene/material/Technique.hxx +++ b/simgear/scene/material/Technique.hxx @@ -20,6 +20,7 @@ #include "EffectGeode.hxx" #include +#include #include #include @@ -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 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& 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 _shadowingStateSet; - float _glVersion; + SGSharedPtr _validExpression; + int _contextIdLocation; }; } #endif diff --git a/simgear/scene/material/mat.cxx b/simgear/scene/material/mat.cxx index d65893a9..2c97551a 100644 --- a/simgear/scene/material/mat.cxx +++ b/simgear/scene/material/mat.cxx @@ -29,6 +29,8 @@ #include #include +#include +#include #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()); tniq->passes.push_back(pass); Effect* effect = new Effect; effect->techniques.push_back(tniq); -- 2.39.5