FBO render as Texture : Color does not render correctly

I am render using FBO buffer, but Texture does not render the color correctly. I dont have any clue about it. Help me.


#include <GL/glew.h>
#include <GL/glut.h>
#include <GL/glu.h>

#include <stdlib.h>
#include <stdio.h>
#include <math.h>

void init();
void display();

// Buffer objects for FBO

unsigned int *fb, color, depth;


void CHECK_FRAMEBUFFER_STATUS()

{                                                         
        GLenum status;
        status = glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER); 
        switch(status) {
        case GL_FRAMEBUFFER_COMPLETE:
        break;

        case GL_FRAMEBUFFER_UNSUPPORTED:
        break;

        default:
        fputs("Framebuffer Error
", stderr);
        exit(-1);
        }
}


void init()
{

///////////////////////////////////        INIT OF FB1         //////////////////////////////..........///////////


               glEnable(GL_TEXTURE_2D);

                fb = (unsigned int *)malloc(1 * sizeof(unsigned int));
                glGenFramebuffersEXT(1, fb);
                glGenTexturesEXT(1, &color);
                glGenRenderbuffersEXT(1, &depth);

                glBindFramebuffer(GL_FRAMEBUFFER, fb[0]);
                glBindTexture(GL_TEXTURE_2D, color);

               glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
               glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
               glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
               glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
               glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 800, 480, 0, GL_RGBA, GL_UNSIGNED_INT, NULL);

                glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, color, 0);

                glBindRenderbuffer(GL_RENDERBUFFER,depth);
                glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, 800, 480);
                glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depth);

                CHECK_FRAMEBUFFER_STATUS();

}

void prepare()
{

            ///// render into 1st fbo /////


            glBindTexture(GL_TEXTURE_2D, 0);
            glEnable(GL_TEXTURE_2D);

            glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fb[0]);

            glClearColor(1,1,1,0);
            glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );

           glViewport(0, 0, 800.0f, 480.0f);
           glMatrixMode(GL_PROJECTION);
           glLoadIdentity();
           gluOrtho2D (0, 800.0f, 0, 480.0f);
           glMatrixMode(GL_MODELVIEW);

           // glEnable(GL_DEPTH_TEST);
           glDisable(GL_CULL_FACE);

           glColor4ub(0,0,255,255);
           glRectf(0.0f,0.0f, 100.0f,100.0f);

           glColor4ub(0, 255, 0,255);
           glRectf(110.0f,110.0f, 300.0f,300.0f);

           glColor4ub(0,0,255,255);
           glRectf(310.0f,310.0f, 400.0f,400.0f);

                   glBindFramebuffer(GL_FRAMEBUFFER, 0); 

}

void final()
{


/////////////   RENDER FB0 AS TEXTURE      /////////////////////////



            glBindFramebuffer(GL_FRAMEBUFFER, 0);

            glClearColor(1.,1.,1.,0.);
            glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );

           glViewport(0, 0, 800.0f, 480.0f);
           glMatrixMode(GL_PROJECTION);
           glLoadIdentity();
           gluOrtho2D (0, 800.0f, 0, 480.0f);
           glMatrixMode(GL_MODELVIEW);
           glLoadIdentity();

               glEnable(GL_TEXTURE_2D);
           glBindTexture(GL_TEXTURE_2D, color);

           glEnable(GL_DEPTH_TEST);
           //glEnable(GL_CULL_FACE);
           glDisable(GL_CULL_FACE);

           glEnable(GL_BLEND);
           glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

           glBegin(GL_QUADS);

           glTexCoord2f(0.0f, 0.0f); glVertex3f(0.0f, 0.0f, 0.0f);
           glTexCoord2f(0.0f, 1.0f); glVertex3f(0.0f, 480.0f, 0.0f);
           glTexCoord2f(1.0f, 1.0f); glVertex3f(800.0f, 480.0f, 0.0f);
           glTexCoord2f(1.0f, 0.0f); glVertex3f(800.0f, 0.0f, 0.0f);

           glEnd();



}



void display()
{
    prepare();
    final();
    glutSwapBuffers();
}


int main(int argc, char *argv[])
{
    glutInit(&argc, argv);
    glutInitDisplayMode( GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH );
    glutInitWindowSize(800, 480);              // window size

    glutCreateWindow("FBO test");
    glutDisplayFunc(display);
    glutIdleFunc(glutPostRedisplay);
    glewInit();
    init();

    glutMainLoop();

    return 0;
}

Thanks in Advance,

If you provide some basic information, you’re more likely to get help.

What is it doing now (specifically)?
What do you want it to do (specifically)?
What have you done to try and diagnose the problem yourself?

Thanks for your reply Dark Photon.

I have created a FBO object and bind it with a depth and texture attachment.
I am rendering three different color rectangles to the Frame Buffer Object.
And I rendered it as texture in default window system based Frame Buffer.
But the color of the rectangle is not correct. Why it is render as different in texture?

The problem is that you’re using the legacy fixed-function pipeline, and you don’t completely understand it. If you’re going to use it, you need to do some more reading. Here’s a link to the ol’ OpenGL 2.1 Specification.

You can confirm that the problem is in your rendering the texture to the window by changing your final() method as follows:


void final()
{
    glBindFramebuffer(GL_READ_FRAMEBUFFER, fb[0]);
    glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
    glBlitFramebuffer( 0, 0, 800, 480, 0, 0, 800, 480, GL_COLOR_BUFFER_BIT, GL_NEAREST );
}

This just copies the contents of the color texture bound to the COLOR0 attachment of your FBO to the window, bypassing all shader-related rendering. As you can see, this looks just fine.

The problem is with your state setup in final(). Specifically, the state you need to setup to correctly drive shader generation in OpenGL’s legacy fixed-function pipeline (where OpenGL internally generates vertex and fragment shaders for you based on GL state that you setup in your application).

The default is for those shaders to MODULATE the fragment color with the texture color. Your current fragment color at this point is “blue”, which when modulated by your texture color gives you the result you see. What it sounds like you instead want is to just get the raw texture color written by those internally-generated fragment shaders. For that, you need to set the tex env mode to REPLACE:


glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE );

What you’ve tripped over above is one good reason to just write your own shaders. With those, it’s much harder to have this kind of problem because you’re in complete control of how fragments are being shaded.

Thanks Dark Photon,

It’s works fine. Adding,

glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE );

in my code solve my problem and rendering correctly. I think I have lack of knowledge about this legacy fixed-function pipeline. I will study the PDF that you have shared. Thanks for your reply :slight_smile: