原文:Directx11教程(9) 增加一个TimerClass类

     在上篇教程代码的基础上,我们增加一个TimerClass类,这个类的功能很简单,就是可以计算相邻2帧的时间差。利用这个时间差值,可以实现平滑的动画,使得动画不会因为不同机器fps不同,从而动画效果变快或者变慢。

    我们主要是利用QueryPerformanceCounter函数来查询定时器的计数值。

    如果硬件里有定时器,它会启动这个定时器,之后会不断获取定时器的值,这样的定时器精度,就跟硬件时钟的晶振一样精确的。

TimerClass.h代码如下:

#pragma once
#include <windows.h>

//主要用来计算相邻两帧之间的时间
//可以用来实现平滑的与fps无关的动画。
class TimerClass
    {
    public:
        TimerClass(void);
        TimerClass(const TimerClass&);
        ~TimerClass(void);
        bool Initialize();
        void Frame();

        float GetTime();

    private:
        INT64 m_frequency;
        float m_ticksPerMs;
        INT64 m_startTime;
        float m_frameTime;

    };

TimerClass.cpp代码如下:

#include "TimerClass.h"

TimerClass::TimerClass(void)
    {
    }

TimerClass::TimerClass(const TimerClass& other)
    {
    }

TimerClass::~TimerClass(void)
    {
    }

bool TimerClass::Initialize()
    {
   // 检测系统是否支持高精度计时器.
    QueryPerformanceFrequency((LARGE_INTEGER*)&m_frequency);
    if(m_frequency == 0)
        {
        return false;
        }

   // 得到每毫秒多少个计数器.
    m_ticksPerMs = (float)(m_frequency / 1000);

    QueryPerformanceCounter((LARGE_INTEGER*)&m_startTime);

    return true;
    }

//每个渲染帧都会被调用,从而计算出每帧之间的时间
void TimerClass::Frame()
    {
    INT64 currentTime;
    float timeDifference;

    QueryPerformanceCounter((LARGE_INTEGER*)& currentTime);

    timeDifference = (float)(currentTime - m_startTime);

    m_frameTime = timeDifference / m_ticksPerMs;

    m_startTime = currentTime;

    return;
    }

float TimerClass::GetTime()
    {
    return m_frameTime;
    }

我们在SystemClass.h中增加一些代码,包含TimerClass.h

…

#include "GraphicsClass.h"
#include "TimerClass.h"

const float PI     = 3.14159265358979323f;

class SystemClass
    { 
…

        GraphicsClass* m_Graphics;

        //计时器类
        TimerClass* m_Timer;
    };

 

SystemClass.cpp代码如下,我只贴出了修改了代码的函数。

#include "SystemClass.h"

SystemClass::SystemClass(void)
    {
    m_Input = 0;
    m_Graphics = 0;

    m_Timer = 0;

    }

//调用窗口初始化函数和其它一些类的初始化函数
bool SystemClass::Initialize()
    { 
…
   // 初始化图形对象
    result = m_Graphics->Initialize(screenWidth, screenHeight, m_hwnd);
    if(!result)
        {
        return false;
        }
    // 创建计时器对象.
    m_Timer = new TimerClass;
    if(!m_Timer)
        {
        return false;
        }

    // 初始化计时器对象
    result = m_Timer->Initialize();
    if(!result)
        {
        MessageBox(m_hwnd, L"Could not initialize the Timer object.", L"Error", MB_OK);
        return false;
        }

    return true;
    }

bool SystemClass::Frame()
    {
…

    m_Timer->Frame();

根据时间来设定摄像机旋转的角度,基本上能保证旋转不会因为fps不同而不同

    //动画,旋转摄像机
    m_Graphics->m_Camera->roll(m_Timer->GetTime()/1000);

    // 执行帧渲染函数.
    result = m_Graphics->Frame();
    if(!result)
        {
        return false;
        }
    return true;
    }

程序执行后,将会发现一个旋转的颜色立方体,你也可以用Q,W,E,A,S,D,Z,X,C控制摄像机,改变观察方向。

程序的截图和上篇教程中的图是一样的。

完整的代码请参考:

工程文件myTutorialD3D11_8

代码下载:

http://files.cnblogs.com/mikewolf2002/myTutorialD3D11.zip

