Как мне достичь среднего, скажем, 60 (или 30) FPS в моей игре нет доступа к прерыванию вертикального отката? (Некоторые драйверы не предоставляют прерывание vblank.)
Я не хочу тратить время на процессорное копирование кадров быстрее, чем монитор может отобразить в любом случае, но в то же время я не хочу, чтобы средняя частота кадров падала намного ниже, чем скорость отображения монитора, так как это лишило бы игрока своевременной обратной связи.
Я использую OpenGL, но принцип должен быть таким же для GDI или для всего остального.
Меня не интересует, прежде всего, избегать слез, а скорее сохранять иллюзию контроль в реальном времени, это объединенная задержка на входе и выходе.
Я уверен, что для этого должен быть какой-то стандартный шаблон. (Периодические таймеры? Sleep?) Я использую Windows (pre-Metro), но приветствуются и более общие идеи.
Комментарий, который вы добавили, сделал более очевидным, что вы беспокоитесь о разрыве: очевидно, вы должны использовать двойную буферизацию, которую вы активируете при вызове ChoosePixelFormat()
но вам все равно нужно правильно выбрать время, чтобы не было слез:
перерисовать сразу после вашего звонка SwapBuffers()
, Это дает вам 1/60 секунды; если вам нужно больше, вы должны временно опуститься до 30 кадров в секунду.
Вы МОЖЕТЕ немедленно вызвать следующий SwapBuffers, но если вы сделаете это, вы бы потребляли 100% ЦП, потому что на момент 1 вы должны перерисовать буфер сразу после него. Чтобы избежать этого, вы должны пытаться спать, если остается достаточно времени, например, использовать QueryPerformanceCounter/Frequency
определить, сколько времени осталось до следующей 1/60 секунды: если оно превышает, например, 8 миллисекунд, Sleep(1)
, иначе занят — подождите, чтобы частота кадров не менялась слишком сильно.
Других решений пока нет …