Framebuffers in OS X

I am trying to start using framebuffers in my app. I fallowed Apple tutorial Using a Framebuffer Object as a Texture. And my code looks like this:

Somewhere in header file:

    GLuint framebuffer, texture;
    GLenum status;

And .m file:

   -(void)initFBO {
    glGenFramebuffersEXT(1, &framebuffer);
    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, framebuffer);
    glGenTextures(1, &texture);
    glBindTexture(GL_TEXTURE_2D, texture);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0,
                    GL_RGBA, GL_UNSIGNED_BYTE, NULL);
    glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
                    GL_TEXTURE_2D, texture, 0);
    status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
    if (status != GL_FRAMEBUFFER_COMPLETE_EXT) {
            NSLog(@"failed");
            } else {
            NSLog(@"success");
           }
    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
    }

    -(void)someDrawingFunc {
    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb);
    glClear(GL_COLOR_BUFFER_BIT);
    glEnable(GL_TEXTURE_2D);
    glBindTexture(GL_TEXTURE_2D, someTexture1);
    glBegin(GL_QUADS);
    glTexCoord2f(0.0f, 0.0f);
    glVertex2f(0.0, height);
    glTexCoord2f(0.0f, 1.0f);;
    glVertex2f(0.0, 0.0);
    glTexCoord2f(1.0f, 1.0f);
    glVertex2f(width, 0.0);
    glTexCoord2f(1.0f, 0.0f);
    glVertex2f(width, height);
    glEnd();

    glBindTexture(GL_TEXTURE_2D, someTexture2);
    glBegin(GL_QUADS);
    glTexCoord2f(0.0f, 0.0f);
    glVertex2f(0.0, height);
    glTexCoord2f(0.0f, 1.0f);;
    glVertex2f(0.0, 0.0);
    glTexCoord2f(1.0f, 1.0f);
    glVertex2f(width, 0.0);
    glTexCoord2f(1.0f, 0.0f);
    glVertex2f(width, height);
    glEnd();
    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
    
    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
    glEnableClientState(GL_VERTEX_ARRAY);
    glBindTexture(GL_TEXTURE_2D, texture);
    CGFloat verfb[] = {0, 0,
        width, 0,
        width, height,
        0, height};
    CGFloat texfb[] = {0, 0,
        1, 0,
        1, 1,
        0, 1,};
    glVertexPointer(2, GL_FLOAT, 0, verfb);
    glTexCoordPointer(2, GL_FLOAT, 0, texfb);
    glDrawArrays(GL_QUADS, 0, 4);
    glDisableClientState(GL_VERTEX_ARRAY);
    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
    glFlush();
    }

In console I see “success”, but in my app window I see:
[ATTACH=CONFIG]261[/ATTACH]

While with same code just without using framebuffer at all, I see:
[ATTACH=CONFIG]262[/ATTACH]

What am I doing wrong?

http://www.opengl.org/wiki/Framebuffer_Object_Examples#Color_only

and if that doesn’t work, try making a depth renderbuffer.
http://www.opengl.org/wiki/Framebuffer_Object_Examples#Quick_example.2C_render_to_texture_.282D.29

I tried both suggested solutions. My app firstly opens without any texture (image). And then user drags image on my app window, then texture is being created and textured quad is being drawn so that it would look like showing image. First time when I drag image (943x567) it says “success” and draws image to window. But when I draw on it with my OpenGL brush it doesn’t reacts. Then I drag same image one more time and it says success again, but draws only black color. If I launch app and first time drag 3200x2000 image, it says

failed to make complete framebuffer object 8cdd

, but draws image to window. And again, if I drag any image second time on my app image it draws only black screen. And even if I firstly drag image 943x567 witch first time is being drawn to window good, after any type of transformation (for example glTranslatef) it becames black piece of window.

I have made some progress. Now my frambuffer code looks like this:

-(void)initFBO {
glGenFramebuffersEXT(1, &framebuffer);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, framebuffer);
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0,
                GL_RGBA, GL_UNSIGNED_BYTE, NULL);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
                GL_TEXTURE_2D, texture, 0);
