Limiting fps with std::chrono

心不动则不痛 提交于 2019-12-06 00:43:49

One can do better by updating m_BeginFrame and m_EndFrame by invFpsLimit instead of by system_clock::now(). This might look something like:

#include <iostream>
#include <thread>

int fpsLimit() {return 60;}

int
main()
{
    using namespace std::chrono;
    using dsec = duration<double>;
    auto invFpsLimit = duration_cast<system_clock::duration>(dsec{1./fpsLimit()});
    auto m_BeginFrame = system_clock::now();
    auto m_EndFrame = m_BeginFrame + invFpsLimit;
    unsigned frame_count_per_second = 0;
    auto prev_time_in_seconds = time_point_cast<seconds>(m_BeginFrame);
    while (true)
    {
        // Do drawing work ...

        // This part is just measuring if we're keeping the frame rate.
        // It is not necessary to keep the frame rate.
        auto time_in_seconds = time_point_cast<seconds>(system_clock::now());
        ++frame_count_per_second;
        if (time_in_seconds > prev_time_in_seconds)
        {
            std::cerr << frame_count_per_second << " frames per second\n";
            frame_count_per_second = 0;
            prev_time_in_seconds = time_in_seconds;
        }

        // This part keeps the frame rate.
        std::this_thread::sleep_until(m_EndFrame);
        m_BeginFrame = m_EndFrame;
        m_EndFrame = m_BeginFrame + invFpsLimit;
    }
}

In C++17 and forward, I recommend constructing invFpsLimit with round instead of duration_cast for slightly better accuracy:

auto invFpsLimit = round<system_clock::duration>(dsec{1./fpsLimit()});

The documentation of sleep_until says:

The function also may block for longer than until after sleep_time has been reached due to scheduling or resource contention delays.

If you really need exact fps use either vSync, or replace the if block in your code with the following loop which continually does nothing until the frame time is used up:

while (m_WorkTime < invFpsLimit)
{
    m_EndFrame = std::chrono::system_clock::now();
    m_WorkTime = m_EndFrame - m_BeginFrame;
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!