无论是在动画还是在一些游戏中,定时器总是必不可少的,游戏的帧数动画的播放等都离不开定时器的控制。这里以dx11龙书中提供的定时器为例,具体看看是怎么实现一个简单但精度高使用方便的定时器的。

  这个定时器使用的windows中的高精度计时函数QueryPerformanceCounter和QueryPerformanceFrequency

BOOL QueryPerformanceCounter(  LARGE_INTEGER* lpPerformanceCount );
BOOL QueryPerformanceFrequency( LARGE_INTEGER* lpFrequency );
 QueryPerformanceCounter函数以计数为单位,因为不同的机器中两次计数之间的差值可能不同,所以就需要QueryPerformanceFrequency函数 返回1s内计数的个数
__int64 countsPerSec;
QueryPerformanceFrequency((LARGE_INTEGER*)&countsPerSec);
m_secondsPerCount = 1.0 / countsPerSec;

  通过这样便可以得到系统两次计数之间的时间差,这是定时器把时间转换为秒的基准。

  下面看看这个定时器类GameTimer的具体实现

  GameTimer.h

 #ifndef GAMETIMER_H
#define GAMETIMER_H class GameTimer
{
public:
GameTimer();
float TotalTime() const;//返回定时器从计时开始到现在的总时间,不包括暂停时间
float DeltaTime() const;//返回本次计时与上次计时之间的时间差 void Reset();//重置
void Start();//暂停后恢复计时
void Stop();//暂停
void Tick();//计时一次,每一帧调用 private:
double m_secondsPerCount;//系统相关,系统两次计数之间的时间差,是定时器把时间转换为s的基准
double m_deltaTime;//距离上次计时的时间差 __int64 m_baseTime;//定时器开始工作的时间点
__int64 m_pausedTime;//暂停的总时间
__int64 m_stopTime;//暂停的开始时间
__int64 m_prevTime;//上次计时的时间点
__int64 m_currTime;//本次计时的时间点 bool m_isStopped;//是否暂停
}; #endif //GAMETIMER_H

  

  GameTimer.cpp

 #include "GameTimer.h"
#include <windows.h> GameTimer::GameTimer() : m_secondsPerCount(0.0), m_deltaTime(-1.0), m_baseTime(), m_pausedTime(),
m_prevTime(), m_currTime(), m_isStopped(false)
{
__int64 countsPerSec;
QueryPerformanceFrequency((LARGE_INTEGER*)&countsPerSec);
m_secondsPerCount = 1.0 / countsPerSec;
} float GameTimer::TotalTime() const
{
if (m_isStopped)
{
return static_cast<float>((m_stopTime - m_baseTime - m_pausedTime)*m_secondsPerCount);
}
else
{
return static_cast<float>((m_currTime - m_baseTime - m_pausedTime)*m_secondsPerCount);
}
} float GameTimer::DeltaTime() const
{
return static_cast<float>(m_deltaTime);
} void GameTimer::Tick()
{
if (m_isStopped)
{
m_deltaTime = 0.0;
return;
}
//得到这一帧的时间
__int64 currentTime;
QueryPerformanceCounter((LARGE_INTEGER*)&currentTime);
m_currTime = currentTime; //两次计时之间的时间
m_deltaTime = (m_currTime - m_prevTime) * m_secondsPerCount; m_prevTime = m_currTime; if (m_deltaTime < 0.0)
m_deltaTime = 0.0;
} void GameTimer::Reset()
{
__int64 currentTime;
QueryPerformanceCounter((LARGE_INTEGER*)(&currentTime)); m_baseTime = currentTime;
m_prevTime = currentTime;
m_stopTime = ;
m_isStopped = false;
} void GameTimer::Start()
{
__int64 startTime;
QueryPerformanceCounter((LARGE_INTEGER*)&startTime); if (m_isStopped)
{
//更新暂停的总时间
m_pausedTime += (startTime - m_stopTime); m_prevTime = startTime; //不再暂停
m_stopTime = ;
m_isStopped = false;
}
} void GameTimer::Stop()
{
if (!m_isStopped)
{
__int64 currentTime;
QueryPerformanceCounter((LARGE_INTEGER*)&currentTime); m_stopTime = currentTime;
m_isStopped = true;
}
}

  注释已经很详细了,类中函数和变量的作用也很明显。构造函数主要是获得根机器相关的变量,得到两次计数之间的时间差。

  定时第一次工作是应调用Reset()初始化,以后在每一帧中调用Tick()更新计时器的各种变量。通过TotalTime()和DeltaTime()可以得到相关时间信息,用Stop()和Start()

分别暂停和恢复定时器。

