Directx11学习笔记【七】 游戏定时器的实现
无论是在动画还是在一些游戏中,定时器总是必不可少的,游戏的帧数动画的播放等都离不开定时器的控制。这里以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*)¤tTime);
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*)(¤tTime)); 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*)¤tTime); m_stopTime = currentTime;
m_isStopped = true;
}
}
注释已经很详细了,类中函数和变量的作用也很明显。构造函数主要是获得根机器相关的变量,得到两次计数之间的时间差。
定时第一次工作是应调用Reset()初始化,以后在每一帧中调用Tick()更新计时器的各种变量。通过TotalTime()和DeltaTime()可以得到相关时间信息,用Stop()和Start()
分别暂停和恢复定时器。
Directx11学习笔记【七】 游戏定时器的实现的更多相关文章
- Directx11学习笔记【九】 3D渲染管线
原文:Directx11学习笔记[九] 3D渲染管线 原文地址:http://blog.csdn.net/bonchoix/article/details/8298116 3D图形学研究的基本内容,即 ...
- Directx11学习笔记【一】 最简单的windows程序HelloWin
声明:本系列教程代码有部分来自dx11龙书及dx11游戏编程入门两本书,后面不再说明 首先,在vs2013中创建一个空的解决方案Dx11Demo,以后的工程都会放在这个解决方案下面.然后创建一个win ...
- Linux学习笔记(七) 查询系统
1.查看命令 (1)man 可以使用 man 命令名称 命令查看某个命令的详细用法,其显示的内容如下: NAME:命令名称 SYNOPSIS:语法 DESCRIPTION:说明 OPTIONS:选项 ...
- (转)Qt Model/View 学习笔记 (七)——Delegate类
Qt Model/View 学习笔记 (七) Delegate 类 概念 与MVC模式不同,model/view结构没有用于与用户交互的完全独立的组件.一般来讲, view负责把数据展示 给用户,也 ...
- Directx11学习笔记【二十二】 用高度图实现地形
本文由zhangbaochong原创,转载请注明出处http://www.cnblogs.com/zhangbaochong/p/5827714.html 在前面我们曾经实现过简单的地形(Direct ...
- Directx11学习笔记【二】 将HelloWin封装成类
我们把上一个教程的代码封装到一个类中来方便以后的使用. 首先新建一个空工程叫做MyHelloWin,添加一个main.cpp文件,然后新建一个类叫做MyWindow,将于窗体有关的操作封装到里面 My ...
- Learning ROS for Robotics Programming Second Edition学习笔记(七) indigo PCL xtion pro live
中文译著已经出版,详情请参考:http://blog.csdn.net/ZhangRelay/article/category/6506865 Learning ROS forRobotics Pro ...
- Typescript 学习笔记七:泛型
中文网:https://www.tslang.cn/ 官网:http://www.typescriptlang.org/ 目录: Typescript 学习笔记一:介绍.安装.编译 Typescrip ...
- muduo网络库学习笔记(三)TimerQueue定时器队列
目录 muduo网络库学习笔记(三)TimerQueue定时器队列 Linux中的时间函数 timerfd简单使用介绍 timerfd示例 muduo中对timerfd的封装 TimerQueue的结 ...
- python3.4学习笔记(七) 学习网站博客推荐
python3.4学习笔记(七) 学习网站博客推荐 深入 Python 3http://sebug.net/paper/books/dive-into-python3/<深入 Python 3& ...
随机推荐
- C# 开发Chrome内核浏览器(WebKit.net)
原文地址:http://www.cnblogs.com/linyijia/p/4045333.html
- 【mysql】关于子查询的一个例子
假设表my_tbl包含三个字段a,b,c:现在需要查询表中列a的每个不同值下的列b为最小值的记录量. 比如表记录为: a b c 1 3 'cd' 2 3 'nhd' 1 5 'bg' ...
- c语言来实现c++
闲来没事,看了看sqlite的源代码,突然想用c实现c++,写了例如以下demo,自我感觉不错 #include <stdio.h> #include <stdlib.h> s ...
- Unreal Engine 4 RenderTarget制作Live Camera效果
Unreal Engine 4 RenderTarget制作Live Camera效果 先上效果: Live Camera我不知道怎么翻译.反正意思就是将一个摄影机的Image渲染到一个2D平面上. ...
- spring的长处 ioc aop
spring 的长处? 1.减少了组件之间的耦合性 ,实现了软件各层之间的解耦 2.能够使用easy提供的众多服务.如事务管理,消息服务等 3.容器提供单例模式支持 4.容器提供了AOP技术,利用它非 ...
- JS 数字 、中文、 英文、判断
<pre name="code" class="html">单独的验证: 利用正则表达式限制网页表单里的文本框输入内容: 用正则表达式限制只能输入中 ...
- 怎样在万网加入Lync Online SRV记录
万网已经支持SRV记录解析了,可是有好几个朋友问我怎么加入SRV记录(假设域名提供商不支持,能够通过DNSPOD来实现),过程例如以下 1:绑定域名至Office 365 略,请查看我的视频或者博客中 ...
- Hibernate主键生成策略简单总结
数据库表主键的知识点: Generator 为每个 POJO 的实例提供唯一标识. 一般情况,我们使用"native".class 表示采用由生成器接口net.sf.hiberna ...
- 漫游Kafka介绍章节简介
原文地址:http://blog.csdn.net/honglei915/article/details/37564521 介绍 Kafka是一个分布式的.可分区的.可复制的消息系统.它提供了普通消息 ...
- Windows7在自由的虚拟机(微软官方虚拟机)
Windows7在自由的虚拟机(微软官方虚拟机) 前言: 不是说windows7自带的虚拟机最好用,但他的正式版.免费.只是希望你能windows7用户.它将能够自由使用: 还是Vmware. 微软为 ...