QT之OpenGL模板测试

1. 概述

当片段着色器处理完一个片段之后,模板测试(Stencil Test)会开始执行,和深度测试一样,它可能会丢弃片段。被保留下来的片段会进入深度测试。

一个模板缓冲中,(通常)每个模板值(Stencil Value)是8位的。所以每个像素/片段一共能有256种不同的模板值。我们可以将这些模板值设置为我们想要的值,然后当某一个片段有某一个模板值的时候,我们就可以选择丢弃或是保留这个片段了。

模板缓冲示意图:
在这里插入图片描述
模板缓冲中1的部分最后会被渲染出来,最终效果为一个

2. 使用步骤及函数介绍

  • 开启模板缓冲
glEnable(GL_STENCIL_TEST);
  • 每一帧时清空模板缓冲
// GL_STENCIL_BUFFER_BIT 这个就表示要清除模板缓冲
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
  • 设置模板缓冲掩码
// 这里的掩码是表示允不允许向模板缓冲中写入数据
glStencilMask(0xFF); // 允许所有位写入
glStencilMask(0x00); // 不允许所有位写入
  • 模板函数
/*
这个函数仅仅告诉OpenGL应该对模板缓冲中的内容做什么行为的操作,而不是应该如何更新缓冲
func:指定具体的行为 GL_NEVER、GL_LESS、GL_LEQUAL、GL_GREATER、GL_GEQUAL、GL_EQUAL、GL_NOTEQUAL和GL_ALWAYS
ref:表示func行为的参考值,如GL_EQUAL 则表示模板缓冲中的值等于 ref 时进行绘制,否则丢弃
mask:设置屏蔽位的,它会将ref值和模板缓冲中的值进行与运算后再使其比较,默认为0xFF
*/
glStencilFunc(GLenum func, GLint ref, GLuint mask)

/*
这个函数则指定应该如何更新模板缓冲的值,默认情况下均为 GL_KEEP
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(GLenum sfail, GLenum dpfail, GLenum dppass)

3. Demo

Demo中模仿OpenGL中的模型增加外边框的操作,核心步骤:

  1. 开启模板测试
    glEnable(GL_STENCIL_TEST);
    
  2. 指定如何更新模板缓冲区的值
    glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
    
  3. 每帧情况模板测试缓冲并设置缓冲只读
    // 使用
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
    // 不允许向模板缓冲区写入值
    glStencilMask(0x00);
    
  4. 第一次绘制模型前,设置对缓冲区进行的操作
    // 告诉OpenGL应该对模板缓冲中所有片段进行绘制,同时在通过模板测试及深度测试后模板缓冲区的内容会被替换成1(被替换的操作是由glStencilOp指定的,替换的值则是由glStencilFunc给定)
    glStencilFunc(GL_ALWAYS, 1, 0xFF);
    // 允许向模板缓冲区写入值
    glStencilMask(0xFF);
    
  5. 指定第二次绘制时对缓冲区的操作
    // 绘制不等于1的区域,由于第二次会模型会被放大,所以被放大的那一部分会被绘制
    glStencilFunc(GL_NOTEQUAL, 1, 0xFF);
    

模板测试Demo

4. 参考

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值