Directx11学习笔记【七】 游戏定时器的实现的更多相关文章

  1. Directx11学习笔记【九】 3D渲染管线

    原文:Directx11学习笔记[九] 3D渲染管线 原文地址:http://blog.csdn.net/bonchoix/article/details/8298116 3D图形学研究的基本内容,即 ...

  2. Directx11学习笔记【一】 最简单的windows程序HelloWin

    声明:本系列教程代码有部分来自dx11龙书及dx11游戏编程入门两本书,后面不再说明 首先,在vs2013中创建一个空的解决方案Dx11Demo,以后的工程都会放在这个解决方案下面.然后创建一个win ...

  3. Linux学习笔记(七) 查询系统

    1.查看命令 (1)man 可以使用 man 命令名称 命令查看某个命令的详细用法,其显示的内容如下: NAME:命令名称 SYNOPSIS:语法 DESCRIPTION:说明 OPTIONS:选项 ...

  4. (转)Qt Model/View 学习笔记 (七)——Delegate类

    Qt Model/View 学习笔记 (七) Delegate  类 概念 与MVC模式不同,model/view结构没有用于与用户交互的完全独立的组件.一般来讲, view负责把数据展示 给用户,也 ...

  5. Directx11学习笔记【二十二】 用高度图实现地形

    本文由zhangbaochong原创,转载请注明出处http://www.cnblogs.com/zhangbaochong/p/5827714.html 在前面我们曾经实现过简单的地形(Direct ...

  6. Directx11学习笔记【二】 将HelloWin封装成类

    我们把上一个教程的代码封装到一个类中来方便以后的使用. 首先新建一个空工程叫做MyHelloWin,添加一个main.cpp文件,然后新建一个类叫做MyWindow,将于窗体有关的操作封装到里面 My ...

  7. Learning ROS for Robotics Programming Second Edition学习笔记(七) indigo PCL xtion pro live

    中文译著已经出版,详情请参考:http://blog.csdn.net/ZhangRelay/article/category/6506865 Learning ROS forRobotics Pro ...

  8. Typescript 学习笔记七:泛型

    中文网:https://www.tslang.cn/ 官网:http://www.typescriptlang.org/ 目录: Typescript 学习笔记一:介绍.安装.编译 Typescrip ...

  9. muduo网络库学习笔记(三)TimerQueue定时器队列

    目录 muduo网络库学习笔记(三)TimerQueue定时器队列 Linux中的时间函数 timerfd简单使用介绍 timerfd示例 muduo中对timerfd的封装 TimerQueue的结 ...

  10. python3.4学习笔记(七) 学习网站博客推荐

    python3.4学习笔记(七) 学习网站博客推荐 深入 Python 3http://sebug.net/paper/books/dive-into-python3/<深入 Python 3& ...

随机推荐

  1. HDU 2255 奔小康,赚钱(KM算法模板)

    解决问题的思路: 二部图,正确的匹配,卡费用流,使用KM算法. #include <cstring> #include <algorithm> #include <cst ...

  2. [华为机试练习题]50.求M的N次方的最后三位

    题目 描写叙述: 正整数M 的N次方有可能是一个很大的数字,我们仅仅求该数字的最后三位 例1: 比方输入5和3 ,5的3次方为125.则输出为125 例2: 比方输入2和10 2的10次方为1024 ...

  3. hdu5119(dp)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5119 分析:dp[i][j]表示由前i个数组成异或和为j的方法数,则dp[i][j]=d[i-1][j ...

  4. Oracle数据库案例整理-Oracle系统执行时故障-Shared Pool内存不足导致数据库响应缓慢

    1.1       现象描写叙述 数据库节点响应缓慢,部分用户业务受到影响. 查看数据库告警日志,開始显示ORA-07445错误,然后是大量的ORA-04031错误和ORA-00600错误. 检查数据 ...

  5. Python-方法重载的问题

    定义一个父类,在写一个子类继承他,重载他的foo方法: class Father: def foo(self): print"I am father" class Son(Fath ...

  6. jeecg 3.5.2 新版本号4种首页风格 【经典风格,shortcut风格,ACE bootstrap风格,云桌面风格】

    [1]经典风格: [2]Shortcut风格: [3]ACE bootsrap风格: [4]云桌面风格: [5]自己定义图表 watermark/2/text/aHR0cDovL2Jsb2cuY3Nk ...

  7. 将Eclipse包括第一3正方形jar包裹Project Export并产生能够执行jar

    于Project对,Export-Java-Runnable JAR file.需要注意的是一定要选择"Package required libraries into generated J ...

  8. DOM解析XML文件实例

    XML文件: response: <?xml version="1.0"?> <soap:Envelope xmlns:soap="http://www ...

  9. Android HAL

  10. 泛型Binary Search Tree实现,And和STL map比较的经营业绩

    问题叙述性说明: 1.binary search tree它是一种二进制树的.对于key值.比当前节点左孩子少大于右子. 2.binary search tree不是自平衡树.所以,当插入数据不是非常 ...