【DirectX11】【学习笔记(12)】FPS实现

这一节我们学习如何制作一个高分辨率的定时器。这个可以用来确保我们的物体在1秒内的距离是确定的,不管我们的游戏每秒有60帧还是6帧(因为我们之前世界矩阵的变换是基于每一帧的)

Global Declarations

double countsPerSecond = 0.0;
__int64 CounterStart = 0;

int frameCount = 0;
int fps = 0;

__int64 frameTimeOld = 0;
double frameTime;

New and Modified Functions

void UpdateScene(double time);

void RenderText(std::wstring text, int inInt);

void StartTimer();
double GetTime();
double GetFrameTime();

我们创建了一些新的函数以及修改了一些之前的函数参数

updatescene我们把每一帧渲染的时间作为参数。

rendertext我们把FPS作为参数,让它显示(其实它已经是全局变量了,但是这样更清晰)

下面三个函数,第一个用来启动定时器。第二个用来测量我们我们距离start开始的时间,每一帧对framecount+1;每秒把值传入fps,然后清空framecount。第三个用来得到每帧的持续时间。

Timer Functions

我们这里调用两个win32函数

QueryPerformanceFrequency(),返回一个64位整数,代表每秒的计数。(频率)

我们使用QueryPerformanceCounter,得到当前时间的计数,也是一个64位整数。

所以starttimer函数把频率变量存储在countspersecond里,把当前时间存储在counterstart里

gettime函数得到当前时间,存储在current time里。我们从current里减去conterstart,得到从开始到现在的时间。然后我们除每秒钟的计数值,得到从开始到现在的秒数。

GetFrameTime函数基本上做了前两个函数的事情,除了找从开始到现在的时间,我们得到上一次调用这个函数的时间,然后返回每帧需要的秒数。这个可以用来保证我们的相机和动画平稳移动。

void StartTimer()
{
    LARGE_INTEGER frequencyCount;
    QueryPerformanceFrequency(&frequencyCount);

    countsPerSecond = double(frequencyCount.QuadPart);

    QueryPerformanceCounter(&frequencyCount);
    CounterStart = frequencyCount.QuadPart;
}

double GetTime()
{
    LARGE_INTEGER currentTime;
    QueryPerformanceCounter(&currentTime);
    return double(currentTime.QuadPart-CounterStart)/countsPerSecond;
}

double GetFrameTime()
{
    LARGE_INTEGER currentTime;
    __int64 tickCount;
    QueryPerformanceCounter(&currentTime);

    tickCount = currentTime.QuadPart-frameTimeOld;
    frameTimeOld = currentTime.QuadPart;

    if(tickCount < 0.0f)
        tickCount = 0.0f;

    return float(tickCount)/countsPerSecond;
}

The UpdateScene() Functions New Parameter

之前我们对于物体每帧都旋转一个固定值,如果30帧,物体就会转很慢,如果每秒300帧,物体就转很快。

现在我们把固定值乘每帧渲染的时间,如果时间长,固定值就大,如果时间段固定值就小。这样每秒转的角度都是一样的。

rot += 1.0f * time;

Add the New Param. To printString

printString << text <<inInt;

这样打印出来就是FPS:50。

Call the RenderText() Function, Passing in the FPS

RenderText(L"FPS: ", fps);
        frameCount++;
        if(GetTime() > 1.0f)
        {
            fps = frameCount;
            frameCount = 0;
            StartTimer();
        }    

        frameTime = GetFrameTime();

        UpdateScene(frameTime);

这里就是我们消息循环的部分,当超过一秒时,重新计数。

讲到这里,这节内容终于讲完拉~ 

本节内容的代码部分可以在我的github里面找到!

游戏开发路途遥远,但我相信只要坚持,总能到达彼岸!

如果我的文章对于你学习DirectX11有点帮助,欢迎评论给出建议,让我们一起学习进步!

                                                                                               ———————— 小明 2018.12.9 16.07

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值