5 Stencil Testing
文本统计:约 334 个字 • 32 行代码
glStencilMask
是模板测试的位掩码,它会与将要写入缓冲的模板值进行与(AND)运算。主要使用的位掩码有 0x00
与 0xFF
接下来要进行的就是模板测试,一共有两个函数可以用来配置模板测试 glStencilFunc
与 glStencilOp
前者是用于判断是否通过缓冲测试,后者用于更新模板值
glStencilFunc
的参数包含了
- 模板测试函数,比如说
GL_NEVER
、GL_LESS
、GL_LEQUAL
、GL_GREATER
、GL_GEQUAL
、GL_EQUAL
、GL_NOTEQUAL
和GL_ALWAYS
- 参考值,模板测试的参考值
- 掩码,在测试之前,对参考值以及现有的模板值都做 AND 运算
glStencilOp
则描述了各个情况对模板缓冲的写入情况
glStencilOp(GLenum sfail, GLenum dpfail, GLenum dppass)
一共包含三个选项,我们能够设定每个选项应该采取的行为:
sfail
:模板测试失败时采取的行为。dpfail
:模板测试通过,但深度测试失败时采取的行为。dppass
:模板测试和深度测试都通过时采取的行为。
本次教程中完成的是绘制物体边框的工作,代码大致如下所示
//启动深度测试
glEnable(GL_DEPTH_TEST);
//只有在深度测试与模板测试都通过的情况下才会改变模板缓冲
glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
//清除当前所有缓冲
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
//设置掩码为零,就算通过了模板测试与深度测试,依然无法改变模板缓冲中的值
glStencilMask(0x00); // 记得保证我们在绘制地板的时候不会更新模板缓冲
normalShader.use();
DrawFloor()
//现在模板缓冲中的值依然全部都是0
//设置一直通过模板缓冲,并且由于参考是为1,行为是GL_REPLACE,于是通过深度测试的部分就会在模板缓冲中记录为1
glStencilFunc(GL_ALWAYS, 1, 0xFF);
//会改变模板缓冲中的值
glStencilMask(0xFF);
DrawTwoContainers();
//设置通过模板缓冲的条件是模板缓冲中的值不为1
glStencilFunc(GL_NOTEQUAL, 1, 0xFF);
//不改变模板缓冲中的值
glStencilMask(0x00);
//取消深度缓冲
glDisable(GL_DEPTH_TEST);
shaderSingleColor.use();
//绘制略微放大的正方体,并且染成绿色
DrawTwoScaledUpContainers();
//恢复默认的
glStencilMask(0xFF);
glEnable(GL_DEPTH_TEST);