Directx11教程(9) 增加一个TimerClass类的更多相关文章

  1. Directx11教程(11) 增加一个debug宏

    原文:Directx11教程(11) 增加一个debug宏       现在我们在common.h中增加一个debug的宏,在每个d3d11函数后调用,如果d3d函数出错,它能够给出程序中错误的代码行 ...

  2. Directx11教程(56) 建立一个skydome

    原文:Directx11教程(56) 建立一个skydome       本章建立一个skydome(天空穹),主要学习如何使用cube mapping.      cube map就是把六张纹理当作 ...

  3. Directx11教程(5) 画一个简单的三角形(1)

    原文:Directx11教程(5) 画一个简单的三角形(1)       在本篇教程中,我们将通过D3D11画一个简单的三角形.在D3D11中,GPU的渲染主要通过shader来操作(当然还有一些操作 ...

  4. Directx11教程(10) 画一个简易坐标轴

    原文:Directx11教程(10) 画一个简易坐标轴       本篇教程中,我们将在三维场景中,画一个简易的坐标轴,分别用红.绿.蓝三种颜色表示x,y,z轴的正向坐标轴. 为此,我们要先建立一个A ...

  5. Directx11教程(7) 画一个颜色立方体

    原文:Directx11教程(7) 画一个颜色立方体       前面教程我们通过D3D11画了一个三角形,本章我们将画一个颜色立方体,它的立体感更强.主要的变动是ModelClass类,在Model ...

  6. Directx11教程(6) 画一个简单的三角形(2)

    原文:Directx11教程(6) 画一个简单的三角形(2)      在上篇教程中,我们实现了在D3D11中画一个简单的三角形,但是,当我们改变窗口大小时候,三角形形状却随着窗口高宽比例改变而改变, ...

  7. Directx11教程(19) 画一个简单的地形

    原文:Directx11教程(19) 画一个简单的地形       通常我们在xz平面定义一个二维的网格,然后y的值根据一定的函数计算得到,比如正弦.余弦函数的组合等等,可以得到一个看似不错的地形或者 ...

  8. Directx11教程(4) 一个最基本D3D应用程序(2)

    原文:Directx11教程(4) 一个最基本D3D应用程序(2) 接着上篇教程的代码,本篇加入基本的D3D代码,实现一个完整的D3D11程序框架. 我们增加一个新类D3DClass, 用来处理3D渲 ...

  9. Directx11教程(8) 一个新的camera类

    原文:Directx11教程(8) 一个新的camera类      本章我们将替换掉CameraClass类,实现一个稍微靠谱点的摄像机类.并通过Q,W,E,A,S,D,Z,X,C等按键实现摄像机的 ...

随机推荐

  1. ES5-ES8 数组拥有的方法

    1.判断是否是数组 Array.isArray( arg ) 有兼容性 2.toString 数组转字符串 arr.toString(); 3.join 数组每一项间的拼接 arr.join(); S ...

  2. mysql大数据表优化

    1.应尽量避免在 where 子句中使用!=或<>操作符,否则将引擎放弃使用索引而进行全表扫描. 2.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉 ...

  3. Hibernate-概述-搭建-测试-配置详解

    一 hibernate概述 1.1 框架是什么 1.框架是用来提高开发效率的 2.封装了好了一些功能.我们需要使用这些功能时,调用即可.不需要再手动实现. 3.所以框架可以理解成是一个半成品的项目.只 ...

  4. oracle数据导入/导出(2)

    Oracle数据导入导出imp/exp 功能:Oracle数据导入导出imp/exp就相当与oracle数据还原与备份. 大多情况都可以用Oracle数据导入导出完成数据的备份和还原(不会造成数据的丢 ...

  5. Jquery点击加载更多

    一.点击加载更多有点像分页获取数据类似,下面是本人写的一个简单的小例子 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitiona ...

  6. Leetcode228. Summary Ranges汇总区间

    给定一个无重复元素的有序整数数组,返回数组区间范围的汇总. 示例 1: 输入: [0,1,2,4,5,7] 输出: ["0->2","4->5",& ...

  7. Leetcode563.Binary Tree Tilt二叉树的坡度

    给定一个二叉树,计算整个树的坡度. 一个树的节点的坡度定义即为,该节点左子树的结点之和和右子树结点之和的差的绝对值.空结点的的坡度是0. 整个树的坡度就是其所有节点的坡度之和. 示例: 输入: 1 / ...

  8. 一句话介绍python线程、进程和协程

    一.进程: Python的os模块封装了常见的系统调用,其中就包括fork.而fork是linux常用的产生子进程的方法,简言之是一个调用,两个返回. 在python中,以下的两个模块用于进程的使用. ...

  9. 20190725-Silly

    $ \mathsf{You\ think\ about\ what\ you\ want\ because\ you're\ just\ alive}$ ——C418-Alive 我不能yuanlia ...

  10. mysql 查询条件不区分大小写问题

    转自 http://blog.csdn.net/qishuo_java/article/details/40118937 转自 https://www.cnblogs.com/wuyun-blog/p ...