LeanrnOpenGL 学习笔记----模板测试

75 阅读2分钟

本来一直跟着 LeanrnOpenGL 学习 OpenGl,但是奈何学到高阶的内容总是十分晦涩难懂,看了好几遍文章也看不懂,只能自己找相关的视频和文章。

这次是记录模板测试相关的学习笔记,建议阅读完 LeanrnOpenGL 再看本文,至少相应的函数介绍还是教程里的详细。

模板测试?蒙版测试!我看它就是搞一个遮罩层,从而只显示绘制图形的特定区域

函数说明

对于模板测试,主要只有三个函数:glStencilOp(), glStencilFunc(), glStencilMask()

glStencilOp(GLenum sfail, GLenum dpfail, GLenum dppass) 是用于设定模板/深度测试失败或成功的动作的。这个函数只需要用一次,是不需要反复更改的,类似全局设定的东西。

glStencilFunc(GLenum func, GLint ref, GLuint mask) 则是控制一个接下来 Draw 的图像能不能通过模板测试的。所以在每个 Draw前面都需要有它的设置。

glStencilMask(0xFF/0X00) 是用于允许/阻止对缓冲区的更改,它不会阻止进行模板测试与否。

绘制轮廓

对于背景的绘制,它不能被模块测试丢掉(要被丢也是被深度测试,即前面有物体挡住导致看不到背景),所以对于大部分通过双测试的背景,由于我们默认的是设置是 REPLACE,会用参考值重写模块缓冲区,这不是我们希望的。

所以哪怕它通过测试,它也不能重写缓冲区,由此设置 glStencilMask(0x00);

对于主体的绘制,主体需要正常被展示的同时,还需要将他覆盖的缓冲区设置为 1(此时缓冲区还都是0,需要设置成一个不同的值)。

  • 我们需要允许它修改缓冲区:glStencilMask(0xFF);
  • 我们同时需要它始终通过模块测试,因为只有通过了才能用 REPLACE 操作重写缓冲区,所以设置:glStencilFunc(GL_ALWAYS, 1, 0xFF);

对于轮廓的绘制,轮廓就是主体和一个放大的主体间的不重叠部分。由于刚才小主体的缓冲区都是 1,大主体只需要为 1 的不显示,只显示外边大的一圈就可以了。

  • 所以设置: glStencilFunc(GL_NOTEQUAL, 1, 0xFF); 达成为 1 的不显示
  • 并且因为它是轮廓,我们不需要深度测试:glDisable(GL_DEPTH_TEST);

个人认为,被绘制出来的轮廓部分实际是会改变缓冲区的(即缓冲区为 1 的部分会是大的主体),如果为了模板不被污染,还是要在绘制轮廓前也要设置 glStencilMask(0x00);