OpenGL学习笔记十三(模板测试)

需要模板测试的原因

在上节中,讲了深度测试,即
判断一个像素点是否能通过深度检测,显示到屏幕上,但是在实际开发中,我们可能遇到很多
需求,希望实现不是通过深度关系进行遮挡的,比如游戏里常见的透视效果,可以看到一个物体之后的东西,这种情况下,我们就不能仅仅使用深度测试就能实现,需要其他的测试方式——模板测试,通过模板测试,可以实现更多更有意思的效果。

模板测试

模板测试和深度测试一样,都是为了挑选像素点并按照自己定义的比较函数实现想要的效果
模板测试先于深度测试执行,模板缓存精度只有八位,即只能存256以内的数,不像深度缓冲那样高的精度,因此使用的存储空间更小。

模板缓存

模板缓冲和深度缓冲一样是一个二维数组,用于保存对应的像素点的模板值,我们可以设置某个点的模板值,与当前缓冲区中的模板值作比较,通过则显示该点,不通过则不进行渲染。
图片选自LearnOpenGL
模板缓冲首先会被清除为0,之后在模板缓冲中使用1填充了一个空心矩形。场景中的片段将会只在片段的模板值为1的时候会被渲染(其它的都被丢弃了)。

模板测试函数

开启模板测试

glEnable(GL_STENCIL_TEST);

模板缓存写入函数开关

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

glStencilMask允许我们设置一个位掩码(Bitmask),它会与将要写入缓冲的模板值进行与(AND)运算。默认情况下设置的位掩码所有位都为1,不影响输出,但如果我们将它设置为0x00,写入缓冲的所有模板值最后都会变成0

模板测试比较函数

一共有两个函数能够用来配置模板测试:glStencilFunc和glStencilOp。

glStencilFunc

glStencilFunc(GLenum func, GLint ref, GLuint mask)一共包含三个参数:

  • func:设置模板测试函数(Stencil Test Function)。这个测试函数将会应用到已储存的模板值上和glStencilFunc函数的ref值上。可用的选项有:GL_NEVER、GL_LESS、GL_LEQUAL、GL_GREATER、GL_GEQUAL、GL_EQUAL、GL_NOTEQUAL和GL_ALWAYS。它们的语义和深度缓冲的函数类似。
  • ref:设置了模板测试的参考值(Reference Value)。模板缓冲的内容将会与这个值进行比较。
  • mask:设置一个掩码,它将会与参考值和储存的模板值在测试比较它们之前进行与(AND)运算。初始情况下所有位都为1。

glStencilOp

glStencilOp(GLenum sfail, GLenum dpfail, GLenum dppass)一共包含三个选项,我们能够设定每个选项应该采取的行为:

  • sfail:模板测试失败时采取的行为。
  • dpfail:模板测试通过,但深度测试失败时采取的行为。
  • dppass:模板测试和深度测试都通过时采取的行为。
行为 描述
GL_KEEP 保持当前储存的模板值
GL_ZERO 将模板值设置为0
GL_REPLACE 将模板值设置为glStencilFunc函数设置的ref值
GL_INCR 如果模板值小于最大值则将模板值加1
GL_INCR_WRAP 与GL_INCR一样,但如果模板值超过了最大值则归零
GL_DECR 如果模板值大于最小值则将模板值减1
GL_DECR_WRAP 与GL_DECR一样,但如果模板值小于0则将其设置为最大值
GL_INVERT 按位翻转当前的模板缓冲值

清空缓存内容

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
发布了61 篇原创文章 · 获赞 225 · 访问量 4万+

猜你喜欢

转载自blog.csdn.net/qq_36696486/article/details/104387802