首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用std限制fps::chrono

用std限制fps::chrono
EN

Stack Overflow用户
提问于 2019-03-15 21:56:05
回答 3查看 1.9K关注 0票数 4
代码语言:javascript
复制
std::chrono::system_clock::time_point m_BeginFrame = std::chrono::system_clock::now();
std::chrono::system_clock::time_point m_EndFrame = std::chrono::system_clock::now();
std::chrono::nanoseconds m_WorkTime = std::chrono::nanoseconds::zero();
std::chrono::nanoseconds m_WaitTime = std::chrono::nanoseconds::zero();
auto invFpsLimit = std::chrono::nanoseconds(1e9 / fpsLimit());

// main loop
while (!glfwWindowShouldClose(m_pScreen->glfwWindow()))
{
    m_WaitTime = m_BeginFrame - m_EndFrame;
    m_EndFrame = std::chrono::system_clock::now();
    m_WorkTime = m_EndFrame - m_BeginFrame;

    // if need sleep
    if (m_WorkTime < invFpsLimit)
    {
        std::this_thread::sleep_until(m_BeginFrame + invFpsLimit);
        m_DeltaTime = invFpsLimit;
    }
    else
    {
       m_DeltaTime = m_WorkTime;
    }

    m_BeginFrame = std::chrono::system_clock::now();

    TRACE("   %f   %u   %u   %u",
            ((float)1e9 / (float)(m_WaitTime.count() + m_WorkTime.count())),
            m_WorkTime.count(),
            m_WaitTime.count(),
            invFpsLimit.count());


    // think and opengl stuff...
}

我试图用这段代码来限制fps,但是Fraps向我展示了大约56-57的值。

代码语言:javascript
复制
58.848454   3175500   13817300   16666666
55.259304   3314200   14782300   16666666
58.923698   2321700   14649400   16666666
56.200928   2167400   15625900   16666666
52.774071   3188200   15760500   16666666
50.600887   4899700   14862800   16666666
65.011055   2347500   13034500   16666666
54.966499   2611700   15581200   16666666
55.605911   2653400   15330300   16666666
56.476437   2386100   15320400   16666666
55.280689   2581400   15508100   16666666
56.437550   2355400   15363300   16666666
47.170700   5535900   15663700   16666666
64.713608   3039700   12413000   16666666
56.136570   2941100   14872600   16666666
53.444496   3624200   15086800   16666666
60.074493   2397500   14248500   16666666
51.737339   3777100   15551300   16666666
59.369026   3665800   13178000   16666666
59.355282   3543900   13303800   16666666
54.243759   3961000   14474300   16666666
45.764706   7823500   14027400   16666666
61.242237   6239400   10089200   16666666
73.396652   2013800   11610800   16666666
50.531849   3824000   15965500   16666666
62.895454   2796000   13103400   16666666
60.611572   2360500   14138000   16666666
56.074242   2241700   15591800   16666666
55.143208   2454800   15679800   16666666

我试着把时钟换成system_clock,使用sleep_for而不是sleep_untill,没有什么工作。

有什么特别的事情,我不知道的std时钟或工作代码,我看不到?

偷我的fps是什么?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2019-03-16 01:49:26

通过使用m_BeginFrame而不是system_clock::now()更新invFpsLimitm_EndFrame可以做得更好。这看起来可能类似于:

代码语言:javascript
复制
#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;
    }
}

在C++17和forward中,为了获得更高的精度,我建议使用round而不是duration_cast构造invFpsLimit

代码语言:javascript
复制
auto invFpsLimit = round<system_clock::duration>(dsec{1./fpsLimit()});
票数 5
EN

Stack Overflow用户

发布于 2020-09-26 16:48:01

为了获得增量,您可以这样做:

代码语言:javascript
复制
unsgined deltaTime = 1000.0f / frame_count_per_fps; // In milliseconds
票数 1
EN

Stack Overflow用户

发布于 2019-03-15 22:48:10

sleep_until说:

由于调度或资源争用延迟,该函数还可以在到达sleep_time之前阻塞更长的时间。

如果您确实需要确切的fps,可以使用vSync,或者用下面的循环替换代码中的If块,直到帧时间用完为止,这个循环一直不做任何事情:

代码语言:javascript
复制
while (m_WorkTime < invFpsLimit)
{
    m_EndFrame = std::chrono::system_clock::now();
    m_WorkTime = m_EndFrame - m_BeginFrame;
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55191160

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档