OpenGL Несогласованная частота кадров

0

Я создавал/переносил игру, которую я делал на С#, на C++, и когда я начал смотреть на свои кадры в секунду, я заметил что-то странное.

Я изначально программировал свою игру на С#, и частота кадров всегда была довольно последовательной. Когда я включил VSync, я получил бы 60 кадров в секунду и без, где-то около 600-700 или около того. Это всегда было очень статическим числом. Теперь, в среде C++, я замечаю, что частота кадров падает совсем немного и выглядит очень неустойчивой/непоследовательной (довольно уверен, что это имеет какое-то отношение к моей реализации).

Я собирался создать журнал и позволить приложению запускать захват числа кадров, однако это привело к снижению частоты кадров, и поэтому я решил не пытаться показать вам, ребята, через этот маршрут. Вместо этого я просто скажу, что когда приложение запускается, частота кадров отображается как 0 в течение примерно 20 мс, а затем скачки до примерно 2500 кадров в секунду. Затем приложение будет перемещаться по +500 или -500, а иногда даже эффективно удваивать, где оно составляет около 4000 кадров в секунду. Используя OpenTK, частота кадров всегда показывалась как 60fps при первом запуске (Vsync включен), и не было проблемы с отображением 0fps за несколько мс.

Я совершенно уверен, что частота кадров падает, увеличивается, падает, увеличивается и т.д. Который, для меня, выглядит как переменная, катящаяся, когда она достигает максимального значения.

Я также должен упомянуть, что я не использую библиотеку OpenGL. Я хотел написать все это с нуля, что я делал довольно успешно. Я просто не знаю, почему частота кадров настолько непоследовательна.

Вот первичный класс, где все инициализируется, и подсчитывается сама частота кадров. Надеюсь, кто-то может помочь мне определить то, что я сделал неправильно. Я заранее извиняюсь, потому что класс составляет около 220 строк кода.

http://pastebin.com/tV4Sd2K3

Я делаю только один треугольник, который выполняется через немедленный режим.

Здесь также три быстрых снимка, чтобы еще раз продемонстрировать, о чем я говорю: это длится около 20-30 мс, а затем достигает более 2000 кадров в секунду.

Изображение 174551

Этот показывает резкий низкий всплеск (я буквально ничего не делаю, кроме как сделать треугольник!)

Изображение 174551

И высокий всплеск, опять же, только рендеринг 1 треугольника. ничего больше не происходит!

Изображение 174551

Эти фотографии - просто быстрый пример, иногда это намного хуже или лучше.

Заключительные мысли после получения помощи: эта проблема была вызвана как моей реализацией, так и отладкой в visual studio. Я создал сборку релизов, закрыл все и запустил исполняемый файл. Отклонение кадров было только около +-50; он хорошо висит вокруг 2700-2800 кадров в секунду. Итак, извлеченный урок: отладка в Visual Studio не является WYSIWYG.

  • 0
    Что-нибудь еще работает в фоновом режиме? Также забудьте о немедленном режиме, он устарел, вместо этого используйте шейдеры и VBO
  • 0
    @ratchetfreak Visual Studio и Google Chrome, и я использую только немедленный режим для начальной отладки; Я буду очень скоро снимать его с моего двигателя.
Показать ещё 5 комментариев
Теги:
opengl
frame-rate

1 ответ

2
Лучший ответ

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();
}

НТН.

  • 0
    Я посмотрю на повышение и QueryPerformanceCounter.
  • 0
    Ваше обновление было улучшением. Теперь он прыгает всего около 150 кадров или около того, намного лучше, чем почти 500-600 кадров в секунду, которые он делал.
Показать ещё 4 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню