• 热门专题

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

作者:迈克老狼2012  发布日期:2012-03-21 20:57:36
Tag标签:Directx11  TimerClass类  
  • 在上篇文章代码的基础上,我们增加一个TimerClass类,这个类的功能很简单,就是可以计算相邻2帧的时间差。利用这个时间差值,可以实现平滑的动画,使得动画不会因为不同机器fps不同,从而动画效果变快或者变慢。

    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

     

    //定义该宏能够减少windows头文件的大小,使编译器不编译一些不必要的文件,加快编译时间 
    #define WIN32_LEAN_AND_MEAN
    
    #include <windows.h>
    
    #include "InputClass.h" 
    #include "GraphicsClass.h" 
    #include "TimerClass.h"
    
    const float PI     = 3.14159265358979323f;
    
    class SystemClass 
        { 
        public: 
            SystemClass(void); 
            SystemClass(const SystemClass &); 
            ~SystemClass(void);
    
            bool Initialize(); 
            void Shutdown(); 
            void Run();
    
            LRESULT CALLBACK MessageHandler(HWND, UINT, WPARAM, LPARAM); 
        private: 
            bool Frame(); 
            void InitializeWindows(int&, int&); 
            void ShutdownWindows();
    
            LPCWSTR m_applicationName; 
            HINSTANCE m_hinstance; 
            HWND m_hwnd;
    
           //InputClass和GraphicsClass是SystemClass的两个成员变量 
            InputClass* m_Input; 
            GraphicsClass* m_Graphics;
    
            //计时器类 
            TimerClass* m_Timer; 
        };
    
    //定义静态的回调函数以及应用程序句柄 
    //因为定义窗口类时候,必须指定窗口回调函数,所以我们用静态的回调函数WndProc 
    static LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
    
    static SystemClass* ApplicationHandle = 0;
    
    

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

     

    #include "SystemClass.h"
    
    
    SystemClass::SystemClass(void) 
        { 
        m_Input = 0; 
        m_Graphics = 0;
    
        m_Timer = 0;
    
        }
    
    SystemClass::SystemClass(const SystemClass &) 
        {
    
        }
    
    SystemClass::~SystemClass(void) 
        { 
        }
    
    //调用窗口初始化函数和其它一些类的初始化函数 
    bool SystemClass::Initialize() 
        { 
        bool result; 
        int screenWidth = 0, screenHeight = 0;
    
        // 初始化窗口 
        InitializeWindows(screenWidth, screenHeight);
    
       //创建input对象处理键盘输入 
        m_Input = new InputClass; 
        if(!m_Input) 
            { 
            return false; 
            }
    
        // 初始化输入对象. 
        m_Input->Initialize();
    
        // 创建图形对象,这个对象将渲染应用程序中的所有物体 
        m_Graphics = new GraphicsClass; 
        if(!m_Graphics) 
            { 
            return false; 
            } 
       // 初始化图形对象 
        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; 
        }
    
    void SystemClass::Shutdown() 
        { 
        //其它类的一些销毁工作 
        // 释放计时器对象. 
        if(m_Timer) 
            { 
            delete m_Timer; 
            m_Timer = 0; 
            }
    
    
        if(m_Graphics) 
            { 
            m_Graphics->Shutdown(); 
            delete m_Graphics; 
            m_Graphics = 0; 
            }
    
        if(m_Input) 
            { 
            delete m_Input; 
            m_Input = 0; 
            } 
        // 执行一些销毁工作. 
        ShutdownWindows();
    
        }
    
    bool SystemClass::Frame() 
        { 
        bool result;
    
        //检测用户是否按下ESC键,如果按下,退出程序. 
        if(m_Input->IsKeyDown(VK_ESCAPE)) 
            { 
            return false; 
            }
    
        //如果A,S,D,W,Q,E,Z,X,C键按下,移动摄像机 
        if(GetAsyncKeyState('W') & 0x8000)   //前后 
            m_Graphics->m_Camera->walk(-0.1); 
        if(GetAsyncKeyState('S') & 0x8000)    
            m_Graphics->m_Camera->walk(0.1); 
        if(GetAsyncKeyState('A') & 0x8000)   //左右 
            m_Graphics->m_Camera->strafe(-0.1); 
        if(GetAsyncKeyState('D') & 0x8000)    
            m_Graphics->m_Camera->strafe(0.1); 
        if(GetAsyncKeyState('Q') & 0x8000)    //上下 
            m_Graphics->m_Camera->fly(-0.1); 
        if(GetAsyncKeyState('E') & 0x8000)    
            m_Graphics->m_Camera->fly(0.1); 
        if(GetAsyncKeyState('Z') & 0x8000)    
            m_Graphics->m_Camera->pitch(PI/180); 
        if(GetAsyncKeyState('X') & 0x8000)    
            m_Graphics->m_Camera->yaw(PI/180); 
        if(GetAsyncKeyState('C') & 0x8000)    
            m_Graphics->m_Camera->roll(PI/180); 
        if(GetAsyncKeyState('R') & 0x8000) //摄像机复位    
            { 
            // 设置摄像机位置. 
            m_Graphics->m_Camera->Reset(); 
            D3DXVECTOR3 campos = D3DXVECTOR3(0.0f, 0.0f, -10.0f); 
            m_Graphics->m_Camera->setPosition(&campos); 
            }
    
    
        m_Timer->Frame();
    
        //动画,旋转摄像机 
        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控制摄像机,改变观察方向。

About IT165 - 广告服务 - 隐私声明 - 版权申明 - 免责条款 - 网站地图 - 网友投稿 - 联系方式
本站内容来自于互联网,仅供用于网络技术学习,学习中请遵循相关法律法规