status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
if (status != GL_FRAMEBUFFER_COMPLETE_EXT) {
        NSLog(@"failed");
        } else {
        NSLog(@"success");
       }
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
}

-(void)someDrawingFunc {
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, framebuffer);
glPushAttrib(GL_VIEWPORT_BIT | GL_ENABLE_BIT);  // Push our glEnable and glViewport states
glViewport(0, 0, width, height);
glClearColor(0.0, 0.0, 1.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT);
glLoadIdentity();
glEnable(GL_BLEND);
glBlendFunc(GL_ONE, GL_ZERO);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, someTexture);
glBegin(GL_QUADS);
glTexCoord2f(0.0f, 0.0f);
glVertex2f(0.0, height);
glTexCoord2f(0.0f, 1.0f);;
glVertex2f(0.0, 0.0);
glTexCoord2f(1.0f, 1.0f);
glVertex2f(width, 0.0);
glTexCoord2f(1.0f, 0.0f);
glVertex2f(width, height);
glEnd();
glPopAttrib();
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);

[self drawFBO];
}

-(void)drawFBO {
glClearColor(1.0, 0.0, 0.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT);
glLoadIdentity();
    glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, texture);
glBegin(GL_QUADS);
glTexCoord2f(-1.0f, -1.0f); glVertex2f(-1.0f, -1.0f);
glTexCoord2f(-1.0f, 1.0f); glVertex2f(-1.0f, 1.0f);
glTexCoord2f(1.0f, 1.0f); glVertex2f(1.0f, 1.0f);
glTexCoord2f(1.0f, -1.0f); glVertex2f(1.0f, -1.0f);
glEnd();
glFlush();
glBindTexture(GL_TEXTURE_2D, 0);
}

But in my app window I see:
[ATTACH=CONFIG]266[/ATTACH]

After glReadPixels and saving pixels to image I get image witch looks like this:
[ATTACH=CONFIG]267[/ATTACH]

Note: Image is filled with glClearColor. And from somewhere there appears mysterious black line.

When without using framebuffer at all, with the same code (Note: without using frame buffer) in my app window I get:
[ATTACH=CONFIG]268[/ATTACH]

And after glReadPixels and saving to file I get:
[ATTACH=CONFIG]269[/ATTACH]

What am I doing wrong? Thanks.

I think you need to simplify your question. You are stating multiple cases.

Did you do what I suggested? Did you read what the Wiki said? If your FBO doesn’t have a depth, then call glDisable(GL_DEPTH_TEST) and glDepthMask(GL_FALSE). Ok, so you are clearing the FBO to blue and you are rendering to it with a quad (someDrawingFunc) and you only end up with blue. I guess that means that the quad’s pixels are getting rejected.
How are you setting up your projection and modelview matrix? What are your values for width and height?

Another thing. If you are going to use fixed function, then you need to know how to use it. For now, just before rendering your quad, call glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE) and call glColor4f(1.0, 1.0, 1.0, 1.0).

glDisable(GL_DEPTH_TEST) and glDepthMask(GL_FALSE) is alredy used in my code. glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE) and glColor4f(1.0, 1.0, 1.0, 1.0) gives no difference. My OpenGL set up looks like this:

glcontext = [self openGLContext];
[glcontext makeCurrentContext];
zoomSlider.floatValue = -0.5;
[zoomSlider needsDisplay];
width = 5 * textureWidth;
height = 5 * textureHeight;
glLoadIdentity(); //clean settings, because -(void)initOpenGL could be called few times during runtime
NSSize size = {width / (-10 * (-0.5)), height / (-10 * (-0.5))}; //get needed frame size witch depends on zoom slider and texture size
[self setFrameSize:size]; //set NSOpenGLView frame size to view only textured quad (no black or other color background)
glViewport(0, 0, width, height);
glMatrixMode(GL_MODELVIEW);
glFrustum(0, width, 0, height, 0.1, 100);
glTranslatef(0.0,0.0,-0.5);

