Рисование объекта за X секунд в OpenGL - PullRequest
2 голосов
/ 27 апреля 2011

В OpenGL все работает с основным циклом (насколько я знаю). Это проблема, если вы хотите нарисовать объект за заданное время. Пока что я делаю следующее: я измеряю приблизительный FPS моего приложения и устанавливаю счетчик, который я уменьшаю на каждой итерации в основном цикле. Когда счетчик достигает 0, я прекращаю рисовать. Так, например, если я хочу нарисовать объект на 2 с на экране, а мой FPS равен 30, я установил счетчик на 60 и нарисую объект, пока счетчик не достигнет 0.

Это работает нормально, но не очень. Например, это мешает написать что-то вроде drawObjectFor(object, time) поскольку объект иногда находится "далеко" от основного цикла. Есть ли лучший способ сделать это?

Ответы [ 2 ]

5 голосов
/ 27 апреля 2011

Ваш FPS может (и обычно будет) варьироваться, поэтому подсчет кадров не является хорошей идеей.

Предположим, этот пример показывает, как это может вас укусить:
Ваше приложение работает с частотой 60 FPSи ваше время кадра составляет 16,58 мс.Это значит, что объект должен находиться на экране в течение 2 секунд, вам придется нарисовать объект за 120 кадров.Легко, поехали!
Рисование объекта добавляет 0,1 мс, что дает общее время кадра 16,68 мс.Ох, ш * т.Теперь у вас есть 30 FPS, и ваш объект отображается в течение 4 секунд ...

Используйте правильное время , чтобы решить, рисовать ваш объект или нет.Когда вы пришли к выводу, что время вашего объекта истекло, просто установите флаг, чтобы вы не рисовали его (или удалите его из графа сцены, если он у вас есть, или удалите его, или что-то еще).

Это можно сделать разными способами:

  • Под Windows
    • Использовать SetTimer, который отправит сообщение в очередь сообщений вашего окна.Когда вы получаете уведомление WM_TIMER, установите для флага do_draw объекта (или как вы хотите его называть) значение false.
    • Если вы уже используете WaitFor(Single|Multiple)Object где-то один раз в каждом кадре, выполните CreateWaitableTimer,и подожди на этом тоже.Вы можете использовать MsgWaitForMultipleObjectsEx для закачки и ожидания сообщений за один раз, и одновременно проверять APC.
    • Ничто не мешает вам читать время вручную один раз за кадр.GetTickCount один раз, добавьте 2000 и сделайте if(new_count <= old_count + 2000) draw_object().Хотя точность GetTickCount ужасна (несколько десятков миллисекунд), это не имеет значения при ожидании в течение 2 секунд.
  • Под Linux
    • Использованиеtimerfd и epoll для проверки готовности или установите timerfd на неблокирование и посмотрите, возвращает ли чтение из него EAGAIN
    • Используйте clock_gettime и сделайте это вручную (как с GetTickCount)
    • Использование setitimer
1 голос
/ 27 апреля 2011

В самом объекте может быть поле «время жизни», которое отсчитывает время до тех пор, пока объект не будет уничтожен (или, по крайней мере, сделан невидимым).1004 *.Затем вам также понадобится передать время кадра объекту, возможно, при рендеринге, чтобы он мог соответственно уменьшить его timeToLive.

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