OpenGL 模板缓冲区stencil到底如何使用?

在写模板缓冲OpenGL相关的API时,看了半天帖子都没有搞清楚模板缓冲区到底是什么时候写入值的。
下面总结一下。

模板缓冲区的理解

模板测试

在OpenGL中,模板测试(Stencil Testing)是一种用于控制像素绘制的方式。它允许开发者根据模板缓冲区(Stencil Buffer)中的值来决定是否绘制某个像素。模板测试通常用于实现一些高级的图形效果,如阴影、反射、折射等。

模板缓冲区

我们怎么填充模板缓冲区?

如果我们想在模板缓冲区中将一块矩形区域填充为1,那们我需要“绘制一个矩形”,并进行以下操作。

glStencilFunc(GL_ALWAYS,1,0XFF);
glStencilOp(GL_KEEP,GL_KEEP,GL_REPLACE);
glStencilMask(0xFF)

通过将glStencilFunc的第一个参数设置为GL_ALWAYS,使得任意模板值都能通过测试,这样如果深度测试也通过的话,就会通过glStencilOp的第三个参数设置的GL_REPLACE将模板值都替换为glStencilFunc的第二个参数。这样一来,我们就达到了在规定区域中将模板值设置为1的目的。glStencilMask(0xFF)的作用是设置模板缓冲区的写入掩码。0xFF表示所有位都可以被写入。在这个例子中,0xFF表示所有位都可以被写入。
而矩形并不需要真正的绘制,它只是用来指定哪些像素有效,哪些无效。怎么做到这个矩形没有被真正的绘制呢?用的是下面这段代码来屏蔽颜色和深度缓存。

glColorMask(GL_FALSE,GL_FALSE,GL_FALSE,FL_FALSE);
glDepthMask(GL_FALSE);

glColorMask函数允许你指定哪些数据输入颜色缓存,4个参数分别对应RGBA值,这里我们将4个参数都置为GL_FALSE,意味着所有颜色数据都不会输入到颜色缓存中。而深度缓存需要另外调用glDepthMask并传入GL_FALSE参数来屏蔽深度值。这样我们矩形区域外的所有像素的颜色和深度都被屏蔽了,所以我们的绘制就不会影响到这些像素。

怎么应用模板缓冲区

由上面得到的模板缓冲区中已经有一个矩形区域被设置为1了,如下图所示。

在这里插入图片描述
那我们应该如何应用这个缓冲区呢?
如果我想只有在这个绘制的矩形范围内,能够被出图,也就是裁剪功能,那我们可以通过设置如下测试函数来进行绘制,并且记住要将之前禁用的深度和颜色绘制重新启用。

glStencilFunc(GL_EQUAL,1,0xFF);

但需要注意的是,此时无论我们想在屏幕上绘制什么,我们并不需要我们的模板缓冲区被更新了,所以我们需要将模板缓冲区写入的掩码设置为0,这样,我们对模板缓冲区的任何写入操作都会被屏幕。

glStencilMask(0x00);

模板缓冲区为什么需要更新?

由“我们怎么填充模板缓冲区?”这一节可以看出,更新模板缓冲区可以直接通过绘制来填充模板缓冲区。

一段简单的裁剪例子

glEnable(GL_STENCIL_TEST);
glStencilFunc(GL_ALWAYS,1,0XFF);
glStencilOp(GL_KEEP,GL_KEEP,GL_REPLACE);
glStencilMask(0xFF);
glDepthMask(GL_FALSE);
glColorMask(GL_FALSE,GL_FALSE,GL_FALSE,FL_FALSE);
glClear(GL_STENCIL_BUFFER_BIT);

glDrawArrays(GL_TRIANGLES,0,6);

glStencilFunc(GL_EQUAL,1,0xFF);
glStencilMask(0x00);
glDepthMask(GL_TRUE);
glColorMask(GL_TRUE,GL_TRUE,GL_TRUE,GL_TRUE);

glDrawArrays(GL_TRIANGLES,6,3);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值