【问题标题】:Problems with layers, depth and blending in openGLopenGL 中的层、深度和混合问题
【发布时间】:2010-11-11 14:29:53
【问题描述】:

我需要以分层方式将一些纹理叠加到视频上(即第一个纹理应该出现在下面,当它们都是半透明时,第二个纹理应该出现等)。 纹理都有不同的 Z 值,所以那里不应该有冲突。图片讲了一千个单词,所以我在下面附上了一个:

如您所见,箭头是半透明的,彼此交叉。然而,只有蓝色和红色箭头似乎相互作用。为了论证起见,假设红色箭头的 z(在这种情况下为垂直)值为 4,蓝色为 6,白色为 10。 我正在使用的混合功能是: gl.glBlendFunc(GL.GL_SRC_ALPHA, GL.GL_ONE_MINUS_SRC_ALPHA);GL_DEPTH_TEST 已启用。 我正在寻找与红色和蓝色纹理相同的所有叠加纹理。即,您可以看到白色箭头下方的红色箭头,并且在较暗的 2 个红色箭头交叉的位置显示较深的红色。谁能指出我正确的方向?

编辑:下面是用于为每个帧渲染设置 openGL 的代码。

public void display(final GL gl, final GLProjection projection, final FieldMask fieldMask)
{
    layerTextureShader.updateShader(gl, projection, fieldMask);
    if (useMask)
    {
        layerMaskShader.updateShader(gl, projection, fieldMask);
    }

    gl.glTexEnvf(GL.GL_TEXTURE_ENV, GL.GL_TEXTURE_ENV_MODE, GL.GL_MODULATE);

    gl.glBindBuffer(GL.GL_ARRAY_BUFFER, getVertexBufferObject());
    gl.glBufferData(GL.GL_ARRAY_BUFFER, getNoOfVertices() * 3 * 4, getVertices(), GL.GL_STREAM_DRAW);
    gl.glBindBuffer(GL.GL_ARRAY_BUFFER, 0);

    gl.glBindBuffer(GL.GL_ARRAY_BUFFER, getTexCoordBufferObject());
    gl.glBufferData(GL.GL_ARRAY_BUFFER, getNoOfVertices() * 2 * 4, getTexCoords(), GL.GL_STREAM_DRAW);
    gl.glBindBuffer(GL.GL_ARRAY_BUFFER, 0);

    gl.glBindBuffer(GL.GL_ELEMENT_ARRAY_BUFFER, getIndicesBufferObject());
    gl.glBufferData(GL.GL_ELEMENT_ARRAY_BUFFER, getNoOfIndices() * 4, getIndices(), GL.GL_STREAM_DRAW);
    gl.glBindBuffer(GL.GL_ELEMENT_ARRAY_BUFFER, 0);

    gl.glBindBuffer(GL.GL_ARRAY_BUFFER, getColorBufferObject());
    gl.glBufferData(GL.GL_ARRAY_BUFFER, getNoOfVertices() * 4 * 4, getColors(), GL.GL_STREAM_DRAW);
    gl.glBindBuffer(GL.GL_ARRAY_BUFFER, 0);

    if (useMask)
    {
        gl.glBindBuffer(GL.GL_ARRAY_BUFFER, getMaskColorBufferObject());
        gl.glBufferData(GL.GL_ARRAY_BUFFER, getNoOfVertices() * 4 * 4, getMaskColors(), GL.GL_STREAM_DRAW);
        gl.glBindBuffer(GL.GL_ARRAY_BUFFER, 0);
    }

    gl.glEnable(GL.GL_TEXTURE_2D);
    gl.glActiveTexture(GL.GL_TEXTURE0);
    gl.glBindTexture(GL.GL_TEXTURE_2D, textureId);

    gl.glEnable(GL.GL_BLEND);
    gl.glBlendFunc(GL.GL_SRC_ALPHA, GL.GL_ONE_MINUS_SRC_ALPHA);

    if (useMask)
    {
        gl.glBlendEquation(GL.GL_MIN);

        layerMaskShader.use(gl);

        display(gl, true);

        layerMaskShader.release(gl);
    }

    gl.glBlendEquation(GL.GL_MAX);

    layerTextureShader.use(gl);

    display(gl, false);

    layerTextureShader.release(gl);

    gl.glDisable(GL.GL_TEXTURE_2D);

    gl.glDepthMask(true);

    gl.glDisable(GL.GL_BLEND);
}

【问题讨论】:

    标签: opengl alphablending layer depth


    【解决方案1】:

    对于 alpha 混合,您需要确保以正确的顺序绘制它们或使用加法混合绘制它们。

    执行此操作的常用方法是将 Alpha 混合项目与非 Alpha 混合项目分开。渲染所有标准项目,从后到前对 alpha 混合项目进行排序,然后按该顺序渲染它们。如果帧速率是一个问题(例如,如果您有很多项目要排序),您可以跨多个帧进行排序。

    【讨论】:

    • 感谢您的回复。我可以确认对象正在按照您在从后到前的顺序中的建议进行渲染。抱歉,我应该在第一篇文章中提到这一点。
    • 您的纹理环境模式是否设置为调制? glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
    • 以前不是,但现在是。然而,问题仍然存在。非常感谢您的帮助。
    • 看起来您使用glBlendEquation 进行蒙版,但没有将其设置回glBlendEquation(GL_FUNC_ADD); 进行正常混合。除非我读错了代码。
    • 你,我的好先生,真是个了不起的天才!!!谢谢!我什至没有想到这一点!
    猜你喜欢
    • 2011-11-22
    • 1970-01-01
    • 2023-03-10
    • 1970-01-01
    • 2011-09-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-18
    相关资源
    最近更新 更多