Я создавал/переносил игру, которую я делал на С#, на C++, и когда я начал смотреть на свои кадры в секунду, я заметил что-то странное.
Я изначально программировал свою игру на С#, и частота кадров всегда была довольно последовательной. Когда я включил VSync, я получил бы 60 кадров в секунду и без, где-то около 600-700 или около того. Это всегда было очень статическим числом. Теперь, в среде C++, я замечаю, что частота кадров падает совсем немного и выглядит очень неустойчивой/непоследовательной (довольно уверен, что это имеет какое-то отношение к моей реализации).
Я собирался создать журнал и позволить приложению запускать захват числа кадров, однако это привело к снижению частоты кадров, и поэтому я решил не пытаться показать вам, ребята, через этот маршрут. Вместо этого я просто скажу, что когда приложение запускается, частота кадров отображается как 0 в течение примерно 20 мс, а затем скачки до примерно 2500 кадров в секунду. Затем приложение будет перемещаться по +500 или -500, а иногда даже эффективно удваивать, где оно составляет около 4000 кадров в секунду. Используя OpenTK, частота кадров всегда показывалась как 60fps при первом запуске (Vsync включен), и не было проблемы с отображением 0fps за несколько мс.
Я совершенно уверен, что частота кадров падает, увеличивается, падает, увеличивается и т.д. Который, для меня, выглядит как переменная, катящаяся, когда она достигает максимального значения.
Я также должен упомянуть, что я не использую библиотеку OpenGL. Я хотел написать все это с нуля, что я делал довольно успешно. Я просто не знаю, почему частота кадров настолько непоследовательна.
Вот первичный класс, где все инициализируется, и подсчитывается сама частота кадров. Надеюсь, кто-то может помочь мне определить то, что я сделал неправильно. Я заранее извиняюсь, потому что класс составляет около 220 строк кода.
Я делаю только один треугольник, который выполняется через немедленный режим.
Здесь также три быстрых снимка, чтобы еще раз продемонстрировать, о чем я говорю: это длится около 20-30 мс, а затем достигает более 2000 кадров в секунду.
Этот показывает резкий низкий всплеск (я буквально ничего не делаю, кроме как сделать треугольник!)
И высокий всплеск, опять же, только рендеринг 1 треугольника. ничего больше не происходит!
Эти фотографии - просто быстрый пример, иногда это намного хуже или лучше.
Заключительные мысли после получения помощи: эта проблема была вызвана как моей реализацией, так и отладкой в visual studio. Я создал сборку релизов, закрыл все и запустил исполняемый файл. Отклонение кадров было только около +-50; он хорошо висит вокруг 2700-2800 кадров в секунду. Итак, извлеченный урок: отладка в Visual Studio не является WYSIWYG.
timeGetTime()
- это ужасно неправильный способ измерения времени. Поэтому я сомневаюсь, что у вас есть точные значения FPS на первом месте. Используйте boost::chrono
(обратите внимание, что std::chrono
в настоящее время не обеспечивает хорошую точность в реализации Visual Studio 2013) или собственный QueryPerformanceCounter
.
Другое дело, что является актуальной проблемой перехода FPS, является вашей основной петлей:
while (isGameRunning)
{
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
if (msg.message == WM_QUIT)
{
break;
}
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else
{
draw();
}
}
Вы рисуете только если у вас нет сообщений Win32 для продолжения (когда PeekMessage()
возвращает false
). Таким образом, с любым сообщением у вас есть потерянные кадры.
Вы должны сделать это так:
while (isGameRunning)
{
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE | PM_NOYIELD)) // add PM_NOYIELD
{
// Move it to 'WndProc'.
// Break loop by setting 'isGameRunning' to 'false'
//if (msg.message == WM_QUIT)
//{
// break;
//}
TranslateMessage(&msg);
DispatchMessage(&msg);
}
// Draw unconditionnaly
draw();
}
НТН.