From acf19cebf8d3f7f59b52c4fadda8ab8612f068cb Mon Sep 17 00:00:00 2001 From: Tim Moore Date: Fri, 29 Jan 2010 19:07:53 +0100 Subject: [PATCH] Stencil operations for effects From Lauri Peltonen --- simgear/scene/material/Effect.cxx | 112 ++++++++++++++++++++++++++++++ 1 file changed, 112 insertions(+) diff --git a/simgear/scene/material/Effect.cxx b/simgear/scene/material/Effect.cxx index 940b1f18..9da202f7 100644 --- a/simgear/scene/material/Effect.cxx +++ b/simgear/scene/material/Effect.cxx @@ -51,6 +51,7 @@ #include #include #include +#include #include #include #include @@ -253,6 +254,24 @@ struct CullFaceBuilder : PassAttributeBuilder InstallAttributeBuilder installCullFace("cull-face"); +struct ColorMaskBuilder : PassAttributeBuilder +{ + void buildAttribute(Effect* effect, Pass* pass, const SGPropertyNode* prop, + const osgDB::ReaderWriter::Options* options) + { + const SGPropertyNode* realProp = getEffectPropertyNode(effect, prop); + if (!realProp) + return; + + ColorMask *mask = new ColorMask; + Vec4 m = getColor(realProp); + mask->setMask(m.r(), m.g(), m.b(), m.a()); + pass->setAttributeAndModes(mask); + } +}; + +InstallAttributeBuilder installColorMask("color-mask"); + EffectNameValue renderingHintInit[] = { { "default", StateSet::DEFAULT_BIN }, @@ -475,6 +494,99 @@ struct BlendBuilder : public PassAttributeBuilder InstallAttributeBuilder installBlend("blend"); + +EffectNameValue stencilFunctionInit[] = +{ + {"never", Stencil::NEVER }, + {"less", Stencil::LESS}, + {"equal", Stencil::EQUAL}, + {"less-or-equal", Stencil::LEQUAL}, + {"greater", Stencil::GREATER}, + {"not-equal", Stencil::NOTEQUAL}, + {"greater-or-equal", Stencil::GEQUAL}, + {"always", Stencil::ALWAYS} +}; + +EffectPropertyMap stencilFunction(stencilFunctionInit); + +EffectNameValue stencilOperationInit[] = +{ + {"keep", Stencil::KEEP}, + {"zero", Stencil::ZERO}, + {"replace", Stencil::REPLACE}, + {"increase", Stencil::INCR}, + {"decrease", Stencil::DECR}, + {"invert", Stencil::INVERT}, + {"increase-wrap", Stencil::INCR_WRAP}, + {"decrease-wrap", Stencil::DECR_WRAP} +}; + +EffectPropertyMap stencilOperation(stencilOperationInit); + +struct StencilBuilder : public PassAttributeBuilder +{ + void buildAttribute(Effect* effect, Pass* pass, const SGPropertyNode* prop, + const osgDB::ReaderWriter::Options* options) + { + if (!isAttributeActive(effect, prop)) + return; + + const SGPropertyNode* pmode = getEffectPropertyChild(effect, prop, + "mode"); + if (pmode && !pmode->getValue()) { + pass->setMode(GL_STENCIL, StateAttribute::OFF); + return; + } + const SGPropertyNode* pfunction + = getEffectPropertyChild(effect, prop, "function"); + const SGPropertyNode* pvalue + = getEffectPropertyChild(effect, prop, "value"); + const SGPropertyNode* pmask + = getEffectPropertyChild(effect, prop, "mask"); + const SGPropertyNode* psfail + = getEffectPropertyChild(effect, prop, "stencil-fail"); + const SGPropertyNode* pzfail + = getEffectPropertyChild(effect, prop, "z-fail"); + const SGPropertyNode* ppass + = getEffectPropertyChild(effect, prop, "pass"); + + Stencil::Function func = Stencil::ALWAYS; // Always pass + int ref = 0; + unsigned int mask = ~0u; // All bits on + Stencil::Operation sfailop = Stencil::KEEP; // Keep the old values as default + Stencil::Operation zfailop = Stencil::KEEP; + Stencil::Operation passop = Stencil::KEEP; + + ref_ptr stencilFunc = new Stencil; + + if (pfunction) + findAttr(stencilFunction, pfunction, func); + if (pvalue) + ref = pvalue->getIntValue(); + if (pmask) + mask = pmask->getIntValue(); + + if (psfail) + findAttr(stencilOperation, psfail, sfailop); + if (pzfail) + findAttr(stencilOperation, pzfail, zfailop); + if (ppass) + findAttr(stencilOperation, ppass, passop); + + // Set the stencil operation + stencilFunc->setFunction(func, ref, mask); + + // Set the operation, s-fail, s-pass/z-fail, s-pass/z-pass + stencilFunc->setOperation(sfailop, zfailop, passop); + + // Add the operation to pass + pass->setAttributeAndModes(stencilFunc.get()); + } +}; + +InstallAttributeBuilder installStencil("stencil"); + + EffectNameValue alphaComparisonInit[] = { {"never", AlphaFunc::NEVER}, -- 2.39.5