timeGetTime()start变量大于end变量

时间:2015-09-19 16:08:10

标签: c++ windows ogre

我正在使用timeGetTime()将帧速率限制为每秒60帧。我打算这样做的方法是获得渲染所述60帧所需的时间,然后使用Sleep等待第二秒的剩余时间。但由于某种原因timeGetTime()在我第一次调用它时返回的数字大于在我渲染60帧之后调用它时的数字。

以下是代码:

标题

#ifndef __TesteMapa_h_
#define __TesteMapa_h_
#include "BaseApplication.h"
#include "Mundo.h"

class TesteMapa : public BaseApplication{
public:
    TesteMapa()
    virtual ~TesteMapa();

protected:
    virtual void createScene();

    virtual bool frameRenderingQueued(const Ogre::FrameEvent& evt);
    virtual bool frameEnded(const Ogre::FrameEvent& evt);

    virtual bool keyPressed(const OIS::KeyEvent &evt);
    virtual bool keyReleased(const OIS::KeyEvent &evt);

private:
    Mundo mundo = Mundo(3,3,3);
    short altura, largura, passos, balanca, framesNoSegundo=0;
    Ogre::SceneNode *noSol, *noSolFilho, *noCamera;
    DWORD inicioSegundo = 0, finala;//inicioSegundo is the start variable and finala the ending variable
};
#endif 

CPP相关功能

bool TesteMapa::frameEnded(const Ogre::FrameEvent& evt){
    framesNoSegundo++;

    if (inicioSegundo == 0)
        inicioSegundo = timeGetTime();
    else{
        if (framesNoSegundo == 60){
            finala = timeGetTime(); //getting this just to see the value being returned
            Sleep(1000UL - (timeGetTime() - inicioSegundo));
            inicioSegundo = 0;
            framesNoSegundo = 0;
        }
    }
    return true;
}

我在主要功能中使用timeBeginPeriod(1)timeEndPeriod(1)

1 个答案:

答案 0 :(得分:1)

如果您使用的是Visual Studio 2013或更早版本,则std :: chrono使用64hz自动收录器(每个刻度15.625毫秒),这很慢。 VS 2015应该解决这个问题。您可以使用QueryPerformanceCounter。以下是以固定频率运行且无漂移的示例代码,因为延迟基于计数器的原始读数。 dwLateStep是一个调试辅助工具,如果一个或多个步骤花费的时间太长,它会增加。该代码与Windows XP兼容,其中Sleep(1)最多可能需要2 ms,这就是为什么代码只有在有2 ms或更长时间延迟时才会进入休眠状态。

typedef unsigned long long UI64;        /* unsigned 64 bit int */
#define FREQ    60                      /* frequency */
DWORD    dwLateStep;                    /* late step count */
LARGE_INTEGER liPerfFreq;               /* 64 bit frequency */
LARGE_INTEGER liPerfTemp;               /* used for query */
UI64 uFreq = FREQ;                      /* thread frequency */
UI64 uOrig;                             /* original tick */
UI64 uWait;                             /* tick rate / freq */
UI64 uRem = 0;                          /* tick rate % freq */
UI64 uPrev;                             /* previous tick based on original tick */
UI64 uDelta;                            /* current tick - previous */
UI64 u2ms;                              /* 2ms of ticks */
UI64 i;

    /* ... */ /* wait for some event to start thread */
    QueryPerformanceFrequency(&liPerfFreq);
    u2ms = ((UI64)(liPerfFreq.QuadPart)+499) / ((UI64)500);

    timeBeginPeriod(1);                 /* set period to 1ms */
    Sleep(128);                         /* wait for it to stabilize */

    QueryPerformanceCounter(&liPerfTemp);
    uOrig = uPrev = liPerfTemp.QuadPart;

    for(i = 0; i < (uFreq*30); i++){
        /* update uWait and uRem based on uRem */
        uWait = ((UI64)(liPerfFreq.QuadPart) + uRem) / uFreq;
        uRem  = ((UI64)(liPerfFreq.QuadPart) + uRem) % uFreq;
        /* wait for uWait ticks */
        while(1){
            QueryPerformanceCounter((PLARGE_INTEGER)&liPerfTemp);
            uDelta = (UI64)(liPerfTemp.QuadPart - uPrev);
            if(uDelta >= uWait)
                break;
            if((uWait - uDelta) > u2ms)
                Sleep(1);
        }
        if(uDelta >= (uWait*2))
            dwLateStep += 1;
        uPrev += uWait;
        /* fixed frequency code goes here */
        /*  along with some type of break when done */
    }

    timeEndPeriod(1);                   /* restore period */