学习OpenGL ES for Android(十九)— 模板测试

本文深入讲解OpenGL中的模板测试,一种用于控制片段是否被绘制的技术。文章详细解释了如何通过GLES20 API启用和配置模板测试,包括设置模板函数、模板操作及模板掩码。通过实例演示了如何利用模板测试实现特定的渲染效果,如仅绘制未被遮挡的区域。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

模板测试的文档https://learnopengl-cn.github.io/04%20Advanced%20OpenGL/02%20Stencil%20testing/,和深度测试类似,它也会丢弃片段。启用模板测试的代码

GLES20.glEnable(GLES20.GL_STENCIL_TEST);

注意:在Android中,只使用这句是无法启用模板测试的,还需要使用下面代码配置GLSurfaceView,因为默认的配置是没有配置模板测试的。

setEGLConfigChooser(8, 8, 8, 8, 16, 8);

在绘制时同样的要清除模板缓冲,

GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT | GLES20.GL_STENCIL_BUFFER_BIT);

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

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

模板函数主要有这两个glStencilFunc和glStencilOp,具体解析请参考文档,glStencilOp一般只设置一次,而glStencilFunc在绘制每个模型前都会设置一次。

现在实现文档中的效果,先绘制地面部分,设置其不会更新模型缓冲;然后绘制两个箱子的部分,将模板缓冲更新为1;随后禁用模板写入以及深度测试;绘制比两个箱子大的纯色物体,绘制方式设置为:如果重叠部分已经有了则不绘制,只绘制不重叠的部分,显示效果像是两个箱子外套了层。关键的代码

    @Override
    public void onSurfaceChanged(GL10 gl, int width, int height) {
        super.onSurfaceChanged(gl, width, height);
        GLES20.glDepthFunc(GLES20.GL_LESS);
        GLES20.glEnable(GLES20.GL_STENCIL_TEST);
        GLES20.glStencilOp(GLES20.GL_KEEP, GLES20.GL_KEEP, GLES20.GL_REPLACE);

        ……
    }
    @Override
    public void onDrawFrame(GL10 gl) {
        GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT | GLES20.GL_STENCIL_BUFFER_BIT);

        // 保证地板不会更新模型缓冲
        GLES20.glStencilFunc(GLES20.GL_NOTEQUAL, 1, 0xFF);
        GLES20.glStencilMask(0x00);
        drawFloor();

        GLES20.glStencilFunc(GLES20.GL_ALWAYS, 1, 0xFF);
        GLES20.glStencilMask(0xFF);
        drawCube();

        GLES20.glStencilFunc(GLES20.GL_NOTEQUAL, 1, 0xFF);
        GLES20.glStencilMask(0x00);
        GLES20.glDisable(GLES20.GL_DEPTH_TEST);
        drawScaleCube();
        GLES20.glStencilMask(0xFF);
        GLES20.glEnable(GLES20.GL_DEPTH_TEST);
    }

显示效果,

本章源码https://github.com/jklwan/OpenGLProject/blob/master/sample/src/main/java/com/chends/opengl/renderer/advanced/opengl/StencilTestingRenderer.java

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值