Use SGExpressions for evaluating a Technique's validity
This commit is contained in:
@@ -4,6 +4,7 @@
|
|||||||
#include <boost/bind.hpp>
|
#include <boost/bind.hpp>
|
||||||
#include <boost/foreach.hpp>
|
#include <boost/foreach.hpp>
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include <osg/GLExtensions>
|
#include <osg/GLExtensions>
|
||||||
@@ -45,13 +46,15 @@ void ValidateOperation::operator() (GraphicsContext* gc)
|
|||||||
}
|
}
|
||||||
|
|
||||||
Technique::Technique(bool alwaysValid)
|
Technique::Technique(bool alwaysValid)
|
||||||
: _alwaysValid(alwaysValid), _glVersion(1.1f)
|
: _alwaysValid(alwaysValid), _contextIdLocation(-1)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
Technique::Technique(const Technique& rhs, const osg::CopyOp& copyop) :
|
Technique::Technique(const Technique& rhs, const osg::CopyOp& copyop) :
|
||||||
_contextMap(rhs._contextMap), _alwaysValid(rhs._alwaysValid),
|
_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 std;
|
||||||
using namespace boost;
|
using namespace boost;
|
||||||
@@ -81,8 +84,12 @@ Technique::Status Technique::valid(osg::RenderInfo* renderInfo)
|
|||||||
return contextInfo.valid();
|
return contextInfo.valid();
|
||||||
}
|
}
|
||||||
ref_ptr<ValidateOperation> validOp = new ValidateOperation(this);
|
ref_ptr<ValidateOperation> validOp = new ValidateOperation(this);
|
||||||
renderInfo->getState()->getGraphicsContext()->getGraphicsThread()
|
GraphicsContext* context = renderInfo->getState()->getGraphicsContext();
|
||||||
->add(validOp.get());
|
GraphicsThread* thread = context->getGraphicsThread();
|
||||||
|
if (thread)
|
||||||
|
thread->add(validOp.get());
|
||||||
|
else
|
||||||
|
context->add(validOp.get());
|
||||||
return newStatus;
|
return newStatus;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -96,10 +103,13 @@ Technique::Status Technique::getValidStatus(const RenderInfo* renderInfo) const
|
|||||||
|
|
||||||
void Technique::validateInContext(GraphicsContext* gc)
|
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 oldVal = contextInfo.valid();
|
||||||
Status newVal = INVALID;
|
Status newVal = INVALID;
|
||||||
if (getGLVersionNumber() >= _glVersion)
|
expression::FixedLengthBinding<1> binding;
|
||||||
|
binding.getBindings()[_contextIdLocation].val.intVal = contextId;
|
||||||
|
if (_validExpression->getValue(&binding))
|
||||||
newVal = VALID;
|
newVal = VALID;
|
||||||
contextInfo.valid.compareAndSwap(oldVal, newVal);
|
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)
|
bool Technique_writeLocalData(const Object& obj, osgDB::Output& fw)
|
||||||
{
|
{
|
||||||
const Technique& tniq = static_cast<const Technique&>(obj);
|
const Technique& tniq = static_cast<const Technique&>(obj);
|
||||||
fw.indent() << "alwaysValid "
|
fw.indent() << "alwaysValid "
|
||||||
<< (tniq.getAlwaysValid() ? "TRUE\n" : "FALSE\n");
|
<< (tniq.getAlwaysValid() ? "TRUE\n" : "FALSE\n");
|
||||||
|
#if 0
|
||||||
fw.indent() << "glVersion " << tniq.getGLVersion() << "\n";
|
fw.indent() << "glVersion " << tniq.getGLVersion() << "\n";
|
||||||
|
#endif
|
||||||
if (tniq.getShadowingStateSet()) {
|
if (tniq.getShadowingStateSet()) {
|
||||||
fw.indent() << "shadowingStateSet\n";
|
fw.indent() << "shadowingStateSet\n";
|
||||||
fw.writeObject(*tniq.getShadowingStateSet());
|
fw.writeObject(*tniq.getShadowingStateSet());
|
||||||
|
|||||||
@@ -20,6 +20,7 @@
|
|||||||
#include "EffectGeode.hxx"
|
#include "EffectGeode.hxx"
|
||||||
|
|
||||||
#include <simgear/structure/SGAtomic.hxx>
|
#include <simgear/structure/SGAtomic.hxx>
|
||||||
|
#include <simgear/structure/SGExpression.hxx>
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
@@ -90,13 +91,12 @@ public:
|
|||||||
void setShadowingStateSet(osg::StateSet* ss) { _shadowingStateSet = ss; }
|
void setShadowingStateSet(osg::StateSet* ss) { _shadowingStateSet = ss; }
|
||||||
virtual void resizeGLObjectBuffers(unsigned int maxSize);
|
virtual void resizeGLObjectBuffers(unsigned int maxSize);
|
||||||
virtual void releaseGLObjects(osg::State* state = 0) const;
|
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; }
|
bool getAlwaysValid() const { return _alwaysValid; }
|
||||||
void setAlwaysValid(bool val) { _alwaysValid = val; }
|
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:
|
protected:
|
||||||
// Validity of technique in a graphics context.
|
// Validity of technique in a graphics context.
|
||||||
struct ContextInfo : public osg::Referenced
|
struct ContextInfo : public osg::Referenced
|
||||||
@@ -113,7 +113,8 @@ protected:
|
|||||||
mutable ContextMap _contextMap;
|
mutable ContextMap _contextMap;
|
||||||
bool _alwaysValid;
|
bool _alwaysValid;
|
||||||
osg::ref_ptr<osg::StateSet> _shadowingStateSet;
|
osg::ref_ptr<osg::StateSet> _shadowingStateSet;
|
||||||
float _glVersion;
|
SGSharedPtr<SGExpressionb> _validExpression;
|
||||||
|
int _contextIdLocation;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -29,6 +29,8 @@
|
|||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
#include <vector>
|
||||||
|
#include<string>
|
||||||
|
|
||||||
#include "mat.hxx"
|
#include "mat.hxx"
|
||||||
|
|
||||||
@@ -312,7 +314,8 @@ SGMaterial::build_state( bool defer_tex_load )
|
|||||||
}
|
}
|
||||||
|
|
||||||
_status[i].state = pass;
|
_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);
|
tniq->passes.push_back(pass);
|
||||||
Effect* effect = new Effect;
|
Effect* effect = new Effect;
|
||||||
effect->techniques.push_back(tniq);
|
effect->techniques.push_back(tniq);
|
||||||
|
|||||||
Reference in New Issue
Block a user