• 热门专题

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

作者:迈克老狼2012  发布日期:2012-03-21 20:55:19
Tag标签:Directx11  camera类  
  • 本章我们将替换掉CameraClass类,实现一个强大的摄像机类。

    并通过Q,W,E,A,S,D,Z,X,C实现摄像机的控制。

    CameraClass.h的代码如下:

     

    #pragma once
    
    #include <d3dx10math.h>
    
    class CameraClass 
        { 
        //支持两种摄像机模型 AIRCRAFT 允许在空间自由运动,具有6个自由度 
        // LANDOBJECT 沿某些特定轴进行移动 
        public: 
            enum CameraType { LANDOBJECT, AIRCRAFT };
    
        public: 
            CameraClass(void); 
            CameraClass(const CameraClass&); 
            ~CameraClass(void);
    
            void strafe(float units); // 左右 
            void fly(float units);   // 上下 
            void walk(float units);   // 前后
    
            void pitch(float angle); // 旋转view坐标系right向量 
            void yaw(float angle);  // 旋转up向量 
            void roll(float angle); // 旋转look向量
    
            void getViewMatrix(D3DXMATRIX* V); 
            void setCameraType(CameraType cameraType); 
            void getPosition(D3DXVECTOR3* pos); 
            void setPosition(D3DXVECTOR3* pos); 
    
            void getRight(D3DXVECTOR3* right); 
            void getUp(D3DXVECTOR3* up); 
            void getLook(D3DXVECTOR3* look); 
        private: 
            CameraType  _cameraType; 
            D3DXVECTOR3 _right; 
            D3DXVECTOR3 _up; 
            D3DXVECTOR3 _look; 
            D3DXVECTOR3 _pos;
    
        };
    
    

    CameraClass.cpp代码如下:

     

    #include "CameraClass.h"
    
    
    CameraClass::CameraClass(void) 
        { 
        _cameraType = AIRCRAFT;
    
        _pos   = D3DXVECTOR3(0.0f, 0.0f, 0.0f); 
        _right = D3DXVECTOR3(1.0f, 0.0f, 0.0f); 
        _up    = D3DXVECTOR3(0.0f, 1.0f, 0.0f); 
        _look  = D3DXVECTOR3(0.0f, 0.0f, 1.0f);
    
        }
    
    CameraClass::CameraClass(const CameraClass& other) 
        { 
        }
    
    CameraClass::~CameraClass(void) 
        { 
        }
    
    void CameraClass::getPosition(D3DXVECTOR3* pos) 
        { 
        *pos = _pos; 
        }
    
    void CameraClass::setPosition(D3DXVECTOR3* pos) 
        { 
        _pos = *pos; 
        }
    
    void CameraClass::getRight(D3DXVECTOR3* right) 
        { 
        *right = _right; 
        }
    
    void CameraClass::getUp(D3DXVECTOR3* up) 
        { 
        *up = _up; 
        }
    
    void CameraClass::getLook(D3DXVECTOR3* look) 
        { 
        *look = _look; 
        }
    
    //行走,沿着摄像机观察方向的移动 
    void CameraClass::walk(float units) 
        { 
        // 仅在x,z平面移动 
        if( _cameraType == LANDOBJECT ) 
            _pos += D3DXVECTOR3(_look.x, 0.0f, _look.z) * units;
    
        if( _cameraType == AIRCRAFT ) 
            _pos += _look * units; 
        }
    
    //扫视,是指保持观察方向不变,沿向量right方向从一边平移到另一边 
    void CameraClass::strafe(float units) 
        { 
        // 仅在x,z平面移动 
        if( _cameraType == LANDOBJECT ) 
            _pos += D3DXVECTOR3(_right.x, 0.0f, _right.z) * units;
    
        if( _cameraType == AIRCRAFT ) 
            _pos += _right * units; 
        } 
    //飞行模式,升降,指沿着向量up方向的移动 
    void CameraClass::fly(float units) 
        { 
        // 仅在y轴移动 
        if( _cameraType == LANDOBJECT ) 
            _pos.y += units;
    
        if( _cameraType == AIRCRAFT ) 
            _pos += _up * units; 
        }
    
    void CameraClass::pitch(float angle) 
        { 
        D3DXMATRIX T; 
        D3DXMatrixRotationAxis(&T, &_right, angle);
    
       // 绕着right向量,旋转up和look 
        D3DXVec3TransformCoord(&_up,&_up, &T); 
        D3DXVec3TransformCoord(&_look,&_look, &T); 
        }
    
    void CameraClass::yaw(float angle) 
        { 
        D3DXMATRIX T;
    
        //对LANDOBJECT,总是绕着(0,1,0)旋转。 
        if( _cameraType == LANDOBJECT ) 
            D3DXMatrixRotationY(&T, angle);
    
        //对于aircraft,绕着up向量旋转 
        if( _cameraType == AIRCRAFT ) 
            D3DXMatrixRotationAxis(&T, &_up, angle);
    
       // 绕着up或者y轴,旋转right和look 
        D3DXVec3TransformCoord(&_right,&_right, &T); 
        D3DXVec3TransformCoord(&_look,&_look, &T); 
        }
    
    void CameraClass::roll(float angle) 
        { 
        //只对aircraft模式才左roll旋转 
        if( _cameraType == AIRCRAFT ) 
            { 
            D3DXMATRIX T; 
            D3DXMatrixRotationAxis(&T, &_look, angle);
    
            // 绕着look向量,旋转up和right 
            D3DXVec3TransformCoord(&_right,&_right, &T); 
            D3DXVec3TransformCoord(&_up,&_up, &T); 
            } 
        }
    
    void CameraClass::getViewMatrix(D3DXMATRIX* V) 
        { 
        // 保持view局部坐标系,各轴的彼此正交 
        D3DXVec3Normalize(&_look, &_look); 
        // look X right 
        D3DXVec3Cross(&_up, &_look, &_right); 
        D3DXVec3Normalize(&_up, &_up);
    
        D3DXVec3Cross(&_right, &_up, &_look); 
        D3DXVec3Normalize(&_right, &_right);
    
       // 生成view矩阵: 
        float x = -D3DXVec3Dot(&_right, &_pos); 
        float y = -D3DXVec3Dot(&_up, &_pos); 
        float z = -D3DXVec3Dot(&_look, &_pos);
    
        (*V)(0,0) = _right.x; (*V)(0, 1) = _up.x; (*V)(0, 2) = _look.x; (*V)(0, 3) = 0.0f; 
        (*V)(1,0) = _right.y; (*V)(1, 1) = _up.y; (*V)(1, 2) = _look.y; (*V)(1, 3) = 0.0f; 
        (*V)(2,0) = _right.z; (*V)(2, 1) = _up.z; (*V)(2, 2) = _look.z; (*V)(2, 3) = 0.0f; 
        (*V)(3,0) = x;        (*V)(3, 1) = y;     (*V)(3, 2) = z;       (*V)(3, 3) = 1.0f; 
        }
    
    void CameraClass::setCameraType(CameraType cameraType) 
        { 
        _cameraType = cameraType; 
        }
    
    

    修改GraphicsClass.h, 设置成员变量m_Camera为public,以便我们在GraphicsClass类中对齐进行操作。

     

    #pragma once
    
    #include <windows.h> 
    #include "d3dclass.h" 
    #include "cameraclass.h" 
    #include "modelclass.h" 
    #include "colorshaderclass.h"
    
    ///////////// 
    // GLOBALS // 
    ///////////// 
    const bool FULL_SCREEN = false; //是否全屏 
    const bool VSYNC_ENABLED = true; //是否垂直同步 
    const float SCREEN_DEPTH = 1000.0f; //深度,远点 
    const float SCREEN_NEAR = 0.1f; //深度,近点
    
    class GraphicsClass 
        { 
        public: 
            GraphicsClass(void); 
            GraphicsClass(const GraphicsClass&); 
            ~GraphicsClass(void); 
            bool Initialize(int, int, HWND); 
            void Shutdown(); 
            bool Frame(); 
            CameraClass* m_Camera; //设为public,便于在SystemClass中控制 
        private: 
            bool Render();
    
            //定义一个D3DClass类成员变量 
            D3DClass* m_D3D; 
            
            ModelClass* m_Model; 
            ColorShaderClass* m_ColorShader;
    
        };
    
    

    SystemClass.cpp代码的Frame函数更新如下:

     

    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);
    
        
      //动画,旋转摄像机 
        m_Graphics->m_Camera->roll(PI/180);
    
        // 执行帧渲染函数. 
        result = m_Graphics->Frame(); 
        if(!result) 
            { 
            return false; 
            } 
        return true; 
        }
    
    
About IT165 - 广告服务 - 隐私声明 - 版权申明 - 免责条款 - 网站地图 - 网友投稿 - 联系方式
本站内容来自于互联网,仅供用于网络技术学习,学习中请遵循相关法律法规