【问题标题】:WM_TIMER with higher priority?具有更高优先级的 WM_TIMER?
【发布时间】:2015-07-20 19:19:25
【问题描述】:

我希望我的小游戏在标题中显示 FPS,但它不应该重新计算每一帧的 FPS。我只想每秒刷新一次 FPS 计数器,所以我尝试使用SetTimer。问题是定时器只有在我不移动鼠标或按住键时才起作用。据我所知WM_TIMER 是一个低优先级的消息,所以它最后被处理。 有没有办法在任何其他用户输入消息之前处理WM_TIMER 消息,或者至少有另一种方法来创建第二个计时器?

我也尝试使用TimerProc 而不是等待WM_TIMER,但这也不起作用。

【问题讨论】:

  • 使用TimerProc 不起作用,因为它依赖于WM_TIMER 处理。
  • 如果您正在计算帧数以计算帧率,只要计数达到 N(其中 N 是每秒的当前帧率)就触发更新。
  • 我尝试将此作为临时解决方案。剩下的唯一问题是我的 FPS 可能会有所不同。所以 FPS 计数器会不规则地刷新(最​​小)。
  • 或者您可以使用 GetTickCount 记录更新 FPS 的时间。每次绘制新帧时,再次调用 GetTickCount,如果经过一秒钟,则再次更新 FPS。
  • 您还可以启动一个单独的线程,该线程休眠 1 秒,读取每次绘制帧时递增的计数器,最后将计数器设置为零。如果你可以访问 C++11,你可以很容易地用一个额外的线程、一个计数器和一个互斥锁来做到这一点。这样就变得简单了。

标签: c++ winapi timer


【解决方案1】:

如何使用单独的后台线程对其进行测量的简短示例。

int iCount;
int iFramesPerSec;
std::mutex mtx;

// this function runs in a separate thread
void frameCount()
{
    while(true){
        std::this_thread::sleep_for(std::chrono::seconds(1));

        std::lock_guard<std::mutex> lg{mtx}; // synchronize access
        iFramesPerSec = iCount; // frames per second during last second that passed
        iCount = 0;
    }
}

// inside window procedure
case WM_PAINT:
    hdc = BeginPaint(hwnd, &ps);
    ...

    std::lock_guard<std::mutex> lg{mtx}; // synchronize access
    ++iCount;
    EndPaint(hwnd, &ps);
    return 0;

【讨论】:

  • 如果我希望线程在一秒钟内只覆盖一次iFramesPerSec,我是否只需在循环末尾添加一个Sleep(1000)
  • iFramesPerSec 每秒只更新一次,因为 while 循环在每次迭代中首先暂停 1 秒。
  • 哦,对不起,我瞎了,我明白了:D
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-12-09
  • 2021-02-25
  • 2017-02-20
  • 2015-05-09
  • 1970-01-01
  • 1970-01-01
  • 2018-12-02
相关资源
最近更新 更多