我正在尝试创建一个函数,允许我输入每秒所需的帧数和最大帧数,然后使用函数" cout"固定时间步骤到控制台。我正在使用Sleep()以避免忙碌等待。我似乎让程序睡眠时间比它需要的时间长,因为它一直停留在我认为的睡眠命令上。你能帮帮我吗?我在理解时间方面遇到了一些麻烦,特别是在Windows上。
最终,我可能会使用这种计时方法来为一个简单的游戏计时,制作动画,也许就像乒乓球一样,甚至是一个可以加速对象的简单程序。我想我已经理解GDI和wasapi足以在屏幕上播放声音和显示颜色,所以现在我需要了解时机。我在互联网上问这个问题之前已经找了很长时间,我确信我错过了一些东西,但我不能完全把手指放在它上面:( 这是代码:
#include <windows.h>
#include <iostream>
// in this program i am trying to make a simple function that prints frame: and the number frame in between fixed time intervals
// i am trying to make it so that it doesn't do busy waiting
using namespace std;
void frame(LARGE_INTEGER& T, LARGE_INTEGER& T3, LARGE_INTEGER& DELT,LARGE_INTEGER& DESI, double& framepersec,unsigned long long& count,unsigned long long& maxcount,bool& on, LARGE_INTEGER& mili)
{
QueryPerformanceCounter(&T3); // seccond measurement
DELT.QuadPart = &T3.QuadPart - &T.QuadPart; // getting the ticks between the time measurements
if(DELT.QuadPart >= DESI.QuadPart) {count++; cout << "frame: " << count << " !" << endl; T.QuadPart = T3.QuadPart; } // adding to the count by just one frame (this may cause problems if more than one passes)
if(count > maxcount) {on = false;} // turning off the loop
else {DESI.QuadPart = T.QuadPart + DESI.QuadPart;//(long long)framepersec; // setting the stop tick
unsigned long long sleep = (( DESI.QuadPart - DELT.QuadPart) / mili.QuadPart);
cout << sleep << endl;
Sleep(sleep);} // sleeping to avoid busy waiting
}
int main()
{
LARGE_INTEGER T1, T2, Freq, Delta, desired, mil;
bool loopon = true; // keeps the loop flowing until max frames has been reached
QueryPerformanceFrequency(&Freq); // getting num of updates per second
mil.QuadPart = Freq.QuadPart / 1000; // getting the number clock updates that occur in a millisecond
double framespersec; // the number of clock updates that occur per target frame
unsigned long long framecount,maxcount; //to stop the program after a certain amount of frames
framecount = 0;
cout << "Hello world! enter the amount of frames per second : " << endl;
cin >> framespersec;
cout << "you entered: " << framespersec << " ! how many max frames?" << endl;
cin >> maxcount;
cout << "you entered: " << maxcount << " ! now doing the frames !!!" << endl;
desired.QuadPart = (Freq.QuadPart / framespersec);
while(loopon == true) {
frame(T1, T2, Delta, desired, framespersec, framecount, maxcount,loopon, mil);
}
cout << "all frames are done!" << endl;
return 0;
}
答案 0 :(得分:2)
您睡觉的时间受系统时钟频率的限制。频率默认为64 Hz,因此您最终会以16ms的增量看到睡眠。任何小于16毫秒的睡眠时间至少为16毫秒 - 根据CPU负载的不同,它可能会更长。同样,20ms的睡眠可能会被舍入到32ms。
您可以通过调用timeBeginPeriod(...)和timeEndPeriod(...)来更改此句点,这可以将睡眠精度提高到1毫秒。如果你看看像VLC播放器这样的多媒体应用程序,你会发现他们使用这些功能来获得可靠的帧定时。请注意,这会改变系统范围的调度速率,因此会影响笔记本电脑的电池寿命。
更多信息: http://msdn.microsoft.com/en-us/library/windows/desktop/dd757624%28v=vs.85%29.aspx http://msdn.microsoft.com/en-us/library/windows/desktop/ms686298%28v=vs.85%29.aspx
答案 1 :(得分:0)
等待定时器比Sleep
更准确,并且还可以更好地与GUI消息循环集成(将GetMessage
替换为MsgWaitForMultipleObjects
)。我之前已成功使用它们进行图形计时。
他们不会让你获得高精度,例如在亚毫秒时间控制串行或网络输出,但UI更新仍受VSYNC的限制。