DirectX11入门笔记---计时器实现

image-20201217210042177

计时器

计时器支持暂停,开始,重置,每帧调用功能,程序中每一帧调用一次计数,并随时返回距离上一次计数之间的差值。这个差值就是控制游戏、动画更新的最重要的数据。

这个定时器用到了Windows中高精度的计时函数:QueryPerformanceCounter(用于计算调用的时间差)

QueryPerformanceFrequency(返回计时器的计算频率,每秒的计算次数,用于转换秒的转换因子)

BOOL QueryPerformanceCounter(  LARGE_INTEGER* lpPerformanceCount );
BOOL QueryPerformanceFrequency(  LARGE_INTEGER* lpFrequency );

计时器类

#pragma once

// 计时器
class Timer
{
public:
    // 构造函数
    Timer();

    float TotalTime() const;        //返回从开始计时到现在的总时间
    float DeltaTime() const;        //返回时间差

    void Start();        //取消暂停时调用
    void Stop();        //暂停时调用
    void Reset();        //消息循环前调用
    void Tick();        //每帧调用

private:
    float secsPerCount;        //系统有关,把时间单位转换为秒的转换因子
    float deltaTime;        //时间差

    __int64 baseTime;        //计时器开始工作的起始时间点
    __int64 stopTime;        //暂停状态的起始时间点
    __int64 pauseTime;        //累计的暂停时间
    __int64 currTime;        //当前起始时间点
    __int64 prevTime;        //上次起始时间点

    bool IsStop;        //是否暂停

};
#include "Timer.h"
#include <Windows.h>

// 进行初始化
Timer::Timer():secsPerCount(0.0f),deltaTime(0),pauseTime(0),prevTime(0),
currTime(0),IsStop(false)
{
    //计算秒转换因子
    __int64 countPerSec;
    QueryPerformanceFrequency((LARGE_INTEGER*)&countPerSec);
    secsPerCount = 1.0f / (double)countPerSec;
}

float Timer::TotalTime() const
{
    //判断是否处于暂停状态
    if (IsStop)
    {
        return (float)((stopTime - pauseTime) - baseTime * secsPerCount);
    }
    else
    {
        return (float)((currTime - pauseTime) - baseTime * secsPerCount);
    }
}

float Timer::DeltaTime() const
{
    return deltaTime;
}

void Timer::Start()
{
    //记录当前时间
    __int64 currTime_Temp;
    QueryPerformanceCounter((LARGE_INTEGER*)&currTime_Temp);

    //判断是否处于暂停状态
    if (IsStop)
    {
        //添加上暂停的这段时间
        pauseTime += currTime_Temp - stopTime;
        //因为重新计时,所以我们要重新设置
        prevTime = currTime;
        stopTime = 0;
        IsStop = false;
    }
}

void Timer::Stop()
{
    //判断是否处于暂停状态
    if (!IsStop)
    {
        //记录暂停的时间
        __int64 currTime_Temp;
        QueryPerformanceCounter((LARGE_INTEGER*)&currTime_Temp);
        //设置暂停标志
        stopTime = currTime_Temp;
        IsStop = true;
    }
}

void Timer::Reset()
{
    __int64 currTime_Temp;
    QueryPerformanceCounter((LARGE_INTEGER*)&currTime_Temp);
    //因为重置计时器,所以baseTime,prevTime,stopTime要重新设置
    baseTime = currTime_Temp;
    prevTime = currTime_Temp;
    stopTime = 0;
    IsStop = false;
}

void Timer::Tick()
{
    //判断是否暂停
    if (IsStop)
    {
        deltaTime = 0.0;
        return;
    }

    //获取当前时间值
    __int64 currTime_Temp;
    QueryPerformanceCounter((LARGE_INTEGER*)&currTime_Temp);
    currTime = currTime_Temp;

    //计算时间差
    deltaTime = (currTime - prevTime) * secsPerCount;

    //为计算下一帧做准备
    prevTime = currTime;

    //确保deltaTime不是负值
    //出现负值的情况:1.处理器进入节电模式        2.切换到另外一个处理器
    if (deltaTime < 0)
    {
        deltaTime = 0;
    }
}
  • 版权声明: 本博客所有文章除特别声明外,著作权归作者所有。转载请注明出处!
  • Copyrights © 2015-2021 Opda
  • 访问人数: | 浏览次数:

请我喝杯咖啡吧~

支付宝
微信