+
+struct PolygonOffsetBuilder : public PassAttributeBuilder
+{
+ void buildAttribute(Effect* effect, Pass* pass, const SGPropertyNode* prop,
+ const SGReaderWriterOptions* options)
+ {
+ if (!isAttributeActive(effect, prop))
+ return;
+
+ const SGPropertyNode* factor
+ = getEffectPropertyChild(effect, prop, "factor");
+ const SGPropertyNode* units
+ = getEffectPropertyChild(effect, prop, "units");
+
+ ref_ptr<PolygonOffset> polyoffset = new PolygonOffset;
+
+ polyoffset->setFactor(factor->getFloatValue());
+ polyoffset->setUnits(units->getFloatValue());
+
+ SG_LOG(SG_INPUT, SG_BULK,
+ "Set PolygonOffset to " << polyoffset->getFactor() << polyoffset->getUnits() );
+
+ pass->setAttributeAndModes(polyoffset.get(),
+ StateAttribute::OVERRIDE|StateAttribute::ON);
+ }
+};
+
+InstallAttributeBuilder<PolygonOffsetBuilder> installPolygonOffset("polygon-offset");
+
+struct VertexProgramTwoSideBuilder : public PassAttributeBuilder
+{
+ void buildAttribute(Effect* effect, Pass* pass, const SGPropertyNode* prop,
+ const SGReaderWriterOptions* options)
+ {
+ const SGPropertyNode* realProp = getEffectPropertyNode(effect, prop);
+ if (!realProp)
+ return;
+ pass->setMode(GL_VERTEX_PROGRAM_TWO_SIDE,
+ (realProp->getValue<bool>()
+ ? StateAttribute::ON : StateAttribute::OFF));
+ }
+};
+
+InstallAttributeBuilder<VertexProgramTwoSideBuilder>
+installTwoSide("vertex-program-two-side");
+
+struct VertexProgramPointSizeBuilder : public PassAttributeBuilder
+{
+ void buildAttribute(Effect* effect, Pass* pass, const SGPropertyNode* prop,
+ const SGReaderWriterOptions* options)
+ {
+ const SGPropertyNode* realProp = getEffectPropertyNode(effect, prop);
+ if (!realProp)
+ return;
+ pass->setMode(GL_VERTEX_PROGRAM_POINT_SIZE,
+ (realProp->getValue<bool>()
+ ? StateAttribute::ON : StateAttribute::OFF));
+ }
+};
+
+InstallAttributeBuilder<VertexProgramPointSizeBuilder>
+installPointSize("vertex-program-point-size");
+
+EffectNameValue<Depth::Function> depthFunctionInit[] =
+{
+ {"never", Depth::NEVER},
+ {"less", Depth::LESS},
+ {"equal", Depth::EQUAL},
+ {"lequal", Depth::LEQUAL},
+ {"greater", Depth::GREATER},
+ {"notequal", Depth::NOTEQUAL},
+ {"gequal", Depth::GEQUAL},
+ {"always", Depth::ALWAYS}
+};
+EffectPropertyMap<Depth::Function> depthFunction(depthFunctionInit);
+
+struct DepthBuilder : public PassAttributeBuilder
+{
+ void buildAttribute(Effect* effect, Pass* pass, const SGPropertyNode* prop,
+ const SGReaderWriterOptions* options)
+ {
+ if (!isAttributeActive(effect, prop))
+ return;
+ ref_ptr<Depth> depth = new Depth;
+ const SGPropertyNode* pfunc
+ = getEffectPropertyChild(effect, prop, "function");
+ if (pfunc) {
+ Depth::Function func = Depth::LESS;
+ findAttr(depthFunction, pfunc, func);
+ depth->setFunction(func);
+ }
+ const SGPropertyNode* pnear
+ = getEffectPropertyChild(effect, prop, "near");
+ if (pnear)
+ depth->setZNear(pnear->getValue<double>());
+ const SGPropertyNode* pfar
+ = getEffectPropertyChild(effect, prop, "far");
+ if (pfar)
+ depth->setZFar(pfar->getValue<double>());
+ const SGPropertyNode* pmask
+ = getEffectPropertyChild(effect, prop, "write-mask");
+ if (pmask)
+ depth->setWriteMask(pmask->getValue<bool>());
+ const SGPropertyNode* penabled
+ = getEffectPropertyChild(effect, prop, "enabled");
+ bool enabled = ( penabled == 0 || penabled->getBoolValue() );
+ pass->setAttributeAndModes(depth.get(), enabled ? osg::StateAttribute::ON : osg::StateAttribute::OFF);
+ }
+};
+
+InstallAttributeBuilder<DepthBuilder> installDepth("depth");
+