Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Minimal example for creating FBO using OpenGL ES 2.0 on iOS

Tags:

ios

opengl-es

I am having trouble creating an FBO, and then using that as a texture in my iOS app. I've uploaded a stripped down version of my app on github, which shows the problem. I get just a blank screen with a weird color which I never set. Checking status shows that the FBO was created successfully.

https://github.com/glman74/simpleFBO

I have already looked at related stackoverflow questions, and specifically the link below from datenwolf which shows how to set up an FBO using GLUT, but does not use shaders. I am still not sure what I am doing wrong.

https://github.com/datenwolf/codesamples/blob/master/samples/OpenGL/minimalfbo/

I am also appending here relevant parts of the code. In the renderFBO method, I am just doing a clear. I would have expected that this solid colored (green) texture would be used when I am rendering the polygon in the main render.

FBO setup:

// intialize FBO
- (void)setupFBO
{
    fbo_width = 512;
    fbo_height = 512;

    glGenFramebuffers(1, &fboHandle);
    glGenTextures(1, &fboTex);
    glGenRenderbuffers(1, &depthBuffer);

    glBindFramebuffer(GL_FRAMEBUFFER, fboHandle);

    glBindTexture(GL_TEXTURE_2D, fboTex);
    glTexImage2D( GL_TEXTURE_2D,
                 0,
                 GL_RGBA,
                 fbo_width, fbo_height,
                 0,
                 GL_RGBA,
                 GL_UNSIGNED_BYTE,
                 NULL);

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER_APPLE, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, fboTex, 0);

    glBindRenderbuffer(GL_RENDERBUFFER, depthBuffer);
    glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24_OES, fbo_width, fbo_height);
    glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER_APPLE, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthBuffer);

    // FBO status check
    GLenum status;
    status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
    switch(status) {
        case GL_FRAMEBUFFER_COMPLETE:
            NSLog(@"fbo complete");
            break;

        case GL_FRAMEBUFFER_UNSUPPORTED:
            NSLog(@"fbo unsupported");
            break;

        default:
            /* programming error; will fail on all hardware */
            NSLog(@"Framebuffer Error");
            break;
    }

    glBindFramebuffer(GL_FRAMEBUFFER, 0);
}

FBO render:

// render FBO 
- (void)renderFBO
{
    glBindTexture(GL_TEXTURE_2D, 0);
    glEnable(GL_TEXTURE_2D);
    glBindFramebuffer(GL_FRAMEBUFFER, fboHandle);

    glViewport(0,0, fbo_width, fbo_height);
    glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glBindFramebuffer(GL_FRAMEBUFFER, 0);
}

Main Render:

- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect
{
    // render FBO tex
    [self renderFBO];

    glViewport(0, 0, self.view.bounds.size.width, self.view.bounds.size.height);
    // render main
    glClearColor(0.65f, 0.65f, 0.65f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glEnable(GL_TEXTURE_2D);
    glActiveTexture(GL_TEXTURE0);

    glUniform1i(uSamplerLoc, 0);     
    // Render 
    glUseProgram(_program);

    glUniformMatrix4fv(uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX], 1, 0, _modelViewProjectionMatrix.m);
    glUniformMatrix3fv(uniforms[UNIFORM_NORMAL_MATRIX], 1, 0, _normalMatrix.m);

    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

    glDisable(GL_TEXTURE_2D);
}

An ideas on what I might be doing wrong?

Edit #1:

I have made some small changes to my code at github. Tried using GL_FRAMEBUFFER instead of GL_DRAW_FRAMEBUFFER_APPLE above. Also added a bind texture call, which was missing. Still doesn't work.

Edit #2:

I found a solution. I needed to call in main render:

// reset to main framebuffer
[((GLKView *) self.view) bindDrawable];    
like image 969
M-V Avatar asked Jun 28 '12 01:06

M-V


1 Answers

Found a solution, and I have updated the code below in case it is useful for someone.

https://github.com/glman74/simpleFBO/

The main issue is that I needed to call in main render:

// reset to main framebuffer
[((GLKView *) self.view) bindDrawable];   

This is because I was using GLKView. The situation is different from the CAEAGLLayer examples.

like image 62
M-V Avatar answered Oct 14 '22 02:10

M-V