简体   繁体   English

不要在 Java Android Opengl es 2.0 中使用模板

[英]Do not work stencil in Java Android Opengl es 2.0

In android opengl es 2.0 I'm drawing scene by standard renderer (implements GLSurfaceView.Renderer)在android opengl es 2.0中,我正在通过标准渲染器(实现GLSurfaceView.Renderer)绘制场景

@Override
public void onDrawFrame(GL10 gl10)
{
        GLES20.glEnable(GLES20.GL_STENCIL_TEST);
        GLES20.glClearStencil(1);
        GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT | GLES20.GL_STENCIL_BUFFER_BIT);
        GLES20.glEnable(GLES20.GL_DEPTH_TEST);


        glStencilMask(0x00);

        shaderTexture2.useProgram();

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

        //1 step. draw red triangle
        shaderTexture2.draw(buf_slim, mvp, mLightPosInEyeSpace, tex1);


        GLES20.glStencilFunc(GLES20.GL_NOTEQUAL, 1, 0xFF);
        GLES20.glStencilMask(0x00);

        //2 step. draw blue triangle
        shaderTexture2.draw(buf_big, mvp, mLightPosInEyeSpace, tex1);

        GLES20.glStencilMask(0xFF);

}

If in first line of method turn off stencil (for examle comment GLES20.glEnable(GLES20.GL_STENCIL_TEST); ) then both triangles draws( first pic).If stencil turned on then I'm expect at step 1 that at drawing red triangle stencil buffer will be filled with ones, and at step 2 blue triangle will be cuted only in area where was ones from first step (second pic).如果在方法的第一行关闭模板(例如评论GLES20.glEnable(GLES20.GL_STENCIL_TEST); )然后两个三角形都绘制(第一张图片)。如果模板打开,那么我希望在第 1 步绘制红色三角形模板缓冲区将被填充,并且在第 2 步中,蓝色三角形将仅在第一步(第二张图片)中的区域中被切割。 Instead when stencil turned on simply drawing full red triangle, without any blue triangle (third pic).相反,当模板打开时,只需绘制完整的红色三角形,而没有任何蓝色三角形(第三张图片)。 When and which funcs and masks of stencil I should use to draw as i expect?我应该在何时以及使用哪些模板的 funcs 和掩码来按照我的预期进行绘制?

图片1

图片2

图3

Considering specific statements in the order they are executed...考虑特定语句的执行顺序...

The following code will set every pixel in the stencil buffer to 1.以下代码将模板缓冲区中的每个像素设置为 1。

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

Next the red triangle is rendered.接下来渲染红色三角形。 But the stencil function is setup such that any time the stencil and depth tests pass the value 1 will be written to the stencil buffer.但是模板函数被设置为任何时候模板和深度测试通过值 1 都将被写入模板缓冲区。 That doesn't change anything because the stencil buffer is already filled with 1.这不会改变任何东西,因为模板缓冲区已经填充了 1。

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

// 1 step. draw red triangle
shaderTexture2.draw(buf_slim, mvp, mLightPosInEyeSpace, tex1);

At this point the stencil buffer is still filled with the value 1.此时,模板缓冲区仍填充值 1。

Now the stencil function is setup to pass when the current value is not equal to 1. Hence the stencil test will always fail and no fragments of the blue triangle will be visible.现在模板函数设置为在当前值不等于 1 时通过。因此模板测试将始终失败并且蓝色三角形的片段将不可见。

GLES20.glStencilFunc(GLES20.GL_NOTEQUAL, 1, 0xFF);
GLES20.glStencilMask(0x00);

// 2 step. draw blue triangle
shaderTexture2.draw(buf_big, mvp, mLightPosInEyeSpace, tex1);

The following code (untested) alters things such that 0 is used as the stencil clear value.下面的代码(未经测试)改变了一些东西,使得 0 被用作模板清除值。 The value 1 is written to those stencil pixels covered by the red triangle.值 1 被写入被红色三角形覆盖的那些模板像素。 Finally the blue triangle is rendered only to those pixels that have a corresponding stencil pixel equal to 1.最后,蓝色三角形仅渲染到对应模板像素等于 1 的那些像素。

@Override
public void onDrawFrame (GL10 gl10)
{
    GLES20.glEnable(GLES20.GL_STENCIL_TEST);
    GLES20.glClearStencil(0);
    GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT | GLES20.GL_STENCIL_BUFFER_BIT);
    GLES20.glEnable(GLES20.GL_DEPTH_TEST);

    glStencilMask(0x00);

    shaderTexture2.useProgram();

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

    // 1 step. draw red triangle
    shaderTexture2.draw(buf_slim, mvp, mLightPosInEyeSpace, tex1);

    GLES20.glStencilFunc(GLES20.GL_EQUAL, 1, 0xFF);
    GLES20.glStencilMask(0x00);

    // 2 step. draw blue triangle
    shaderTexture2.draw(buf_big, mvp, mLightPosInEyeSpace, tex1);

    GLES20.glStencilMask(0xFF);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM