osg.Stencil
是OpenSceneGraph中用于定义模板测试(Stencil test)所需参数的类。Stencil test是一种在绘制对象时根据某种判断条件来限制绘制区域的技术,常常用于实现镜子、阴影、反射等效果。
osg.Stencil
类可以通过设置测试参数、测试操作、算法等来控制Stencil test的行为。
Stencil();
setFunction
void setFunction(GLenum func, GLint ref, GLuint mask);
设置Boolean测试函数的参数。
参数列表:
func
:GLenum类型,测试函数。可选值:GL_NEVER
、GL_LESS
、GL_LEQUAL
、GL_GREATER
、GL_GEQUAL
、GL_EQUAL
、GL_NOTEQUAL
、GL_ALWAYS
。ref
:GLint类型,参考值mask
:GLuint类型,掩码setOperations
void setOperations(GLenum sfail, GLenum dpfail, GLenum dppass);
设置模板(Stencil)测试的操作。
参数列表:
sfail
:GLenum类型,模板测试失败时的操作。可选值:GL_KEEP
、GL_ZERO
、GL_REPLACE
、GL_INCR
、GL_INCR_WRAP
、GL_DECR
、GL_DECR_WRAP
、GL_INVERT
。dpfail
:GLenum类型,模板测试通过,深度测试失败时的操作。取值同 sfail
。dppass
:GLenum类型,模板测试和深度测试都通过时的操作。取值同 sfail
。setWriteMask
void setWriteMask(GLuint mask);
设置Stencil缓冲的写入掩码。
参数列表:
mask
:GLuint类型,写入掩码。默认值为0xFFFFFFFF
。setReferenceValue
void setReferenceValue(GLint ref);
设置参考值。
参数列表:
ref
:GLint类型,参考值。setClearStencil
void setClearStencil(GLint clearval);
设置清除Stencil Buffer时的默认值。
参数列表:
clearval
:GLint类型,Stencil Buffer的默认值。以下代码段展示了如何使用osg.Stencil
类来实现冰面反射的效果:
osg::ref_ptr<osg::Geode> geode = new osg::Geode;
geode->addDrawable(groundplane);
osg::ref_ptr<osg::Group> reflectionGroup = new osg::Group;
// create a mirror reflection texture image from the geode
osg::ref_ptr<osg::TextureRectangle> textureReflect = new osg::TextureRectangle;
reflectionGroup->addChild(geode.get());
reflectSceneGraph(textureReflect.get(), reflectionGroup.get());
osg::ref_ptr<osg::TexGen> tg = new osg::TexGen;
tg->setMode(osg::TexGen::EYE_LINEAR);
tg->setPlane(osg::TexGen::S,
osg::Plane(0.05f, 0.0f, 0.0f, 0.0f));
tg->setPlane(osg::TexGen::T,
osg::Plane(0.0f, 0.05f, 0.0f, 0.0f));
tg->setPlane(osg::TexGen::R,
osg::Plane(0.0f, 0.0f, 0.05f, 0.0f));
tg->setPlane(osg::TexGen::Q,
osg::Plane(0.0f, 0.0f, 0.0f, 1.0f));
osg::ref_ptr<osg::StateSet> stateset = groundplane->getOrCreateStateSet();
stateset->setTextureAttributeAndModes(2, tg.get(), osg::StateAttribute::ON);
stateset->setTextureAttributeAndModes(2, textureReflect.get(), osg::StateAttribute::ON);
stateset->setTextureMode(2, GL_TEXTURE_GEN_S, osg::StateAttribute::ON);
stateset->setTextureMode(2, GL_TEXTURE_GEN_T, osg::StateAttribute::ON);
stateset->setTextureMode(2, GL_TEXTURE_GEN_R, osg::StateAttribute::ON);
stateset->setTextureMode(2, GL_TEXTURE_GEN_Q, osg::StateAttribute::ON);
// set up the stencil buffer
osg::ref_ptr<osg::Stencil> stencil = new osg::Stencil;
stencil->setFunction(GL_ALWAYS, 1, 0xFFFFFFFF);
// does not matter that any pixels drawn with a stencil value of 1
// will be written to the frame buffer, because we
// will later configure the color mask so that nothing gets
// written for this material when writing to the
// color buffer.
stencil->setOperations(GL_KEEP, GL_KEEP, GL_REPLACE);
stencil->setWriteMask(0xFFFFFFFF);
stencil->setReferenceValue(1);
osg::ref_ptr<osg::StateSet> ss = new osg::StateSet;
ss->setAttributeAndModes(stencil.get(), osg::StateAttribute::OVERRIDE | osg::StateAttribute::ON);
ss->setRenderBinDetails(16, "RenderBin");
groundplane->setStateSet(ss.get());
// disable color writes, so they do not update
// the color buffer, but still update the stencil buffer.
osg::ref_ptr<osg::ColorMask> cm = new osg::ColorMask(false, false, false, false);
ss->setAttribute(cm.get(), osg::StateAttribute::OVERRIDE | osg::StateAttribute::ON);
ss->setTextureMode(2, GL_TEXTURE_2D, osg::StateAttribute::OFF);