Windows中的钳制帧速率

问题描述 投票:0回答:1

我有一个简单的循环

LARGE_INTEGER ticks_per_second;
::QueryPerformanceFrequency(&ticks_per_second);

MSG msg = { 0 };
while (true)
{
    if (msg.message == WM_QUIT)
        exit(0);

    if (::PeekMessageW(&msg, NULL, 0U, 0U, PM_REMOVE))
    {
        ::TranslateMessage(&msg);
        ::DispatchMessageW(&msg);
        continue;
    }

    static double last_time_s = 0;

    LARGE_INTEGER cur_time_li;
    ::QueryPerformanceCounter(&cur_time_li);
    double cur_time_s = (double)cur_time_li.QuadPart / (double)ticks_per_second.QuadPart;

    double diff_s = cur_time_s - last_time_s;
    double rate_s = 1 / 30.0f;

    uint32_t slept_ms = 0;
    if (diff_s < rate_s)
    {
        slept_ms = (uint32_t)((rate_s - diff_s) * 1000.0);
        ::Sleep(slept_ms);
    }

    update();

    ::printf("updated %f %u\n", diff_s, slept_ms);

    last_time_s = cur_time_s;
}

并且希望每秒调用update()30次,但不要更频繁有了这段代码,它就出错了,在控制台中,我得到这样的东西:

updated 0.031747 1
updated 0.001997 31
updated 0.031912 1
updated 0.001931 31
updated 0.031442 1
updated 0.002084 31

哪个似乎仅对第一次更新才是正确的,第二次就太快了,我不明白为什么我知道更新,PeekMessageW等也浪费时间,但是即使我创建了一个while(true)循环并注释了update(),它仍然在打印类似的结果我在关闭vsync的情况下使用DirectX 11进行渲染(在更新功能中进行渲染):

g_pSwapChain->Present(0, 0);

如何修复代码以使一秒钟内被调用30次的update()稳定?

c++ c windows winapi directx
1个回答
0
投票

我不认为强制翻倍是个好主意。我会运行类似这样的内容:

static LARGE_INTEGER last_time_s = { 0 };

::QueryPerformanceCounter(&cur_time_li);
time_diff_microsec.QuadPart = cur_time_li.QuadPart  - last_time_s.QuadPart;
// To avoid precision lost, convert to seconds *before* dividing by ticks-per-second.
time_diff_microsec.QuadPart *= 1000000;
time_diff_microsec.QuadPart /= ticks_per_second.QuadPart;

double rate_s = 1 / 30.0f;
uint32_t slept_ms = 0;
if (time_diff_microsec.QuadPart >= rate_s)//    if (diff_s < rate_s)
{
  //  slept_ms = (uint32_t)(rate_s - time_diff_microsec.LowPart);// *1000.0);
  //  ::Sleep(slept_ms);
  //}

  //update();

  ::printf("updated %lld %u\n", time_diff_microsec.QuadPart, slept_ms);
}
last_time_s.QuadPart = time_diff_microsec.QuadPart/ 1000000;

}

只是简短的“草图”。尚未验证计算是否正确。

© www.soinside.com 2019 - 2024. All rights reserved.