Jump to content

  • Log In with Google      Sign In   
  • Create Account


Stuck on nested FrameBufferObjects


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
3 replies to this topic

#1 Nathan Handley   Members   -  Reputation: 792

Like
0Likes
Like

Posted 14 February 2013 - 11:59 AM

I've been battling this long enough that I feel I must throw in the towel and ask for help.  Ultimately, I'm trying to render to a FrameBufferObject, and then render that to another FrameBufferObject.  Since I couldn't get it working in my game engine, I ran out to the net and cobbled together a really basic example in order to remove impacting variables. Even after this, I just can't get it.  See here:
 
    uint16 mDisplayHeight = 1000;
    uint16 mDisplayWidth = 1600;
    int32 mVideoFlags;

    // Init SDL
    SDL_Init(SDL_INIT_VIDEO);
    mVideoFlags  = SDL_OPENGL;          // Use OpenGL in SDL
    mVideoFlags |= SDL_HWPALETTE;       // Hardware enabled palette
    const SDL_VideoInfo* sdlVideoInfo = SDL_GetVideoInfo();
    if (sdlVideoInfo->hw_available)
        mVideoFlags |= SDL_HWSURFACE;   // Hardware enabled surfaces
    else
        mVideoFlags |= SDL_SWSURFACE;   // Software enabled surfaces
    if (sdlVideoInfo->blit_hw)
        mVideoFlags |= SDL_HWACCEL;     // Hardware enabled blitting
    SDL_SetVideoMode(mDisplayWidth, mDisplayHeight, 32, mVideoFlags);
    SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
    SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL, 1);

    // Initialize OpenGL
    glewInit();
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    glDisable(GL_DEPTH_TEST);

    /** First FBO - The Render One **/
    uint32 mFinalFBOTexID = 0;
    uint32 mFinalFBOID = 0;
    glGenFramebuffers(1, &mFinalFBOID);
    glBindFramebuffer(GL_FRAMEBUFFER, mFinalFBOID);
    glGenTextures(1, &mFinalFBOTexID);
    glBindTexture(GL_TEXTURE_RECTANGLE_ARB, mFinalFBOTexID);
    glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA8, mDisplayWidth,
                 mDisplayHeight, 0, GL_BGRA, GL_UNSIGNED_BYTE, NULL);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_RECTANGLE_ARB,
                           mFinalFBOTexID, 0);
    glBindFramebuffer(GL_FRAMEBUFFER, 0);
    /****/

    /** Second FBO - Intermediate **/
    uint32 mSecondRenderTextureID = 0;
    uint32 mSecondRenderTextureFBO = 0;
    glGenFramebuffers(1, &mSecondRenderTextureFBO);
    glBindFramebuffer(GL_FRAMEBUFFER, mSecondRenderTextureFBO);
    glGenTextures(1, &mSecondRenderTextureID);
    glBindTexture(GL_TEXTURE_RECTANGLE_ARB, mSecondRenderTextureID);
    glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA8, 300,
                 300, 0, GL_BGRA, GL_UNSIGNED_BYTE, NULL);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_RECTANGLE_ARB,
                           mSecondRenderTextureID, 0);
    glBindFramebuffer(GL_FRAMEBUFFER, 0);
    /****/

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho(0, mDisplayWidth, mDisplayHeight, 0, -1, 1);
    glMatrixMode(GL_MODELVIEW);

    // Execution Loop
    while(true)
    {
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

        glBindFramebuffer(GL_FRAMEBUFFER, mFinalFBOID); // X1
        //glBindFramebuffer(GL_FRAMEBUFFER, mSecondRenderTextureFBO); //  X2

        // Draw a quad
        glDisable(GL_TEXTURE_RECTANGLE_ARB);
        glColor3f(1.0f, 1.0f, 0.0f);
        glBegin(GL_QUADS);
            glVertex2i(10, 10);
            glVertex2i(50, 10);
            glVertex2i(50, 50);
            glVertex2i(10, 50);
        glEnd();
        glEnable(GL_TEXTURE_RECTANGLE_ARB);

        /* X2
        glBindFramebuffer(GL_FRAMEBUFFER, mFinalFBOID);
        glBindTexture(GL_TEXTURE_RECTANGLE_ARB, mSecondRenderTextureID);

        glBegin(GL_QUADS);
            glTexCoord2i(0, 100);
            glVertex2i(0, 0);
            glTexCoord2i(100, 100);
            glVertex2i(100, 0);
            glTexCoord2i(100, 0);
            glVertex2i(100, 100);
            glTexCoord2i(0, 0);
            glVertex2i(0, 100);
        glEnd();
        */

        // Draw the 2D Layer on top
        glBindFramebuffer(GL_FRAMEBUFFER, 0);
        glLoadIdentity();
        glBindTexture(GL_TEXTURE_RECTANGLE_ARB, mFinalFBOTexID);

        glBegin(GL_QUADS);
            glTexCoord2i(0, mDisplayHeight);
            glVertex2i(0, 0);
            glTexCoord2i(mDisplayWidth, mDisplayHeight);
            glVertex2i(mDisplayWidth, 0);
            glTexCoord2i(mDisplayWidth, 0);
            glVertex2i(mDisplayWidth, mDisplayHeight);
            glTexCoord2i(0, 0);
            glVertex2i(0, mDisplayHeight);
        glEnd();

        // Present the information
        SDL_GL_SwapBuffers();
    }
 
