2009-05-07 3 views
1

Я использую OpenGL ES, чтобы сделать игру на iPhone. К сожалению, я вижу небольшие (и нерегулярные) икоты.Икота в OpenGL ES. Какая правильная реализация?

Я использую таймер со сном, вызывая функцию ничьей каждые 60 секунд, чтобы обеспечить стабильную частоту кадров. Я попытался изменить момент времени, когда мой таймер пробуждается от сна, давая функции рисования больше времени для выполнения. Икоты получают меньше, когда функция ничьей получает больше времени. С 8 миллисекундами анимация почти текучая. Мои выводы:

  1. Очевидно, что GPU больше времени для выполнения фактического чертежа, приводит к (почти) идеальной жидкостной анимации.
  2. Рисунок в точном конце моего кадра приводит к заиканию, икоту, а что нет.

Теперь, когда я это знаю, Я не уверен, как действовать. Я две противоречащие идеи о причине такого поведения:

  1. Во-первых, это может быть, что команды OpenGL мешают чертежа предыдущего кадра? Насколько я понимаю, это не так, поскольку команды хранятся и будут выполняться только при задании команды рисования.
  2. Во-вторых, может ли колебательное время команд ничьей заставить таймер пропустить галочку?

Какое объяснение более вероятно? Или нет? Конечно, я мог бы просто попытаться поместить функцию ничьи в отдельную нить и посмотреть, решает ли она мою проблему. Но я надеюсь понять больше OpenGL.

Эта функция вызывается, и объясняет, что я везу о:

- (void) drawView 
{ 
    // measure time with mach_absolute_time 

    // gameEngine update  
    // OpenGL commands (translate, rotate, drawArrays etc.) 

    // end measure time with mach_absolute_time 
    // usleep(animationInterval - duration - constant) 
    // constant is the time to start executing 

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

ответ

1

Вы могли бы хотеть, чтобы прочитать эту article about game loops, который объясняет многое. Как правило, лучшим решением является вызов процедуры рисования в бесконечном цикле внутри отдельного потока (см. this question) и обновление базовой модели игры в соответствии с тем, сколько времени прошло с момента последнего обновления. Это даст вам плавное движение.

Редакция: Что касается источника «икоты», они, вероятно, не имеют ничего общего с OpenGL. При 60 fps мы говорим 1/60 сек ≈ 17 мс за кадр. Это трудный график, который легко пропустить, потому что на нем есть другие процессы. Safari или Mail.app просыпаются в фоновом режиме, устройство думает некоторое время, и теперь ваш кадр занимает 30 мс или даже гораздо больше. Это очень легко заметить, если ваша модель ожидает абсолютно постоянной частоты кадров. Решение состоит в том, чтобы обновить модель в соответствии с прошедшим в реальном времени, как я уже писал выше. Связанная статья полностью объясняет это.

+0

Спасибо! Это очень помогло. :) – Kriem

+0

Добро пожаловать. Есть также хорошие идеи в движке Cocos2D для iPhone (http://tinyurl.com/5hpjba), особенно если вы делаете 2D. – zoul

+0

Я. Вы проверите это. Еще раз спасибо! – Kriem

Смежные вопросы