Android OpenGL ES Framebuffer对象 - 渲染深度缓冲到纹理

时间:2010-10-28 09:53:32

标签: android opengl-es depth-buffer

我正在使用运行Froyo的Android设备,支持OpenGL ES 1.1和OpenGL ES 2.0

我想将深度缓冲区渲染到纹理。在其他平台(包括iPhone)上看过OpenGL ES OpenGL ES的一些例子后,我尝试了很多FBO配置。

我似乎能够使用颜色纹理进行FBO设置,但每次添加深度纹理时都会失败。

我当前的代码基于this example,但也创建了颜色纹理,而不是将绘图和读取缓冲区设置为无。

是否有一个在Android上配置OpenGL ES FBO以渲染纹理深度的简单示例?或者是否有一个描述支持和不支持的文档?


感谢您的评论 - 我特别需要ES 1.1的解决方案,如果它可以找到并在Android上运行。我也想看看ES 2 - 我不确定我理解将深度信息打包到色彩缓冲区的想法 - 你有一个参考我可以看看更好地理解这个想法吗?

关于代码 - 我的来源与我上面发布的链接几乎没有什么不同。 Framebuffer状态是它不完整。


感谢片段着色器建议 - 我现在明白了。如果我不能让另一个解决方案工作,请看看。我的理想是同时获得深度和颜色 - 如果我可以帮助它,不要分别渲染颜色和深度。

2 个答案:

答案 0 :(得分:16)

好的,各种答案。这适用于使用OpenGL ES 2的Android 2.2:

    // Create a frame buffer
    glGenFramebuffers( 1, &(frame_buffer ) );

    // Generate a texture to hold the colour buffer
    glGenTextures(1, &(colour_texture) );
    glBindTexture(GL_TEXTURE_2D, colour_texture);
    // Width and height do not have to be a power of two
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
            pixelWidth, pixelHeight,
            0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);

    // Probably just paranoia
    glBindTexture(GL_TEXTURE_2D, 0);

    // Create a texture to hold the depth buffer
    glGenTextures(1, &(depth_texture) );
    glBindTexture(GL_TEXTURE_2D, depth_texture);

    glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT,
            pixelWidth, pixelHeight,
            0, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, NULL);

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);

    glBindTexture(GL_TEXTURE_2D, 0);        

    glBindFramebuffer(GL_FRAMEBUFFER, frame_buffer);

    // Associate the textures with the FBO.

    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
                    GL_TEXTURE_2D, colour_texture, 0);

    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
                    GL_TEXTURE_2D, depth_texture, 0);

    // Check FBO status.    
    GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);

    if ( status == GL_FRAMEBUFFER_COMPLETE )
    {
        // Success
    }

非常简单,请遵循OpenGL ES2手册,按照正确的顺序执行所有操作。

尝试使用OpenGL ES 1.1,将OES添加到所需的函数调用,将_OES添加到常量,因为帧缓冲区对象是扩展。任何将深度纹理附加到帧缓冲区的尝试都会导致帧缓冲区对象不完整。

所以目前我的结论是,这不适用于Android上的OpenGL ES 1.1,但它显然适用于ES 2.2。

如果有人有ES 1.1的解决方案,那么看到它会很有趣。

答案 1 :(得分:0)

许多设备不支持渲染到深度纹理。您需要为深度缓冲区附加渲染缓冲区。