OpenGL ES - 紫色或黑色屏幕

时间:2010-04-15 17:21:55

标签: iphone cocoa-touch opengl-es

我在我的iPhone应用程序中使用OpenGL ES,有时在启动时屏幕变为紫色或黑色 - 在一个案例中是20个。这仅在初始化期间发生,如果屏幕变为黑色或紫色,它将保持这种颜色 - 只有重新启动应用程序才有帮助。 我还发现,当这个错误发生时,应用程序正在运行(我可以通过控制台看到游戏循环工作),但iPhone停止响应触摸(未调用touchesBegan方法)。

这是我的代码:

#define USE_DEPTH_BUFFER FALSE

@implementation EAGLView

@synthesize context;

+ (Class)layerClass {
    return [CAEAGLLayer class];
}

- (id)initWithFrame: (CGRect)frame {
    NSLog(@"init EAGLView");
    if ( (self = [super initWithFrame: frame]) ) {
        NSLog(@"initializing CAEAGLLayer and EAGLContext");
        // Get the layer
        CAEAGLLayer *eaglLayer = (CAEAGLLayer *)self.layer;

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

        context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES1];

        if (!context || ![EAGLContext setCurrentContext:context]) {
            NSLog(@"!context || ![EAGLContext setCurrentContext:context]");
            [self release];
            return nil;
        }
    }
    return self;
}

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


- (BOOL)createFramebuffer {

    glGenFramebuffersOES(1, &viewFramebuffer);
    glGenRenderbuffersOES(1, &viewRenderbuffer);

    glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer);
    glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer);
    [context renderbufferStorage:GL_RENDERBUFFER_OES fromDrawable:(CAEAGLLayer*)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) startDrawing: (GLfloat) viewWidth andHeight: (GLfloat) viewHeight
{
    [EAGLContext setCurrentContext: context]; 
    glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer); 
    glViewport(0, 0, backingWidth, backingHeight); 
    glMatrixMode(GL_PROJECTION); 
    glLoadIdentity();
    glRotatef(-90.0f, 0.0f , 0.0f, 1.0f);

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

    glClearColor(0.0f, 0.0f, 0.0f, 1.0f); 
    glClear(GL_COLOR_BUFFER_BIT); 
} 

-(void) endDrawing
{ 
    glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer); 
    [context presentRenderbuffer: GL_RENDERBUFFER_OES]; 
}

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

    [context release];  
    [super dealloc];
}

...touches processing...

@end

可能是什么问题,我该如何解决?

提前谢谢你, 伊利亚安德。

1 个答案:

答案 0 :(得分:1)

这听起来类似于我在另一部手机上遇到的问题。 发生了什么事情,有时我们会在尝试分配纹理时“失去记忆”,从那时起,OpenGL就不会渲染,应用程序的非可视部分仍然正常运行。

确保经常调用glGetError并在每次报告GL_NO_ERROR之外的其他内容时跟踪消息/中断。 (我们有一个宏,所以,在调试时,我们在每次 OpenGL调用之后调用glGetError。)