我有一个双线程的窗口程序,其中一个线程会不定期向另一个线程发出重绘命令(通过SendMessage)
我想知道要怎么处理才能使帧数维持在60帧,即当重绘命令过于密集时,我需要怎么做才能适当地忽略掉一部分命令,而又不漏掉必要的命令使画面卡顿?
想过在 WndProc 用 Timer,但是听说精度不怎么样,如果直接开第三个线程的话又感觉太麻烦,我想知道能不能直接在 WndProc 层把这一问题搞定。
我有一个双线程的窗口程序,其中一个线程会不定期向另一个线程发出重绘命令(通过SendMessage)
我想知道要怎么处理才能使帧数维持在60帧,即当重绘命令过于密集时,我需要怎么做才能适当地忽略掉一部分命令,而又不漏掉必要的命令使画面卡顿?
想过在 WndProc 用 Timer,但是听说精度不怎么样,如果直接开第三个线程的话又感觉太麻烦,我想知道能不能直接在 WndProc 层把这一问题搞定。
如果你的60帧是手动模拟的,可以参考以下思路:
bool 需要重绘=false;
while(1){
while(有命令){ // 这里参考了windows对WM_PAINT消息的折叠优化(即此消息不会堆积)
switch(获取命令()){
case 重绘命令:
需要重绘=true;
break;
default:
break;
}
}
if(需要重绘){ // 此if的细节你可以自行调整
// 注:一般来说,有了上面的优化,程序既能以最高帧率运行,又能很大程度上减少资源浪费
// 但如果你对帧率有其它要求(如不希望程序超过100帧),则可使用下一行代码
等待直到时间对齐至60帧(); // 可使用Sleep+时间判断/计时器实现
// 注:可选使用timeBeginPeriod提升Sleep、计时器等的精度,但可能会显著缩短续航
// 建议做法是降低对精度的要求(或放弃60帧这个数字)
重绘();
需要重绘=false;
}else{
等待命令到来();
}
}
如果你的60帧指的是显卡的垂直同步:
代码类似上面,但 等待直到时间对齐至60帧() 这个函数需要替换为别的函数,不过关于等待垂直同步并没有一个十分完美的解决方案,这里提供几个可能性:
既然你稳定在 60 帧,那就肯定有计时器呗,自己计时,间隔小于一定时间的就忽略。
而且,你在写什么?
如果你在写普通窗口程序,没有哪个窗口程序是反复刷新的。UI 一般是有消息立刻刷新。
如果你在写游戏,也没有哪个程序是靠另一个线程来通知刷新的。常见的游戏主循环有两种,一种是能跑多少帧就跑多少帧,另一种是延时以确保多少帧刷新一次。都是在一个线程里。