#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 мне также пришлось заново создать фреймбуферы.