OpenGL ES - фиолетовый или черный экран - PullRequest
0 голосов
/ 15 апреля 2010

Я использую OpenGL ES в своем приложении для iPhone, и иногда во время запуска экран становится фиолетовым или черным - в одном случае из двадцати. Это происходит только во время инициализации, и если экран стал черным или фиолетовым, он останется таким цветом - помогает только перезапуск приложения. Также я обнаружил, что когда эта ошибка возникает, приложение работает (я вижу, что игровой цикл работает через консоль), но 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 Ответ

1 голос
/ 22 июля 2010

Это похоже на проблему, с которой я столкнулся на другом телефоне. Случилось так, что иногда мы «выходили из памяти» при попытке выделить текстуру, и с тех пор OpenGL просто не рендерился, а невизуальная часть приложения работала нормально.

Убедитесь, что вы часто вызываете glGetError и отслеживаете сообщение / разрыв каждый раз, когда оно сообщает что-то еще, кроме GL_NO_ERROR. (Для этого у нас есть макрос, поэтому при отладке мы вызываем glGetError после при каждом вызове OpenGL.)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...