Frame buffer objects seem to be messing with my computer

Apprentice
Posts: 16
Joined: 2009.01
Post: #1
I've been working with OpenGL frame buffer objects recently. I had plain FBOs working for a while, and am now trying to build a class that can wrap around an FBO. However, when I run a program that binds to an FBO (through one of my FBO objects) while drawing for off-screen rendering, quitting the program causes the screen to either flicker black or freeze entirely. Blink

My frame buffer object code:
Code:
#import <Cocoa/Cocoa.h>

@interface FrameBuffer : NSObject
{
    GLuint fbo;
    GLuint depthRenderBuffer;
}

+ (void) unbind;
- (void) bind;
- (void) attachTexture: (GLuint) textureID;
- (void) setDepthBufferWidth: (int) width andHeight: (int) height;
- (void) checkStatus;

@end
Code:
#import "FrameBuffer.h"

@implementation FrameBuffer

+ (void) unbind
{
    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
}

- (id) init
{
    if (![super init])
    {
        return nil;
    }

    glGenRenderbuffersEXT(1, &depthRenderBuffer);
    glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, depthRenderBuffer);
    glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT,
      0, 0);
    glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0);

    glGenFramebuffersEXT(1, &fbo);
    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo);

    glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT,
      GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, depthRenderBuffer);
    //glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);

    return self;
}

- (void) bind
{
    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo);
}

- (void) attachTexture: (GLuint) textureID
{
    glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
      GL_TEXTURE_2D, textureID, 0);
}

- (void) setDepthBufferWidth: (int) width andHeight: (int) height
{
    glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, depthRenderBuffer);
    glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT,
      width, height);
}

- (void) checkStatus
{
    GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);

    if (status != GL_FRAMEBUFFER_COMPLETE_EXT)
    {
        NSException *exception;

        switch (status)
        {
            case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT:
                exception = [NSException
                  exceptionWithName: @"FrameBufferIncompleteException"
                  reason: @"GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT"
                  userInfo:nil];
                break;
            case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT:
                exception = [NSException
                  exceptionWithName: @"FrameBufferIncompleteException"
                  reason:
                    @"GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT"
                  userInfo:nil];
                break;
            case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT:
                exception = [NSException
                  exceptionWithName: @"FrameBufferIncompleteException"
                  reason: @"GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT"
                  userInfo:nil];
                break;
            case GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT:
                exception = [NSException
                  exceptionWithName: @"FrameBufferIncompleteException"
                  reason: @"GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT"
                  userInfo:nil];
                break;
            case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT:
                exception = [NSException
                  exceptionWithName: @"FrameBufferIncompleteException"
                  reason: @"GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT"
                  userInfo:nil];
                break;
            case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT:
                exception = [NSException
                  exceptionWithName: @"FrameBufferIncompleteException"
                  reason: @"GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT"
                  userInfo:nil];
                break;
            case GL_FRAMEBUFFER_UNSUPPORTED_EXT:
                exception = [NSException
                  exceptionWithName: @"FrameBufferIncompleteException"
                  reason: @"GL_FRAMEBUFFER_UNSUPPORTED_EXT"
                  userInfo:nil];
                break;
            default:
                exception = [NSException
                  exceptionWithName: @"FrameBufferIncompleteException"
                  reason: @"Unknown error"
                  userInfo:nil];
                break;
        }

        @throw exception;
    }
}

- (void) dealloc
{
    glDeleteFramebuffersEXT(1, &fbo);
    glDeleteRenderbuffersEXT(GL_RENDERBUFFER_EXT, &depthRenderBuffer);

    [super dealloc];
}

@end


My program also uses a texture manager:
Code:
@interface TextureManager : NSObject
{
    GLuint *textures;
    int numTextures;
}

+ (void) unbind;
- (id) initWithNumTextures: (int) num;
- (GLuint) getTextureIDatIndex: (int) index;
- (void) bindTextureAtIndex: (int) index;
- (void) setMagFilter: (GLint) filter;
- (void) setMinFilter: (GLint) filter;
- (void) setWrapping: (GLint) wrap;
- (void) createTextureWithWidth: (int) width withHeight: (int) height;

@end
Code:
#import "TextureManager.h"

@implementation TextureManager

+ (void) unbind
{
    glBindTexture(GL_TEXTURE_2D, 0);
}

