OpenGL3.3模板测试

模板测试

模板缓冲的大致理解:

书上的理解 模板缓存可以理解为 将模板缓存想象为有孔洞的硬纸板 将他按在纸面上 再使用喷漆进行喷绘 就可以得到非常精确的图案了 如前面说的 是一个硬纸壳 所以他是相对于屏幕的二维平面 经典用途是模拟骑车的后视镜视角 首先将镜子本身的形状渲染到模板缓存中 然后绘制整个场景 此时模板缓存可以阻止所有在镜子形状之外的绘制操作

模板缓冲目前的理解就是世界中每个片段都可以设置一个模板值 然后根据这个模板值确定这个片段是否需要被显示 比较多应用于边框这种应用中
边框大概的绘制方法:
边框应用的原理是画两次这个模型 第一次绘制的时候把该绘制的片段的模板值变成1 第二次的时候模型画的稍微大一点 然后在所有该绘制的片段中找模板值不是1的地方绘制这样就会形成边框

设置模板测试的位掩码会与缓冲的模板值进行与(and)运算。如果位掩码设置为0x00 则缓冲中的模板值都会变成0 和深度缓冲的glDepthMask(GL_FALSE)是等价的

使用模板测试一般流程是:

glEnable(GL_STENCIL_TEST);//开启模板参数
下面就是开始绘制模板 也就是这个硬纸壳哪里需要被挖一个洞
glStencilFunc(GL_ALWAYS, 1, 0xFF);//设置所有接下来绘制的片段的片段之都为1
glStencilMask(0xFF);//开启模板写入

/这里就是用绘制函数绘制一遍 把相应片元的模板值变化一下 在这里绘制了的片元的模板值都会被写成1/

glStencilFunc(GL_NOTEQUAL, 1, 0xFF);//让接下来该绘制的片段中模板值不等于1的通过测试 也就是不在上面绘制的片元的位置绘制
glStencilMask(0x00);//禁止写入

/这里就正常绘制其他的场景就行了/

在最后再开启写入 glStencilMask(0xFF); 因为如果不开启写入 在每一帧开始的时候glClear(GL_STENCIL_BUFFER_BIT)就没办法清除上一帧的模板缓存

具体函数功能:

glEnable(GL_STENCIL_TEST);函数

开启模板缓冲

glClear(GL_STENCIL_BUFFER_BIT);函数

清除模板缓冲

glStencilMask();函数

和深度测试的glDepthMask类似 设置模板测试的位掩码 默认情况下位掩码所有位都是1
glStencilMask(0xFF); // 每一位写入模板缓冲时都保持原样(启用写入)
glStencilMask(0x00); // 每一位在写入模板缓冲时都会变成0(禁用写入)

glStencilFunc(GLenum func, GLint ref, GLuint mask) 这个函数主要是设置 什么样的模板值可以通过测试

func:设置模板测试函数 这个测试函数将会应用到已储存的模板值上glStencilFunc函数的ref值上。(说白了就是通过设置这个参数 可以知道如何对glStencilFunc函数的ref值和已储存的模板值进行比较)可用的选项有:
(片段模板值就是ref值)
GL_ALWAYS 永远通过模板测试
GL_NEVER 永远不通过模板测试
GL_LESS 在片段模板值小于缓冲的模板值时片元通过测试
GL_EQUAL 在片段模板值等于缓冲区的模板值时通过测试
GL_LEQUAL 在片段模板值小于等于缓冲区的模板值时通过测试
GL_GREATER 在片段模板值大于缓冲区的模板值时通过测试
GL_NOTEQUAL 在片段模板值不等于缓冲区的模板值时通过测试
GL_GEQUAL 在片段模板值大于等于缓冲区的模板值时通过测试
默认情况是GL_LESS 它将会丢弃模板值大于等于当前模板缓冲值的所有片段

它们的语义和深度缓冲的函数类似。
举个例子 如果是GL_LESS 那么当ref比模板缓存中的数值更小时 片元通过测试
ref:设置了模板测试的参考值 模板缓冲的内容将会与这个值进行比较。 如果这里设置为1则如果片段的模板值是1则通过测试被绘制
mask:设置一个掩码,它将会在ref和存储的模板值比较之前和ref进行与(AND)运算。初始情况下所有位都为1。抛弃结果为0的位平面

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 按位翻转当前的模板缓冲值
默认情况下glStencilOp是设置为(GL_KEEP, GL_KEEP, GL_KEEP)

glStencilFuncSeparate(GLenum face,GLenum func, GLint ref, GLuint mask)

就是允许我们为多边形的正背面设置模板

glStencilOpSeparate(GLenum face,GLenum sfail, GLenum dpfail, GLenum dppass)

就是允许我们为多边形的正背面设置模板参数

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值