#include "Technique.hxx"
#include "Pass.hxx"
+#include "EffectCullVisitor.hxx"
#include <boost/foreach.hpp>
#include <string>
#include <osg/GLExtensions>
+#include <osg/GL2Extensions>
#include <osg/Math>
+#include <osg/Texture2D>
+#include <osg/CopyOp>
#include <osgUtil/CullVisitor>
#include <osgDB/Registry>
}
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)
{
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)
{
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,
expression::ExpParserRegistrar
extensionSupportedRegistrar("extension-supported", extensionSupportedParser);
+class GLShaderLanguageExpression : public GeneralNaryExpression<float, int>
+{
+public:
+ void eval(float& value, const expression::Binding* b) const
+ {
+ value = 0.0f;
+ int contextId = getOperand(0)->getValue(b);
+ GL2Extensions* extensions
+ = GL2Extensions::Get(static_cast<unsigned>(contextId), true);
+ if (!extensions)
+ return;
+ if (!extensions->isGlslSupported())
+ return;
+ value = extensions->getLanguageVersion();
+ }
+};
+
+Expression* shaderLanguageParser(const SGPropertyNode* exp,
+ expression::Parser* parser)
+{
+ GLShaderLanguageExpression* slexp = new GLShaderLanguageExpression;
+ int location = parser->getBindingLayout().addBinding("__contextId",
+ expression::INT);
+ VariableExpression<int>* contextExp = new VariableExpression<int>(location);
+ slexp->addOperand(contextExp);
+ return slexp;
+}
+
+expression::ExpParserRegistrar shaderLanguageRegistrar("shader-language",
+ glVersionParser);
+
+
void Technique::setGLExtensionsPred(float glVersion,
const std::vector<std::string>& extensions)
{