This code renders a yellow quad without any problems.  But, if I uncomment the two X2 blocks and comment out the X1 block, I get a black screen.  I can't seem to figure out how to paint to and render that second FBO.
 
Any advice? This is driving me bonkers. Am I approaching the solution wrong?

Edited by necreia, 14 February 2013 - 08:10 PM.


Sponsor:

#2 _Slin_   Members   -  Reputation: 202

Like
1Likes
Like

Posted 14 February 2013 - 08:02 PM

I don´t see why you disable GL_TEXTURE_RECTANGLE, just to enable it a few lines later, but that of course should not be the problem.

You should probably specify a viewport, but as you can see something in one case, that doesn´t seem to be the problem.

Try to disable blending.

 

I would recommend you to use a frame debugger, which exist for windows, linux, mac and most smartphones: https://www.opengl.org/wiki/Debugging_Tools

There you should be able to look at your target textures and find out where something goes wrong.



#3 Nathan Handley   Members   -  Reputation: 792

Like
0Likes
Like

Posted 14 February 2013 - 08:07 PM

I disable GL_TEXTURE_RECTANGLE in order to unbind the current texture, so that the quad that is rendered is simply color splashed. I'm rendering 2D style, so Ortho should handle what I would have used viewport for.

I've not see that frame debugger before. Thanks. I'll take a look. When I try and dump the texture memory manually of that second texture, it doesn't appear that anything is being written there. Even more surprising, there are no GL_ERRORS! I've even adjusted the generated texture to be a power of two.

It has to be something simple... I just know it.

Edit: Oh, I had an extra disable. I see what you mean. Clipped it out.

Edited by necreia, 14 February 2013 - 08:10 PM.


#4 Nathan Handley   Members   -  Reputation: 792

Like
0Likes
Like

Posted 15 February 2013 - 10:15 AM

