Не удается перезапустить графику iPhone OpenGL при обратном переключении с контроллера просмотра UIKit

#iphone #animation #opengl-es

#iPhone #Анимация #opengl-es

Вопрос:

Я переключаюсь между двумя контроллерами представления iPhone: начальным ViewController, на котором выполняется представление 3D-анимации OpenGL, и вторым ViewController с представлением настроек программы UIKit. Анимация OpenGL работает нормально при запуске приложения, и я могу переключиться на второй VC, чтобы изменить настройки программы. Когда я переключаюсь обратно из настройки VC через делегата, я не могу перезапустить анимацию OpenGL — я получаю только черный вид.

Есть ли что-нибудь еще, что мне нужно сделать, чтобы повторно инициализировать состояние OpenGL-ES при обратном переключении на GL view?

Мой переход с GL ViewController на settings ViewController работает нормально:

 - (IBAction) switchToSettingsView:(id) sender {
    SettingsViewController *controller = [[SettingsViewController alloc] initWithNibName:@"SettingsView" bundle:nil];
    controller.settingsDelegate = self;
    [self stopTimer];    // Stop the animation
    controller.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
    [self presentModalViewController:controller animated:YES];
[controller release];
}
  

Когда я возвращаюсь из представления настроек с помощью следующего делегата, я вижу только черный фон:

 - (void) settingsViewControllerDidFinish:(SettingsViewController *)controller {
    [self dismissModalViewControllerAnimated:YES];
    [self startTimer];
    [glView startAnimation];
    [glView drawView];   // Explicitly re-drawing the GL view doesn't help
}
  

Добавление viewDidAppear / viewWillDisappear не помогло. Они вызываются, как и ожидалось.

 - (void)viewDidAppear:(BOOL)animated
{
    [glView startAnimation];
}

- (void)viewWillDisappear:(BOOL)animated
{
    [glView stopAnimation];
}
  

В настоящее время я не использую CADisplayLink в startAnimation, я использую NSTimer.

Мой OpenGL DrawView запускается в режиме GL после того, как я вернусь через делегат, но на дисплее ничего не отображается.

ОБНОВЛЕНИЕ: УСТРАНЕНО!!! Как и предполагал кихото, помогло воссоздание контекста EAGL. Мне также пришлось воссоздать фреймбуферы. Выполнение одного без другого не решило проблему. Вот код, который я использовал для повторной инициализации состояния графики:

 // Re-initialize the EAGL context and framebuffers
- (void)reInitContext {
    CAEAGLLayer *eaglLayer = (CAEAGLLayer *)self.layer;

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

    [context release];      // Releases the old EAGL Context
    context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES1];

    if (!context) {
        NSLog(@"RECREATING EAGL CONTEXT FAILED!");
    } else {
        NSLog(@"RECREATING EAGL CONTEXT SUCCEEDED!");
    };
    if (![EAGLContext setCurrentContext:context]) {
        NSLog(@"RE-SETTING EAGL CONTEXT FAILED!");
    } else {
        NSLog(@"RE-SETTING EAGL CONTEXT SUCCEEDED!");
    };

    [self destroyFramebuffer];
    [self createFramebuffer];

}
  

Комментарии:

1. Вы снова обновили контекст EAGL при обратном переключении? Работает ли это, если ваш переход не анимирован, и вы запускаете резервное копирование после этого?

2. Значение текущего контекста не изменяется, когда я возвращаюсь. Я попытаюсь полностью повторно инициализировать контекст после того, как вернусь из представления UIKit, и опубликую обновление.

3. Спасибо @quixoto за важный ключ к разрешению. В дополнение к воссозданию контекста EAGL мне также пришлось заново создать фреймбуферы.