5 Stencil Testing

文本统计:约 334 个字 • 32 行代码

glStencilMask 是模板测试的位掩码,它会与将要写入缓冲的模板值进行与(AND)运算。主要使用的位掩码有 0x000xFF

glStencilMask(0xFF); // 每一位写入模板缓冲时都保持原样
glStencilMask(0x00); // 每一位在写入模板缓冲时都会变成0(禁用写入)

接下来要进行的就是模板测试,一共有两个函数可以用来配置模板测试 glStencilFuncglStencilOp

前者是用于判断是否通过缓冲测试,后者用于更新模板值

glStencilFunc 的参数包含了

  • 模板测试函数,比如说 GL_NEVERGL_LESSGL_LEQUALGL_GREATERGL_GEQUALGL_EQUALGL_NOTEQUALGL_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);  

评论区

对你有帮助的话请给我个赞和 star => GitHub stars
欢迎跟我探讨!!!