rendering framebuffer texture not working

Nibbie
Posts: 2
Joined: 2009.10
Post: #1
I have read numerous articles/tutorials online regarding drawing a texture to a framebuffer in opengl, but I am having no luck getting it to work. I am creating a framebuffer, drawing a texture to the fbo, and then drawing the fbo texture to the screen but nothing displays (just a black screen). I am at a loss. If i comment out the fbo code and draw the embedded texture directly to the screen, that works. Is there some iphone specific logic that i am missing (independent of opengl)? Here is my code:

Code:
// INITIALIZATION
    glEnable(GL_TEXTURE_2D);
    glEnable(GL_BLEND);
    glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
    
    // Load Test Texture
    glGenTextures(1, &textureTest);
    glBindTexture(GL_TEXTURE_2D, textureTest);            // Bind Our Texture
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);    // Linear Filtered
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);    // Linear Filtered
    [self loadTexture: @"texture"]; // calls glTexImage2D with image data from png
    
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glViewport(0,0, 320.0f,480.0f);
    glOrthof(0,320.0f, 480.0f,0, -1.0f, 1.0f); // left, right, bottom, top
    glMatrixMode(GL_MODELVIEW);
    
    //FBO Setup
    glGenTextures(1, &textureFBO); // texture handle
    glBindTexture(GL_TEXTURE_2D, textureFBO); //bind it.
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 512, 512, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);    // Linear Filtered
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);    // Linear Filtered
    
    glGenFramebuffersOES(1, &FBO); // frame buffer
    glBindFramebufferOES(GL_FRAMEBUFFER_OES, FBO); //bind the frame buffer
    
    // attach texture to framebuffer color buffer
    glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_TEXTURE_2D, textureFBO, 0);
    if(glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES) != GL_FRAMEBUFFER_COMPLETE_OES)  printf("CANNOT CREATE FRAMEBUFFER\n");


// MAIN DRAWING LOOP
    static const Vertex3D vertices[] = {
            { 0.0,  100.0, 0.0},
            { 100.0,  100.0, 0.0},
            { 0.0, 200.0, 0.0},
            { 100.0, 200.0, 0.0}
        };
    static const GLfloat texCoords[] = {
               0.0, 1.0,
            1.0, 1.0,
            0.0, 0.0,
            1.0, 0.0
        };
    
    glClear(GL_COLOR_BUFFER_BIT);
    glLoadIdentity();
    
    // Render to texture
    glBindFramebufferOES(GL_FRAMEBUFFER_OES, FBO);
    
    // Draw test texture
    glBindTexture(GL_TEXTURE_2D, textureTest);
    glEnableClientState(GL_VERTEX_ARRAY);
    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
        glVertexPointer(3, GL_FLOAT, 0, vertices);
    glTexCoordPointer(2, GL_FLOAT, 0, texCoords);
        glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
    glDisableClientState(GL_VERTEX_ARRAY);
    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
    glBindTexture(GL_TEXTURE_2D, 0); //disable any bound textures.
    // End draw test texture
    
    // Render to screen
    glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0);
    
    // Draw FBO texture
    glBindTexture(GL_TEXTURE_2D, textureFBO);
    glEnableClientState(GL_VERTEX_ARRAY);
    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
        glVertexPointer(3, GL_FLOAT, 0, vertices);
    glTexCoordPointer(2, GL_FLOAT, 0, texCoords);
    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
    glDisableClientState(GL_VERTEX_ARRAY);
    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
    glBindTexture(GL_TEXTURE_2D, 0); //disable any bound textures.
    // End draw FBO texture
Quote this message in a reply
Luminary
Posts: 5,143
Joined: 2002.04
Post: #2
Quote this message in a reply
Sage
Posts: 1,232
Joined: 2002.10
Post: #3
This is your problem:
Code:
glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0);


On the iPhone, there is no "window". The EAGLLayer is also using an FBO, and that FBO's id is not zero. So you need to bind back to whatever that id is to see the results on-screen.

If you look at the iPhone ImageProcessing sample, you'll see that:

1) The EAGLView's -initWithCoder: gens the "system framebuffer". The other view-related functions like -reshapeFramebuffer only reallocate the storage for renderbuffers; the FBO id is only created once, so it is constant for the life of the view.

2) initGL() in the underlying Imaging.c remembers the "display framebuffer" by querying it with GL_FRAMEBUFFER_BINDING_OES. This id is rebound when results need to be rendered on-screen.


You can communicate the "system framebuffer" id any way you like-- this sample is split into ObjC and vanilla C portions, so querying it from GL is simplest.
Quote this message in a reply
Post Reply 

Possibly Related Threads...
Thread: Author Replies: Views: Last Post
  Texture stops rendering klaars 2 3,742 Jul 29, 2011 08:46 AM
Last Post: klaars
  Need help with pixel oriented framebuffer edepot 24 20,225 Mar 3, 2011 07:15 AM
Last Post: mariocaprino
  What is the fastest way to blit a framebuffer to the iPhone screen? Rasterman 20 28,049 Mar 2, 2011 08:26 AM
Last Post: arekkusu