0

我正在尝试创建一个函数,该函数允许我输入所需的每秒帧数和最大帧数,然后在固定的时间步长上将函数“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;
}
4

2 回答 2

2

您睡眠的时间受系统时钟频率的限制。频率默认为 64 Hz,因此您最终会看到以 16 毫秒为增量的睡眠。任何小于 16 毫秒的睡眠将至少持续 16 毫秒 - 根据 CPU 负载,它可能会更长。同样,20 毫秒的睡眠可能会被四舍五入到 32 毫秒。

您可以通过调用 timeBeginPeriod(...) 和 timeEndPeriod(...) 来更改此周期,这可以将睡眠精度提高到 1ms。如果您查看 VLC Player 等多媒体应用程序,您会发现它们使用这些功能来获得可靠的帧计时。请注意,这会更改系统范围的调度速率,因此会影响笔记本电脑的电池寿命。

更多信息: http: //msdn.microsoft.com/en-us/library/windows/desktop/dd757624%28v=vs.85%29.aspx http://msdn.microsoft.com/en-us/library/ windows/桌面/ms686298%28v=vs.85%29.aspx

于 2015-01-14T23:47:02.650 回答
0

等待计时器比 更准确Sleep,并且还更好地与 GUI 消息循环集成(替换GetMessageMsgWaitForMultipleObjects)。我之前已经成功地将它们用于图形计时。

它们不会为您提供高精度,例如以亚毫秒时间控制串行或网络输出,但 UI 更新无论如何都会受到 VSYNC 的限制。

于 2015-01-14T23:44:19.310 回答