In the end, it was the texture size issue. For any Googlers out there, this works:

 

    uint16 mDisplayHeight = 1000;
    uint16 mDisplayWidth = 1600;
    int32 mVideoFlags;

    // Init SDL
    SDL_Init(SDL_INIT_VIDEO);
    mVideoFlags  = SDL_OPENGL;          // Use OpenGL in SDL
    mVideoFlags |= SDL_HWPALETTE;       // Hardware enabled palette
    const SDL_VideoInfo* sdlVideoInfo = SDL_GetVideoInfo();
    if (sdlVideoInfo->hw_available)
        mVideoFlags |= SDL_HWSURFACE;   // Hardware enabled surfaces
    else
        mVideoFlags |= SDL_SWSURFACE;   // Software enabled surfaces
    if (sdlVideoInfo->blit_hw)
        mVideoFlags |= SDL_HWACCEL;     // Hardware enabled blitting
    SDL_SetVideoMode(mDisplayWidth, mDisplayHeight, 32, mVideoFlags);
    SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
    SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL, 1);

    // Initialize OpenGL
    glewInit();
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    glDisable(GL_DEPTH_TEST);

    // Create the frame buffers and textures
    unsigned int mFrameBufferTexIDs[2];
    unsigned int mFrameBufferObjectIDs[2];
    for (int i = 0; i < 2; i++)
    {
        glGenFramebuffers(1, &mFrameBufferObjectIDs[i]);
        glBindFramebuffer(GL_FRAMEBUFFER, mFrameBufferObjectIDs[i]);
        glGenTextures(1, &mFrameBufferTexIDs[i]);
        glBindTexture(GL_TEXTURE_RECTANGLE_ARB, mFrameBufferTexIDs[i]);
        glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
        glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
        glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA8, mDisplayWidth, mDisplayHeight, 0, GL_BGRA, GL_UNSIGNED_BYTE, NULL);
        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_RECTANGLE_ARB, mFrameBufferTexIDs[i], 0);
        glBindFramebuffer(GL_FRAMEBUFFER, 0);
    }

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho(0, mDisplayWidth, mDisplayHeight, 0, -1, 1);
    glMatrixMode(GL_MODELVIEW);

    // Framebuffer and texture arrays are as follows:
    // 0 : Final output (what I want to present to the screen)
    // 1 : Intermediate output (what I want to render to and then render THAT to the screen)
    bool renderToIntermediateFBO = true;

    while(true)
    {
        if (renderToIntermediateFBO == false)
        {
            glBindFramebuffer(GL_FRAMEBUFFER, mFrameBufferObjectIDs[0]);

            // Draw a quad with no texture
            glDisable(GL_TEXTURE_RECTANGLE_ARB);
            glColor3f(1.0f, 1.0f, 0.0f);
            glBegin(GL_QUADS);
                glVertex2i(10, 10);
                glVertex2i(50, 10);
                glVertex2i(50, 50);
                glVertex2i(10, 50);
            glEnd();
            glEnable(GL_TEXTURE_RECTANGLE_ARB);
        }
        else
        {
            glBindFramebuffer(GL_FRAMEBUFFER, mFrameBufferObjectIDs[1]);

            // Draw a quad with no texture
            glDisable(GL_TEXTURE_RECTANGLE_ARB);
            glColor3f(1.0f, 1.0f, 0.0f);
            glBegin(GL_QUADS);
                glVertex2i(10, 10);
                glVertex2i(50, 10);
                glVertex2i(50, 50);
                glVertex2i(10, 50);
            glEnd();
            glEnable(GL_TEXTURE_RECTANGLE_ARB);

            // Draw the intermediate FBO onto the final FBO
            glBindFramebuffer(GL_FRAMEBUFFER, mFrameBufferObjectIDs[0]);
            glBindTexture(GL_TEXTURE_RECTANGLE_ARB, mFrameBufferTexIDs[1]);
            glBegin(GL_QUADS);
                glTexCoord2i(0, mDisplayHeight);
                glVertex2i(0, 0);
                glTexCoord2i(mDisplayWidth, mDisplayHeight);
                glVertex2i(mDisplayWidth, 0);
                glTexCoord2i(mDisplayWidth, 0);
                glVertex2i(mDisplayWidth, mDisplayHeight);
                glTexCoord2i(0, 0);
                glVertex2i(0, mDisplayHeight);
            glEnd();

            // Draw another untextured quad on the final FBO
            glDisable(GL_TEXTURE_RECTANGLE_ARB);
            glColor3f(0.0f, 1.0f, 1.0f);
            glBegin(GL_QUADS);
                glVertex2i(20, 20);
                glVertex2i(60, 20);
                glVertex2i(60, 60);
                glVertex2i(20, 60);
            glEnd();
            glEnable(GL_TEXTURE_RECTANGLE_ARB);
        }

        // Present the final information to the screen
        glBindFramebuffer(GL_FRAMEBUFFER, 0);
        glLoadIdentity();
        glBindTexture(GL_TEXTURE_RECTANGLE_ARB, mFrameBufferTexIDs[0]);
        glColor3f(1.0f, 1.0f, 1.0f);
        glBegin(GL_QUADS);
            glTexCoord2i(0, mDisplayHeight);
            glVertex2i(0, 0);
            glTexCoord2i(mDisplayWidth, mDisplayHeight);
            glVertex2i(mDisplayWidth, 0);
            glTexCoord2i(mDisplayWidth, 0);
            glVertex2i(mDisplayWidth, mDisplayHeight);
            glTexCoord2i(0, 0);
            glVertex2i(0, mDisplayHeight);
        glEnd();
        SDL_GL_SwapBuffers();
    }

 






Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS