glCheckFramebufferStatus返回36054 GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT

时间:2014-01-21 19:33:49

标签: android opengl-es framebuffer fbo render-to-texture

这只是为了分享一些花了我很长时间才弄明白的东西。如果您不需要Depthbuffer或者在EGL中没有Depth Buffer Attachment Point设置,这可能会有所帮助。

出于某种原因,我无法渲染到纹理以将渲染缓冲区对象RBO设置为深度缓冲区:就像这样

    GLES20.glFramebufferTexture2D(GLES20.GL_FRAMEBUFFER, 
            GLES20.GL_COLOR_ATTACHMENT0, GLES20.GL_TEXTURE_2D, 
            juliaTex[0], 0);
    rain.checkGlError("glFramebufferTexture2D");
    GLES20.glFramebufferRenderbuffer(GLES20.GL_FRAMEBUFFER, 
            GLES20.GL_DEPTH_ATTACHMENT, GLES20.GL_RENDERBUFFER, 
            juliaRBO[0]);
    rain.checkGlError("glFramebufferRenderbuffer");

    int status = GLES20.glCheckFramebufferStatus(GLES20.GL_FRAMEBUFFER);

导致错误status == GLES20.GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT

如果我将渲染缓冲区存储更改为GLES20.GL_RGBA4,而不是GLES20.DEPTH_COMPONENT16并将GLES20.GL_DEPTH_ATTACHMENT更改为GLES20.GL_COLOR_ATTACHMENT0,那么错误就会消失,

更改此

    // create render buffer and bind 16-bit depth buffer
    GLES20.glBindRenderbuffer(GLES20.GL_RENDERBUFFER, juliaRBO[0]);
    rain.checkGlError("glBindRenderBuffer");
    GLES20.glRenderbufferStorage(GLES20.GL_RENDERBUFFER, GLES20.DEPTH_COMPONENT16, 
            rain.width, rain.height);

到这个

    // create render buffer and bind 16-bit depth buffer
    GLES20.glBindRenderbuffer(GLES20.GL_RENDERBUFFER, juliaRBO[0]);
    rain.checkGlError("glBindRenderBuffer");
    GLES20.glRenderbufferStorage(GLES20.GL_RENDERBUFFER, GLES20.GL_RGBA4, 
            rain.width, rain.height);

原始代码:

    GLES20.glFramebufferTexture2D(GLES20.GL_FRAMEBUFFER, 
            GLES20.GL_COLOR_ATTACHMENT0, GLES20.GL_TEXTURE_2D, 
            juliaTex[0], 0);
    rain.checkGlError("glFramebufferTexture2D");
    GLES20.glFramebufferRenderbuffer(GLES20.GL_FRAMEBUFFER, 
            GLES20.GL_COLOR_ATTACHMENT0, GLES20.GL_RENDERBUFFER, 
            juliaRBO[0]);
    rain.checkGlError("glFramebufferRenderbuffer");

然后status == GLES20.GL_FRAMEBUFFER_COMPLETE

但纹理是空的。

这是调用创建存储纹理

    // bind texture
    GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, juliaTex[0]);

    // clamp texture to edges
    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_LINEAR);
    rain.checkGlError("glTexParameter JuliaTex");

    // create it
    /*
    int[] buf = new int[rain.width * rain.height];
    juliaTexBuff = ByteBuffer.allocateDirect(buf.length
            * rain.FLOAT_SIZE_BYTES).order(ByteOrder.nativeOrder()).asIntBuffer();
     */
    // generate the textures
    GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D, 0, GLES20.GL_RGBA, 
            rain.width, rain.height, 0, GLES20.GL_RGBA, 
            GLES20.GL_UNSIGNED_SHORT_4_4_4_4, null);

1 个答案:

答案 0 :(得分:-3)

除了将渲染缓冲区附加到颜色附加点之外,为了使其工作,我交换了Framebuffer附件的顺序:

    GLES20.glFramebufferRenderbuffer(GLES20.GL_FRAMEBUFFER, 
            GLES20.GL_COLOR_ATTACHMENT0, GLES20.GL_RENDERBUFFER, 
            juliaRBO[0]);
    rain.checkGlError("glFramebufferRenderbuffer");
    GLES20.glFramebufferTexture2D(GLES20.GL_FRAMEBUFFER, 
            GLES20.GL_COLOR_ATTACHMENT0, GLES20.GL_TEXTURE_2D, 
            juliaTex[0], 0);
    rain.checkGlError("glFramebufferTexture2D");

因此,在Renderbuffer之后,Texture2D会附加到Framebuffer颜色层。我假设最后一个连接点是OpenGL ES使用的点。