为什么我的EAGLView无法创建帧缓冲区?

时间:2013-04-07 17:29:34

标签: ios opengl-es

我以前使用过这个EAGLView(在iOS 4.3左右)

#import <UIKit/UIKit.h>

#import <QuartzCore/QuartzCore.h>
#import <OpenGLES/EAGLDrawable.h>

#import "EAGLView.h"
#import "DrawingUtil.h"


#define USE_DEPTH_BUFFER 0

@interface EAGLView (EAGLViewPrivate)

- (BOOL)createFramebuffer;
- (void)destroyFramebuffer;

@end

@interface EAGLView (EAGLViewSprite)

- (void)setupView;

@end

@implementation EAGLView

@synthesize animationInterval, applicationResignedActive;

// You must implement this
+ (Class) layerClass
{
    return [CAEAGLLayer class];
}

- (id)initWithFrame:(CGRect)frame
{
NSLog(@"[INFO] initWithFrame %f %f %f %f", frame.origin.x, frame.origin.y, frame.size.width, frame.size.height);

    frame.size.width = 256;
    frame.size.width = 256;

    if((self = [super initWithFrame:frame])) {
        // Get the layer
        CAEAGLLayer *eaglLayer = (CAEAGLLayer*) self.layer;

        eaglLayer.opaque = NO;

        eaglLayer.drawableProperties = [NSDictionary dictionaryWithObjectsAndKeys:
                                        [NSNumber numberWithBool:FALSE], kEAGLDrawablePropertyRetainedBacking, kEAGLColorFormatRGBA8, kEAGLDrawablePropertyColorFormat, nil];


        context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES1];
NSLog(@"[INFO] Ready to create framebuffer");
        if(!context || ![EAGLContext setCurrentContext:context] || ![self createFramebuffer]) {
            [self release];
            return nil;
        }

        animationInterval = 1.0 / 30.0;

        [self setupView];
        [self drawView];
    }

    self.opaque = NO;

    return self;
}


- (void)layoutSubviews
{
    [EAGLContext setCurrentContext:context];
    [self destroyFramebuffer];
    [self createFramebuffer];
    [self drawView];
}


- (BOOL)createFramebuffer
{
    glGenFramebuffersOES(1, &viewFramebuffer);
    glGenRenderbuffersOES(1, &viewRenderbuffer);

    glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer);
    glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer);
    [context renderbufferStorage:GL_RENDERBUFFER_OES fromDrawable:(id<EAGLDrawable>)self.layer];
    glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, viewRenderbuffer);

    glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_WIDTH_OES, &backingWidth);
    glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_HEIGHT_OES, &backingHeight);

    if(USE_DEPTH_BUFFER) {
        glGenRenderbuffersOES(1, &depthRenderbuffer);
        glBindRenderbufferOES(GL_RENDERBUFFER_OES, depthRenderbuffer);
        glRenderbufferStorageOES(GL_RENDERBUFFER_OES, GL_DEPTH_COMPONENT16_OES, backingWidth, backingHeight);
        glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_DEPTH_ATTACHMENT_OES, GL_RENDERBUFFER_OES, depthRenderbuffer);
    }

    if(glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES) != GL_FRAMEBUFFER_COMPLETE_OES) {
        NSLog(@"failed to make complete framebuffer object %x", glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES));
        return NO;
    }

    return YES;
}


- (void)destroyFramebuffer
{
    glDeleteFramebuffersOES(1, &viewFramebuffer);
    viewFramebuffer = 0;
    glDeleteRenderbuffersOES(1, &viewRenderbuffer);
    viewRenderbuffer = 0;

    if(depthRenderbuffer) {
        glDeleteRenderbuffersOES(1, &depthRenderbuffer);
        depthRenderbuffer = 0;
    }
}

- (void)startAnimation
{
    animationTimer = [NSTimer scheduledTimerWithTimeInterval:animationInterval target:self selector:@selector(drawView) userInfo:nil repeats:YES];
    animationStarted = [NSDate timeIntervalSinceReferenceDate];
}

- (void)stopAnimation
{
    [animationTimer invalidate];
    animationTimer = nil;
}

- (void)setAnimationInterval:(NSTimeInterval)interval
{
    animationInterval = interval;

    if(animationTimer) {
        [self stopAnimation];
        [self startAnimation];
    }
}




- (void)setupView
{
    self.opaque = NO;

    // Sets up matrices and transforms for OpenGL ES
    glViewport(0, 0, backingWidth, backingHeight);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrthof(0, backingWidth, 0, backingHeight, -1.0f, 1.0f);
    glMatrixMode(GL_MODELVIEW);

    // Clears the view with (transparent) black
    glClearColor(0.0f, 0.0f, 0.0f, 0.0f);

//  glEnableClientState(GL_VERTEX_ARRAY);

}




// Updates the OpenGL view when the timer fires
- (void)drawView
{
    // the NSTimer seems to fire one final time even though it's been invalidated
    // so just make sure and not draw if we're resigning active
    if (self.applicationResignedActive) return;

    // Make sure that you are drawing to the current context
    [EAGLContext setCurrentContext:context];


    glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer);

    [delegate drawView:self forTime:([NSDate timeIntervalSinceReferenceDate] - animationStarted)];


    glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer);
    [context presentRenderbuffer:GL_RENDERBUFFER_OES];


}




// Stop animating and release resources when they are no longer needed.
- (void)dealloc
{
    [self stopAnimation];

    if([EAGLContext currentContext] == context) {
        [EAGLContext setCurrentContext:nil];
    }

    [context release];
    context = nil;

    [super dealloc];
}

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    if ([(id)delegate respondsToSelector:@selector(touchesBegan:withEvent:)])
        [delegate touchesBegan:touches withEvent:event];
}

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
    if ([(id)delegate respondsToSelector:@selector(touchesMoved:withEvent:)])
        [delegate touchesMoved:touches withEvent:event];
}

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
    if ([(id)delegate respondsToSelector:@selector(touchesEnded:withEvent:)])
        [delegate touchesEnded:touches withEvent:event];
}



- (id <EAGLViewDelegate>)delegate { return delegate; }
- (void)setDelegate:(id <EAGLViewDelegate>)v
{
    delegate = v;
}

@end

这是我的主视图创建EAGLView的地方:

    glView = [[EAGLView alloc] initWithFrame:[self frame]];
    [self addSubview:glView];
    NSLog(@"[INFO] create glView %o", [self frame]);
    glView.delegate = self;

    glView.userInteractionEnabled = FALSE;

    [glView setAnimationInterval:1./30.];
    [glView startAnimation];

我在初始化此EAGLView时收到GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_OES。我的主要观点是用于Titanium模块的TiUIView。这可能是一个线程问题吗?

1 个答案:

答案 0 :(得分:0)

我转而使用GLKit。我推荐任何能够做到这一点的人,因为它更方便。这是一个很棒的教程:http://www.raywenderlich.com/5223/beginning-opengl-es-2-0-with-glkit-part-1