#include "Technique.hxx"
#include "Pass.hxx"
#include "TextureBuilder.hxx"
+#include "parseBlendFunc.hxx"
#include <algorithm>
#include <functional>
pass->setMode(GL_BLEND, StateAttribute::OFF);
return;
}
- const SGPropertyNode* psource
- = getEffectPropertyChild(effect, prop, "source");
- const SGPropertyNode* pdestination
- = getEffectPropertyChild(effect, prop, "destination");
- const SGPropertyNode* psourceRGB
- = getEffectPropertyChild(effect, prop, "source-rgb");
- const SGPropertyNode* psourceAlpha
- = getEffectPropertyChild(effect, prop, "source-alpha");
- const SGPropertyNode* pdestRGB
- = getEffectPropertyChild(effect, prop, "destination-rgb");
- const SGPropertyNode* pdestAlpha
- = getEffectPropertyChild(effect, prop, "destination-alpha");
- BlendFunc::BlendFuncMode sourceMode = BlendFunc::ONE;
- BlendFunc::BlendFuncMode destMode = BlendFunc::ZERO;
- if (psource)
- findAttr(blendFuncModes, psource, sourceMode);
- if (pdestination)
- findAttr(blendFuncModes, pdestination, destMode);
- if (psource && pdestination
- && !(psourceRGB || psourceAlpha || pdestRGB || pdestAlpha)
- && sourceMode == BlendFunc::SRC_ALPHA
- && destMode == BlendFunc::ONE_MINUS_SRC_ALPHA) {
- pass->setAttributeAndModes(StateAttributeFactory::instance()
- ->getStandardBlendFunc());
- return;
- }
- BlendFunc* blendFunc = new BlendFunc;
- if (psource)
- blendFunc->setSource(sourceMode);
- if (pdestination)
- blendFunc->setDestination(destMode);
- if (psourceRGB) {
- BlendFunc::BlendFuncMode sourceRGBMode;
- findAttr(blendFuncModes, psourceRGB, sourceRGBMode);
- blendFunc->setSourceRGB(sourceRGBMode);
- }
- if (pdestRGB) {
- BlendFunc::BlendFuncMode destRGBMode;
- findAttr(blendFuncModes, pdestRGB, destRGBMode);
- blendFunc->setDestinationRGB(destRGBMode);
- }
- if (psourceAlpha) {
- BlendFunc::BlendFuncMode sourceAlphaMode;
- findAttr(blendFuncModes, psourceAlpha, sourceAlphaMode);
- blendFunc->setSourceAlpha(sourceAlphaMode);
- }
- if (pdestAlpha) {
- BlendFunc::BlendFuncMode destAlphaMode;
- findAttr(blendFuncModes, pdestAlpha, destAlphaMode);
- blendFunc->setDestinationAlpha(destAlphaMode);
- }
- pass->setAttributeAndModes(blendFunc);
+
+ parseBlendFunc(
+ pass,
+ getEffectPropertyChild(effect, prop, "source"),
+ getEffectPropertyChild(effect, prop, "destination"),
+ getEffectPropertyChild(effect, prop, "source-rgb"),
+ getEffectPropertyChild(effect, prop, "destination-rgb"),
+ getEffectPropertyChild(effect, prop, "source-alpha"),
+ getEffectPropertyChild(effect, prop, "destination-alpha")
+ );
}
};
InstallAttributeBuilder<StencilBuilder> installStencil("stencil");
+struct AlphaToCoverageBuilder : public PassAttributeBuilder
+{
+ void buildAttribute(Effect* effect, Pass* pass, const SGPropertyNode* prop,
+ const SGReaderWriterOptions* options);
+};
+
+#ifndef GL_SAMPLE_ALPHA_TO_COVERAGE_ARB
+#define GL_SAMPLE_ALPHA_TO_COVERAGE_ARB 0x809E
+#endif
+
+void AlphaToCoverageBuilder::buildAttribute(Effect* effect, Pass* pass,
+ const SGPropertyNode* prop,
+ const SGReaderWriterOptions* options)
+{
+ const SGPropertyNode* realProp = getEffectPropertyNode(effect, prop);
+ if (!realProp)
+ return;
+ pass->setMode(GL_SAMPLE_ALPHA_TO_COVERAGE_ARB, (realProp->getValue<bool>() ?
+ StateAttribute::ON : StateAttribute::OFF));
+}
+
+InstallAttributeBuilder<AlphaToCoverageBuilder> installAlphaToCoverage("alpha-to-coverage");
EffectNameValue<AlphaFunc::ComparisonFunction> alphaComparisonInit[] =
{
"comparison");
const SGPropertyNode* pRef = getEffectPropertyChild(effect, prop,
"reference");
+
AlphaFunc::ComparisonFunction func = AlphaFunc::ALWAYS;
float refValue = 1.0f;
if (pComp)
class PropertyExpression : public SGExpression<T>
{
public:
- PropertyExpression(SGPropertyNode* pnode) : _pnode(pnode) {}
+ PropertyExpression(SGPropertyNode* pnode) : _pnode(pnode), _listener(NULL) {}
+
+ ~PropertyExpression()
+ {
+ delete _listener;
+ }
void eval(T& value, const expression::Binding*) const
{
value = _pnode->getValue<T>();
}
+
+ void setListener(SGPropertyChangeListener* l)
+ {
+ _listener = l;
+ }
protected:
SGPropertyNode_ptr _pnode;
+ SGPropertyChangeListener* _listener;
};
class EffectPropertyListener : public SGPropertyChangeListener
if (_tniq.valid())
_tniq->refreshValidity();
}
+
+ virtual ~EffectPropertyListener() { }
+
protected:
osg::observer_ptr<Technique> _tniq;
};
PropertyExpression<T>* pexp = new PropertyExpression<T>(pnode);
TechniquePredParser* predParser
= dynamic_cast<TechniquePredParser*>(parser);
- if (predParser)
- pnode->addChangeListener(new EffectPropertyListener(predParser
- ->getTechnique()));
+ if (predParser) {
+ EffectPropertyListener* l = new EffectPropertyListener(predParser
+ ->getTechnique());
+ pexp->setListener(l);
+ pnode->addChangeListener(l);
+ }
return pexp;
}