Икоты в OpenGL ES. Какова правильная реализация? - PullRequest
1 голос
/ 07 мая 2009

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

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

  1. Очевидно, что графический процессор дает больше времени для выполнения реального рисования, что приводит к (почти) идеальной плавной анимации.
  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 Ответ

1 голос
/ 07 мая 2009

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

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

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