Search code examples
c++openglfbo

Cant render to Frame Buffer Object


I try to render a small quad on a bigger quad but it doesn't seem to work. It renders both quads a small magenta quad and a big white quad with a line on it, on next to each other, not one on top of the other.

glEnable( GL_TEXTURE );
glEnable( GL_TEXTURE_2D );

float *data = new float[ 756 * 756 * 3 ];

for( int i = 0 ; i < 756 ; i++ )
    for( int j = 0 ; j < 756 ; j++ )
        if( i == j )
            for( int k = 0; k < 3 ; k++ )
                data[i * 756 * 3 + j * 3 + k] = 0.0f;
        else
            for( int k = 0; k < 3 ; k++ )
                data[ i * 756 * 3 + j * 3 + k ] = 1.0f;

GLuint Texture;
GLuint FrameBufferObject;

glGenTextures( 1 , &Texture );
glBindTexture( GL_TEXTURE_2D , Texture );
glTexImage2D( GL_TEXTURE_2D , 0 , 3 , 756 , 756 , 0 , GL_RGB , GL_FLOAT , data );

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 );

glewInit();

glGenFramebuffers( 1 , &FrameBufferObject );
glBindFramebuffer( GL_DRAW_FRAMEBUFFER , FrameBufferObject );
glBindTexture( GL_TEXTURE_2D , Texture );

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

//GLuint atchements[] = { GL_COLOR_ATTACHMENT0 };
//glDrawBuffers( 1 , atchements );

GLenum e = glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER);
    if (e != GL_FRAMEBUFFER_COMPLETE)
        cout << " MASIVE ERROR, ABORT ! " << endl;

glBindFramebuffer( GL_DRAW_FRAMEBUFFER , 0 );

/* program main loop */
while (!bQuit)
{
    /* check for messages */
    if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
    {
        /* handle or dispatch messages */
        if (msg.message == WM_QUIT)
        {
            bQuit = TRUE;
        }
        else
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    }
    else
    {
        /* OpenGL animation code goes here */

        glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
        glClear(GL_COLOR_BUFFER_BIT);

        glLoadIdentity();

        glPushMatrix();
        glRotatef(theta, 0.0f, 0.0f, 1.0f);

        glBindTexture( GL_TEXTURE_2D , 0 );

        glBindFramebuffer( GL_DRAW_BUFFER , FrameBufferObject );

        //GLuint atchements[] = { GL_COLOR_ATTACHMENT0 };
        //glDrawBuffers( 1 , atchements );

        glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
        glClear(GL_COLOR_BUFFER_BIT);

        glBindTexture( GL_TEXTURE_2D , 0 );
        glBegin(GL_QUADS);
            glColor3f( 1 , 0 , 1 );

            glVertex2f( 0 , 0 );
            glVertex2f( 0 , .1 );
            glVertex2f( .1 , .1 );
            glVertex2f( .1 , 0 );

            glColor3f( 1 , 1 , 1 );
        glEnd();

        glBindFramebuffer( GL_DRAW_BUFFER , 0 );

        glScalef( 0.5 , .5 , .5 );
        glTranslatef( 0 , 0.3 , 0 );

        glBindTexture( GL_TEXTURE_2D , Texture );
        glBegin(GL_QUADS);

            glTexCoord2f( 0 , 0 );
            glVertex2f( 0 , 0 );

            glTexCoord2f( 0 , 1 );
            glVertex2f( 0 , 1 );

            glTexCoord2f( 1 , 1 );
            glVertex2f( 1 , 1 );

            glTexCoord2f( 1 , 0 );
            glVertex2f( 1 , 0 );

        glEnd();

        glPopMatrix();

        SwapBuffers(hDC);

        theta += 1.0f;
        Sleep (1);
    }
}

Solution

  • There are many issues with your code, but I think the main issue is that you are not using GL_READ_FRAMEBUFFER correctly. This is not to read from the texture you rendered into, but just the source operand for glBlitFramebuffer(). It is totally irrelevant here.

    What you currently are doing in the main loop:

    1. set the FBO as draw framebuffer, so rendering to Texture
    2. clear it
    3. draw some quad with magenta color, texturing still enabled, but texture object 0 bound
    4. still leave the FBO bound as draw framebuffer
    5. you bind the FBO as read framebuffer also, which is of no use here
    6. render a white quad textured with the texture you rendered into in 2&3

    Step 4&6 in combination create an invalid feedback loop, since you still render into Texture at this point. You never render onto the screen, so you shouldn't see anything at all. The fact that you do actually see something besides a black screen means that I overlooked some other error, because you shouldn't. (EDIT: The OP noticed that he originally wrote glBindFramebuffer(GL_DRAW_BUFFER,...) instead of GL_DRAW_FRAMEBUFFER, which now fully explains the observed behavior.)

    You probably want glBindFramebuffer(GL_DRAW_FRAMEBUFFER,0) instead of step 4&5, to render into the default framebuffer again.

    Some other issues:

    • you never adjust the viewport size to match that of the framebuffer you are using
    • you reattach the texture to the FBO repeatedly
    • you use an array of floats to specify the initial texture, although your internal format is just an 8bit per channel normalized uint format