- (id) initWithNumTextures: (int) num
{
    if (![super init])
    {
        return nil;
    }

    textures = calloc(num, sizeof(*textures));
    numTextures = num;

    glGenTextures(num, textures);

    return self;
}

- (GLuint) getTextureIDatIndex: (int) index
{
    return textures[index];
}

- (void) bindTextureAtIndex: (int) index
{
    glBindTexture(GL_TEXTURE_2D, textures[index]);
}

- (void) setMagFilter: (GLint) filter
{
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter);
}

- (void) setMinFilter: (GLint) filter
{
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter);
}

- (void) setWrapping: (GLint) wrap
{
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrap);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrap);
}

- (void) createTextureWithWidth: (int) width withHeight: (int) height
{
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8,  width, height, 0, GL_BGRA,
      GL_UNSIGNED_INT_8_8_8_8_REV, NULL);
}

- (void) dealloc
{
    glDeleteTextures(numTextures, textures);
    free(textures);

    [super dealloc];
}

@end


And finally, code from my NSOpenGLView subclass:

Code:
@interface MyOpenGLView : NSOpenGLView
{
    ...

    TextureManager *textures;
    FrameBuffer *fbo;
}

......

- (void) prepareOpenGL
{
    ...

    textures = [[TextureManager alloc]
      initWithNumTextures: NUM_SCENE_TEXTURES];

    int i;
    for (i = 0; i < NUM_SCENE_TEXTURES; ++i)
    {
        [textures bindTextureAtIndex: i];

        [textures setMagFilter: GL_LINEAR];
        [textures setMinFilter: GL_LINEAR];
        [textures setWrapping: GL_CLAMP_TO_EDGE];

        [textures createTextureWithWidth: 0 withHeight: 0];
    }

    [TextureManager unbind];

    //-----

    fbo = [[FrameBuffer alloc] init];
    // Only bind the first texture for now
    [fbo attachTexture: [textures getTextureIDatIndex: 0]];
    [FrameBuffer unbind];

    ...
}

- (void) reshape
{
    int width = [self bounds].size.width;
    int height = [self bounds].size.height;

    [scene resizeWithWidth: width withHeight: height];

    int i;
    for (i = 0; i < NUM_SCENE_TEXTURES; ++i)
    {
        [textures bindTextureAtIndex: i];

        [textures createTextureWithWidth: width withHeight: height];
    }

    [fbo setDepthBufferWidth: width andHeight: height];
}

- (void) drawRect: (NSRect) bounds
{
    // Setup stuff
    ...

    // First pass - draw scene to texture

    // I enable a shader here.

    // If I comment out the next two likes I don't get any screen flickering or
    // possible crashes when I exit the program.
    [fbo bind];
    [fbo checkStatus];

    glLoadIdentity();

    glClearColor(0.0, 0.0, 0.0, 1.0);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    [scene draw];

    [FrameBuffer unbind];

    glLoadIdentity();

    glClearColor(1.0, 1.0, 1.0, 1.0);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    // I'm not doing anything with the new texture yet.

    glFlush();
}
Quote this message in a reply
Member
Posts: 59
Joined: 2007.12
Post: #2
Did you try removing the destructors?
Quote this message in a reply
Apprentice
Posts: 16
Joined: 2009.01
Post: #3
For my frame buffer object wrapper or something else?

Update

I tried commenting out the glDeleteFramebuffersEXT and glDeleteRenderbuffersEXT calls, and I don't get the black flicker or freezing anymore.
Quote this message in a reply
Post Reply 

Possibly Related Threads...
Thread: Author Replies: Views: Last Post
  SLOW performance drawing multiple polygons per frame with stencil buffer clam61 7 4,119 Apr 27, 2013 11:53 AM
Last Post: clam61
  Saving Frame Buffer nicromonicon 2 3,180 Apr 9, 2008 08:23 AM
Last Post: stevejohnson
  Messing with HID LWStrike 2 2,641 Mar 30, 2006 12:35 AM
Last Post: LWStrike
  New Computer == Open Gl code problem KiroNeem 4 3,341 Mar 31, 2005 09:40 AM
Last Post: KiroNeem
  glRotate and glTranslate are messing up my lighting?!? Jake 5 4,120 Oct 17, 2003 01:08 PM
Last Post: MacFiend