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

模板测试的文档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

发布了53 篇原创文章 · 获赞 17 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/jklwan/article/details/103875850