1. 程式人生 > >Directx11教程(9) 增加一個TimerClass類

Directx11教程(9) 增加一個TimerClass類

art ren bool hive 獲取 Once 動畫 size 多少

原文: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類