【问题标题】:FBO rendering issue - Using generated FBO color/depth in same App for Drawing using GLSLFBO 渲染问题 - 在同一应用程序中使用生成的 FBO 颜色/深度使用 GLSL 进行绘图
【发布时间】:2014-05-26 12:10:46
【问题描述】:

带有两个立方体的图像是使用 BLIT 调用 - 测试代码

带有一个 Cube 的图像在不使用 BLIT CALL - 测试代码时显示

各位, 请按照所附图片和代码如下..

从过去 2 天开始一​​直在为此苦苦挣扎..

在下面的代码中使用 FBO 时遇到问题,我能够成功地附加和渲染到 FBo,但是在同一程序中无法将其用作纹理(颜色和深度缓冲区),我的 glReadpixel 调用之后渲染到 FBO 向我展示 Zero 的所有数据...

当在 GLSL-shader 代码中使用生成的 FBO(color,depth) 时,从 Draw2() 函数调用的代码显示一个没有纹理的混合白色立方体..

请建议...,下面是完整的代码...,我正在创建一个 FBO 并使用 2 个着色器,一个用于正常渲染,另一个使用之前处理的 FBO 的颜色和深度..

这是我的着色器代码

        init_gl()
        {

此片段着色器代码用于在draw()下的程序中使用的正常渲染

            static const char *fragment_shader_source =
                "precision mediump float;           \n"
                "                                   \n"
                "varying vec4 vVaryingColor;        \n"
                "                                   \n"
                "void main()                        \n"
                "{                                  \n"
                "    gl_FragColor = vVaryingColor;  \n"
                "}                                  \n";

这个 Fragment Shader Code 用在 Program2 下 draw2()

                static const char *fragment_shader_source2 =
                "precision mediump float;           \n"
                "                                   \n"
                "varying vec4 vVaryingColor;        \n"
                "uniform sampler2D color;       \n"
                "uniform sampler2D depth;       \n"
                "                                   \n"
                "void main()                        \n"
                "{                                  \n"
                "float r = pow(texture2D(color, gl_FragCoord.xy / vec2(256, 256)).a, 128.0); \n"
                "float g = texture2D(depth, gl_FragCoord.xy / vec2(256, 256)).a;\n"
                "float b = pow(texture2D(depth, gl_FragCoord.xy / vec2(256, 256)).a, 128.0); \n"
                "gl_FragColor = vec4(r, g, b, 1.);   \n"
                "}                                  \n";

我在 FBO 上的第一幅画

    static void draw(uint32_t i)
    {

            EGL_CHECK(glEnable(GL_DEPTH_TEST)); 
        glEnable(GL_TEXTURE_2D);
        EGL_CHECK(glDepthFunc(GL_ALWAYS));
            EGL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, fboInfo.id));
        EGL_CHECK(glUseProgram(program));

        //CUBE DRAWING

在这里读取像素,返回全零

        GLubyte *pixels = malloc(4 * 256 * 256);
        EGL_CHECK(glReadBuffer(GL_COLOR_ATTACHMENT0));
        EGL_CHECK(glReadPixels(0, 0, 256, 256, GL_RGBA, GL_UNSIGNED_BYTE, pixels));

            //**TO TEST my FBO , IF ITS HAVING SOME RENDER DATA**
        EGL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, 0));
        glBindFramebuffer(GL_READ_FRAMEBUFFER, fboInfo.id); 
        glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
        glBlitFramebuffer(0, 0, 256, 256, 0, 0, 256, 256, GL_COLOR_BUFFER_BIT, GL_NEAREST);
        glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
            //TEST CODE ONLY

        glBindTexture(GL_TEXTURE_2D, fboInfo.id);
            glGenerateMipmap(GL_TEXTURE_2D);
            glBindTexture(GL_TEXTURE_2D, 0);

        draw2(i);

    }

没有 FBO 的第二张图(但这使用了可以访问 FBO 数据颜色、深度的 FRAG 着色器)

    static void draw2(uint32_t i)
    {

        glUseProgram(program2);

        //Draw Same Kind of Cube , Which we draw in draw() function

    }

这些是创建 FBO(颜色、深度)的函数

         GLuint createTexture2D(const int w, const int h, GLint internalFormat, GLenum format, GLenum type)
            {
                GLuint textureIdX;
                EGL_CHECK(glGenTextures(1, &textureIdX));
                EGL_CHECK(glBindTexture(GL_TEXTURE_2D, textureIdX));

                EGL_CHECK(glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST));
                EGL_CHECK(glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST));
                EGL_CHECK(glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
                EGL_CHECK(glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
                if (GL_DEPTH_COMPONENT == format) {
                    EGL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_NONE));
                    EGL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE, GL_INTENSITY));
                }
                EGL_CHECK(glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, w, h, 0, format, type, 0));
                EGL_CHECK(glBindTexture(GL_TEXTURE_2D, 0));
                return textureIdX;
            }

            int createFBO(void)
            {
                int result = 0;
                unsigned int fb = 0;

                fboInfo.color = createTexture2D(WINDOW_WIDTH, WINDOW_HEIGHT, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE);
                fboInfo.depth = createTexture2D(WINDOW_WIDTH, WINDOW_HEIGHT, GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT, GL_FLOAT);

                EGL_CHECK(glGenFramebuffers(1, &fboInfo.id));
                EGL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, fboInfo.id));


                EGL_CHECK(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, fboInfo.color, 0));
                EGL_CHECK(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, fboInfo.depth, 0));

                int data = EGL_CHECK(glCheckFramebufferStatus(GL_FRAMEBUFFER));
                if (GL_FRAMEBUFFER_COMPLETE == glCheckFramebufferStatus(GL_FRAMEBUFFER)) {
                    printf("FBO %d set up successfully\n", fboInfo.id);
                    result = 1;
                }
                else {
                    printf("FBO %d NOT set up properly!\n", fboInfo.id);
                }

                EGL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, 0));
                return result;
            }

这就是我的 FBO 结构的样子

typedef struct {
    GLuint id;
    GLuint color;
    GLuint depth;
}FBOInfo;

我的 MAIN 函数如下所示,我在其中创建 FBO,然后调用我的绘图函数并交换缓冲区..

            unsigned long i = 0;
            int ret = init_gl();
            ret = createFBO();
            draw(i);
            EGL_CHECK(eglSwapBuffers(eglDisplay, eglSurface));

【问题讨论】:

    标签: opengl graphics opengl-es opengl-es-2.0 fbo


    【解决方案1】:

    由于这是相当多的代码,并且您认为问题出在 FBO 设置上,因此我专注于该部分。我确实在您设置附件的那部分代码中发现了一个关键问题:

    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, fboInfo.depth, 0);
    

    如果在此之后调用glGetError(),您应该会看到返回错误,因为GL_RENDERBUFFER 不是第三个参数的有效值。唯一有效的参数是 GL_TEXTURE_2DGL_TEXTURE_CUBE_MAP_* 值。在这种情况下,您必须使用 GL_TEXTURE_2D

    如果您从不将其用作纹理,则将渲染缓冲区用于深度缓冲区实际上可能会更好。但要做到这一点,您必须使用所有相应的调用:

    • 使用glGenRenderbuffers 创建ID。
    • glBindRenderbuffer绑定。
    • glRenderbufferStorage 分配它。
    • 使用 glFramebufferRenderbuffer 将其附加到 FBO。

    【讨论】:

    • 当我更改枚举值并将其替换为 GL_TEXTURE_2D 时,我收到 FBO 未正确设置的错误...
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-10-22
    • 2013-12-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多