Width and height values depends on texture image size. Lets say texture size is 1000x1000, then width and height will be 5000x5000. Its multiplied by 5 to have ability to do “zoom-in”.

EDIT:

Strange thing, I changed fbo code a little bit and now I see my textured quad, when I draw FBO to screen but not like I should see it. By the way, when I do glReadPixels and write pixels to image, I get correct image (everything I rendered to FBO).

My FBO code looks like this now:

-(void)initFBO {
    glDeleteFramebuffersEXT(1, &framebuffer);
    glDeleteTextures(1, &texture);
    
    glGenFramebuffersEXT(1, &framebuffer);
    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, framebuffer);
    glEnable(GL_TEXTURE_2D);
    glGenTextures(1, &texture);
    glBindTexture(GL_TEXTURE_2D, texture);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, (oglPlotis/5), (oglAukstis/5), 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);

status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
if (status != GL_FRAMEBUFFER_COMPLETE_EXT) {
        NSLog(@"failed");
        } else {
        NSLog(@"success");
       }
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
}

-(void)someDrawingFunc {
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, framebuffer);
glClearColor(0.0, 0.0, 1.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT);
glEnable(GL_BLEND);
glBlendFunc(GL_ONE, GL_ZERO);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, someTexture);
glBegin(GL_QUADS);
glTexCoord2f(0.0f, 0.0f);
glVertex2f(0.0, height);
glTexCoord2f(0.0f, 1.0f);;
glVertex2f(0.0, 0.0);
glTexCoord2f(1.0f, 1.0f);
glVertex2f(width, 0.0);
glTexCoord2f(1.0f, 0.0f);
glVertex2f(width, height);
glEnd();
glFlush();
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);

[self drawFBO];
}

-(void)drawFBO {
glClearColor(1.0, 0.0, 0.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, texture);
glBegin(GL_QUADS);
glTexCoord2f(0.0f, 0.0f); glVertex2f(0.0f, 0.0f);
glTexCoord2f(0.0f, 1.0f); glVertex2f(0.0f, height);
glTexCoord2f(1.0f, 1.0f); glVertex2f(width, height);
glTexCoord2f(1.0f, 0.0f); glVertex2f(width, 0.0f);
glEnd();
glFlush();
glBindTexture(GL_TEXTURE_2D, 0);
}

And in my app window I see:

[ATTACH=CONFIG]271[/ATTACH]

You can run the numbers through gluProject. I did and looks like the quad should land exactly on the FBO and it should be visible.

As for this part :
glMatrixMode(GL_MODELVIEW);
glFrustum(0, width, 0, height, 0.1, 100);
glTranslatef(0.0,0.0,-0.5);

You should never call glFrustum for the modelview. Put that on your projection matrix.
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glFrustum(0, width, 0, height, 0.1, 100);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0.0,0.0,-0.5);

Also, why use glFrustum? Your clearly want to do a 2D application, so use glOrtho.
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, width, 0, height, -100.0, 100.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0.0,0.0,-0.5);

I use glFrustum because I need perspective projection. I mean, I need that objects that are more far away to become smaller. Thank you for answer. I will try it just right now and give feedback :slight_smile:

EDIT:

Your suggestion have not given any effect. I guess the problem is with my writing to frame buffer. Because when I render to framebuffer, i clear color buffer with blue color. And when I draw framebuffer, I get the textured quad, that I draw as a full size quad to frame buffer, but its not full size. All other area is cleared with blue color (as I did, when rendering to framebuffer). I’ll try some ways about glTranslatef. Because now I guess it could be so that because I do glTranslatef with moving my objects by -0.5 on the z-axis, so it could be that it is moved on z-axis by -0.5 once when rendering to buffer, and moved by -0.5 again when drawing framebuffer to screen.

EDIT 2:

And I was right. The problem was in my glTranslatef. So what I did? I did glPushMatrix(); when rendering to FBO then set needed attributes and after rendering to FBO - glPopMatrix();. Then draw FBO like I did it earlier