OpenGL ES可以';不要让亮度FBO在Android中工作

OpenGL ES可以';不要让亮度FBO在Android中工作,android,opengl-es,fbo,render-to-texture,Android,Opengl Es,Fbo,Render To Texture,我正在使用帧缓冲区在视频渲染器上执行一些后期处理着色器。其中一个着色器非常需要查找,因此我想更改为仅限亮度的帧缓冲区以加快速度。在初始化过程中,我尝试将glTexImage2D调用从RGBA更改为LUMINANCE,但当我尝试在“onDrawFrame”中附加缓冲区时,出现了一个错误 问题是,我已经将示例中的代码拼凑在一起,并没有完全理解它所做的一切。首先,我还创建了一个深度附件,因为我渲染视频,我不需要任何深度信息,但我不知道是否可以禁用它。无论如何,以下是我在onSurfaceCreated

我正在使用帧缓冲区在视频渲染器上执行一些后期处理着色器。其中一个着色器非常需要查找,因此我想更改为仅限亮度的帧缓冲区以加快速度。在初始化过程中,我尝试将glTexImage2D调用从RGBA更改为LUMINANCE,但当我尝试在“onDrawFrame”中附加缓冲区时,出现了一个错误

问题是,我已经将示例中的代码拼凑在一起,并没有完全理解它所做的一切。首先,我还创建了一个深度附件,因为我渲染视频,我不需要任何深度信息,但我不知道是否可以禁用它。无论如何,以下是我在onSurfaceCreated中对FBO的初始化:

        GLES20.glGenTextures(1, renTex, 0);

        // generate
        GLES20.glGenFramebuffers(1, fb2, 0);
        GLES20.glActiveTexture(GLES20.GL_TEXTURE4);

        // generate color texture
        GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, renTex[0]);

        // parameters
        GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE);
        GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE);
        GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR);
        GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_NEAREST);

        // create it 
        // create an empty intbuffer first?
        GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D, 0, GLES20.GL_RGBA, texW, texH, 0, GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, texBuffer);
        //**THIS WORKS AS IS, CHANGING FROM RGBA TO LUMINANCE BREAKS IT**

        // create render buffer and bind 16-bit depth buffer
        GLES20.glBindRenderbuffer(GLES20.GL_RENDERBUFFER, depthRb[0]);
        GLES20.glRenderbufferStorage(GLES20.GL_RENDERBUFFER, GLES20.GL_DEPTH_COMPONENT16, texW, texH);
下面是在onDrawFrame中附加缓冲区的代码:

    GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, fb[0]);
    // specify texture as color attachment
    GLES20.glViewport(0, 0, w, h);
    Matrix.frustumM(mProjMatrix, 0, -.30f, .30f, -.30f, .30f, 3, 7);


    GLES20.glFramebufferTexture2D(GLES20.GL_FRAMEBUFFER, GLES20.GL_COLOR_ATTACHMENT0, GLES20.GL_TEXTURE_2D, renTex[0], 0);
    // attach render buffer as depth buffer


    GLES20.glFramebufferRenderbuffer(GLES20.GL_FRAMEBUFFER, GLES20.GL_DEPTH_ATTACHMENT, GLES20.GL_RENDERBUFFER, depthRb[0]);
    int status = GLES20.glCheckFramebufferStatus(GLES20.GL_FRAMEBUFFER);
    if (status != GLES20.GL_FRAMEBUFFER_COMPLETE)
        System.out.println("Frame buffer not obtained :(");
//This works for RGBA but returns an error for LUMINANCE

有人有什么建议吗?我还可以放弃深度缓冲区组件,或者它是强制性的

GL\u亮度不是颜色可渲染格式。根据第4.4.5节:

表4.5中未列出的格式,包括压缩内部格式。不是 颜色、深度或模具可渲染,无论它们包含哪些组件

表中列出的颜色可渲染格式有:RGBA4、RGB5_A1和RGB565


即使RGB8和RGBA8未在表中列出,但由于您可以使用RGBA8,您的设备可能支持OES_RGB8_RGBA8和/或ARM_RGBA8扩展。

使用两种纹理作为帧缓冲目标,一种为Y平面使用GL_RED_EXT格式,另一种为UV平面使用GL_RG_EXT格式。第二个纹理将具有第一个纹理的一半尺寸,因此您不能一次将它们指定给不同的颜色附件,并且需要使用不同的视口进行两次渲染

 #include "gl2ext.h" 

...
    glGenTextures(1, &mYTextureId);
    glBindTexture(GL_TEXTURE_2D, mYTextureId);
...
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RED_EXT, mCameraFrameWidth, mCameraFrameHeight, 0, GL_RED_EXT, GL_UNSIGNED_BYTE, NULL);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mYTextureId, 0);
    glViewport(0, 0, mCameraFrameWidth, mCameraFrameHeight);
...

    glGenTextures(1, &mUVTextureId);
    glBindTexture(GL_TEXTURE_2D, mUVTextureId);
...
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RG_EXT, mCameraFrameWidth/2, mCameraFrameHeight/2, 0, GL_RG_EXT, GL_UNSIGNED_BYTE, NULL);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mUVTextureId, 0);
    glViewport(0, 0, mCameraFrameWidth/2, mCameraFrameHeight/2);
...

这适用于大多数带有arm7+的iPhone和Android手机。

您是否尝试过使用GL_DEPTH_组件而不是亮度?@BlueVoodoo我会试试这个。我猜你的意思是根本不需要绑定颜色纹理,我将尝试找出如何写入深度组件。你可能仍然需要颜色纹理。我刚才提到的是glTexImage2D()方法。不幸的是,使用GL_DEPTH_组件与GL_LUMINANCE或GL_LUMINANCE_ALPHA具有相同的效果,帧缓冲区无法工作。只有GL_RGBA和GL_RGB似乎起作用。事实上,我可以在RGB和RGBA之间切换,这让我觉得我的代码可能是对的,我怀疑硬件有限制(我使用的是带有Mali 400 GPU的AML8726-MX)。顺便说一句,我确实通过删除深度缓冲区大大加快了速度,但我仍然认为我的着色器最终读取的数据是所需数据的4倍。