Hi!

The attached patch adds support for stencil operations in effects.
Patches are for simgear's scene/material/Effect.cxx and flightgear's
Main/CameraGroup.cxx. I did them with "cvs diff <file>" against latest
CVS version. Hope that is correct way.


The format of stencil operations in effect file is following:
<stencil>
  <function>...</function>
  <value>...</value>
  <mask>...</mask>
  <stencil-fail>...</stencil-fail>
  <z-fail>...</z-fail>
  <pass>...</pass>
</stencil>

Where function can be never, always, less, less-or-equal, equal,
not-equal, greater-or-equal or greater.

Value is the reference value used in stencil operations and mask is the
stencil bit mask.

Stencil-fail, z-fail and pass are stencil operations if stencil test
fails or stencil-test passes but z-test fails or both passes. Possible
functions are zero, keep, replace, increase, decrease, invert,
increase-wrap and decrease-wrap.

I think one has to know something about stencil buffers to use this ;)


I also added a new general tag <color-mask type="vec4d">1 0 0
1</color-mask> that allows only writing to certain channel (in this
example only to red and alpha channel.


As an example, I attached new version of the light-cone.eff I posted few
days ago. This one does the same thing but with stencil operations.
The .ac model used with this should be almost transparent or it will be
too bright.

This version has some issue if there is more than 5 light models
simultaneously. I don't know if this is a OSG issue about rendering
orders or something? But please test and comment.

Lauri, a.k.a. Zan
--
Lauri Peltonen
lauri.pelto...@gmail.com
Index: CameraGroup.cxx
===================================================================
RCS file: /var/cvs/FlightGear-0.9/source/src/Main/CameraGroup.cxx,v
retrieving revision 1.18
diff -r1.18 CameraGroup.cxx
157c157
<         camera->setClearMask(GL_DEPTH_BUFFER_BIT);
---
>         camera->setClearMask(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
205c205
<                 camera->setClearMask(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
---
>                 camera->setClearMask(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
216c216
<                 camera->setClearMask(GL_DEPTH_BUFFER_BIT);
---
>                 camera->setClearMask(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
Index: Effect.cxx
===================================================================
RCS file: /var/cvs/SimGear-0.3/source/simgear/scene/material/Effect.cxx,v
retrieving revision 1.29
diff -r1.29 Effect.cxx
53a54
> #include <osg/Stencil>
255a257,274
> 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<ColorMaskBuilder> installColorMask("color-mask");
> 
477a497,589
> 
> EffectNameValue<Stencil::Function> 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<Stencil::Function> stencilFunction(stencilFunctionInit);
> 
> EffectNameValue<Stencil::Operation> 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<Stencil::Operation> 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<bool>()) {
>             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;
> 
>         Stencil *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);
>     }
> };
> 
> InstallAttributeBuilder<StencilBuilder> installStencil("stencil");
> 
> 

Attachment: light-cone.eff
Description: XML document

------------------------------------------------------------------------------
The Planet: dedicated and managed hosting, cloud storage, colocation
Stay online with enterprise data centers and the best network in the business
Choose flexible plans and management services without long-term contracts
Personal 24x7 support from experience hosting pros just a phone call away.
http://p.sf.net/sfu/theplanet-com
_______________________________________________
Flightgear-devel mailing list
Flightgear-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/flightgear-devel

Reply via email to