CameraClass.h
1 //============================================================================= 2 // Name: CameraClass.h 3 // Des: 一个封装了实现虚拟摄像机的类的头文件 4 //============================================================================= 5 #pragma once 6 #include <d3d9.h> 7 #include <d3dx9.h> 8 9 class CameraClass 10 { 11 private: 12 //成员变量的申明 13 D3DXVECTOR3 m_vRightVector;// 右分量向量 14 D3DXVECTOR3 m_vUpVector; // 上分量向量 15 D3DXVECTOR3 m_vLookVector; // 观察方向向量 16 D3DXVECTOR3 m_vCameraPosition;// 摄像机位置的向量 17 D3DXVECTOR3 m_vTargetPosition; //目标观察位置的向量 18 D3DXMATRIX m_matView; // 取景变换矩阵 19 D3DXMATRIX m_matProj; // 投影变换矩阵 20 LPDIRECT3DDEVICE9 m_pd3dDevice; //Direct3D设备对象 21 public: 22 //一个计算取景变换的函数 23 VOID CalculateViewMatrix(D3DXMATRIX *pMatrix); //计算取景变换矩阵 24 //三个Get系列函数 25 VOID GetProjMatrix(D3DXMATRIX *pMatrix) { *pMatrix = m_matProj; } //返回当前投影矩阵 26 VOID GetCameraPosition(D3DXVECTOR3 *pVector) { *pVector = m_vCameraPosition; } //返回当前摄像机位置矩阵 27 VOID GetLookVector(D3DXVECTOR3 *pVector) { *pVector = m_vLookVector; } //返回当前的观察矩阵 28 29 //四个Set系列函数,注意他们都参数都有默认值NULL的,调用时不写参数也可以 30 VOID SetTargetPosition(D3DXVECTOR3 *pLookat = NULL); //设置摄像机的目标观察位置向量 31 VOID SetCameraPosition(D3DXVECTOR3 *pVector = NULL); //设置摄像机所在的位置向量 32 VOID SetViewMatrix(D3DXMATRIX *pMatrix = NULL); //设置取景变换矩阵 33 VOID SetProjMatrix(D3DXMATRIX *pMatrix = NULL); //设置投影变换矩阵 34 35 36 37 public: 38 // 沿各分量平移的三个函数 39 VOID MoveAlongRightVec(FLOAT fUnits); // 沿right向量移动 40 VOID MoveAlongUpVec(FLOAT fUnits); // 沿up向量移动 41 VOID MoveAlongLookVec(FLOAT fUnits); // 沿look向量移动 42 43 // 绕各分量旋转的三个函数 44 VOID RotationRightVec(FLOAT fAngle); // 绕right向量选择 45 VOID RotationUpVec(FLOAT fAngle); // 绕up向量旋转 46 VOID RotationLookVec(FLOAT fAngle); // 绕look向量旋转 47 public: 48 CameraClass(IDirect3DDevice9 *pd3dDevice); 49 virtual ~CameraClass(void); 50 };
CameraClass.cpp
1 //============================================================================= 2 // Name: CameraClass.cpp 3 // Des: 一个封装了实现虚拟摄像机的类的源文件 4 //============================================================================= 5 #include "CameraClass.h" 6 7 #ifndef WINDOW_WIDTH 8 #define WINDOW_WIDTH 800 //为窗口宽度定义的宏,以方便在此处修改窗口宽度 9 #define WINDOW_HEIGHT 600 //为窗口高度定义的宏,以方便在此处修改窗口高度 10 #endif 11 12 //----------------------------------------------------------------------------- 13 // Desc: 构造函数 14 //----------------------------------------------------------------------------- 15 CameraClass::CameraClass(IDirect3DDevice9 *pd3dDevice) 16 { 17 m_pd3dDevice = pd3dDevice; 18 m_vRightVector = D3DXVECTOR3(1.0f, 0.0f, 0.0f); // 默认右向量与X正半轴重合 19 m_vUpVector = D3DXVECTOR3(0.0f, 1.0f, 0.0f); // 默认上向量与Y正半轴重合 20 m_vLookVector = D3DXVECTOR3(0.0f, 0.0f, 1.0f); // 默认观察向量与Z正半轴重合 21 m_vCameraPosition = D3DXVECTOR3(0.0f, 0.0f, -250.0f); // 默认摄像机坐标为(0.0f, 0.0f, -250.0f) 22 m_vTargetPosition = D3DXVECTOR3(0.0f, 0.0f, 0.0f);//默认观察目标位置为(0.0f, 0.0f, 0.0f); 23 24 } 25 26 27 //----------------------------------------------------------------------------- 28 // Name:CameraClass::CalculateViewMatrix( ) 29 // Desc: 根据给定的矩阵计算出取景变换矩阵 30 //----------------------------------------------------------------------------- 31 VOID CameraClass::CalculateViewMatrix(D3DXMATRIX *pMatrix) 32 { 33 //1.先把3个向量都规范化并使其相互垂直,成为一组正交矩阵 34 D3DXVec3Normalize(&m_vLookVector, &m_vLookVector); //规范化观察分量 35 D3DXVec3Cross(&m_vUpVector, &m_vLookVector, &m_vRightVector); // 上向量与观察向量垂直 36 D3DXVec3Normalize(&m_vUpVector, &m_vUpVector); // 规范化上向量 37 D3DXVec3Cross(&m_vRightVector, &m_vUpVector, &m_vLookVector); // 右向量与上向量垂直 38 D3DXVec3Normalize(&m_vRightVector, &m_vRightVector); // 规范化右向量 39 40 41 // 2.创建出取景变换矩阵 42 //依次写出取景变换矩阵的第一行 43 pMatrix->_11 = m_vRightVector.x; // Rx 44 pMatrix->_12 = m_vUpVector.x; // Ux 45 pMatrix->_13 = m_vLookVector.x; // Lx 46 pMatrix->_14 = 0.0f; 47 //依次写出取景变换矩阵的第二行 48 pMatrix->_21 = m_vRightVector.y; // Ry 49 pMatrix->_22 = m_vUpVector.y; // Uy 50 pMatrix->_23 = m_vLookVector.y; // Ly 51 pMatrix->_24 = 0.0f; 52 //依次写出取景变换矩阵的第三行 53 pMatrix->_31 = m_vRightVector.z; // Rz 54 pMatrix->_32 = m_vUpVector.z; // Uz 55 pMatrix->_33 = m_vLookVector.z; // Lz 56 pMatrix->_34 = 0.0f; 57 //依次写出取景变换矩阵的第四行 58 pMatrix->_41 = -D3DXVec3Dot(&m_vRightVector, &m_vCameraPosition); // -P*R 59 pMatrix->_42 = -D3DXVec3Dot(&m_vUpVector, &m_vCameraPosition); // -P*U 60 pMatrix->_43 = -D3DXVec3Dot(&m_vLookVector, &m_vCameraPosition); // -P*L 61 pMatrix->_44 = 1.0f; 62 } 63 64 65 //----------------------------------------------------------------------------- 66 // Name:CameraClass::SetTargetPosition( ) 67 // Desc: 设置摄像机的观察位置 68 //----------------------------------------------------------------------------- 69 VOID CameraClass::SetTargetPosition(D3DXVECTOR3 *pLookat) 70 { 71 //先看看pLookat是否为默认值NULL 72 if (pLookat != NULL) m_vTargetPosition = (*pLookat); 73 else m_vTargetPosition = D3DXVECTOR3(0.0f, 0.0f, 1.0f); 74 75 m_vLookVector = m_vTargetPosition - m_vCameraPosition;//观察点位置减摄像机位置,得到观察方向向量 76 D3DXVec3Normalize(&m_vLookVector, &m_vLookVector);//规范化m_vLookVector向量 77 78 //正交并规范化m_vUpVector和m_vRightVector 79 D3DXVec3Cross(&m_vUpVector, &m_vLookVector, &m_vRightVector); 80 D3DXVec3Normalize(&m_vUpVector, &m_vUpVector); 81 D3DXVec3Cross(&m_vRightVector, &m_vUpVector, &m_vLookVector); 82 D3DXVec3Normalize(&m_vRightVector, &m_vRightVector); 83 } 84 85 //----------------------------------------------------------------------------- 86 // Name:CameraClass::SetCameraPosition( ) 87 // Desc: 设置摄像机所在的位置 88 //----------------------------------------------------------------------------- 89 VOID CameraClass::SetCameraPosition(D3DXVECTOR3 *pVector) 90 { 91 D3DXVECTOR3 V = D3DXVECTOR3(0.0f, 0.0f, -250.0f); 92 m_vCameraPosition = pVector ? (*pVector) : V;//三目运算符,如果pVector为真的话, 93 //返回*pVector的值(即m_vCameraPosition=*pVector), 94 //否则返回V的值(即m_vCameraPosition=V) 95 } 96 97 //----------------------------------------------------------------------------- 98 // Name:CameraClass::SetViewMatrix( ) 99 // Desc: 设置取景变换矩阵 100 //----------------------------------------------------------------------------- 101 VOID CameraClass::SetViewMatrix(D3DXMATRIX *pMatrix) 102 { 103 //根据pMatrix的值先做一下判断 104 if (pMatrix) m_matView = *pMatrix; 105 else CalculateViewMatrix(&m_matView); 106 m_pd3dDevice->SetTransform(D3DTS_VIEW, &m_matView); 107 //把取景变换矩阵的值分下来分别给右分量,上分量,和观察分量 108 m_vRightVector = D3DXVECTOR3(m_matView._11, m_matView._12, m_matView._13); 109 m_vUpVector = D3DXVECTOR3(m_matView._21, m_matView._22, m_matView._23); 110 m_vLookVector = D3DXVECTOR3(m_matView._31, m_matView._32, m_matView._33); 111 } 112 113 //----------------------------------------------------------------------------- 114 // Name:CameraClass::SetProjMatrix( ) 115 // Desc: 设置投影变换矩阵 116 //----------------------------------------------------------------------------- 117 VOID CameraClass::SetProjMatrix(D3DXMATRIX *pMatrix) 118 { 119 //判断值有没有,没有的话就计算一下 120 if (pMatrix != NULL) m_matProj = *pMatrix; 121 else D3DXMatrixPerspectiveFovLH(&m_matProj, D3DX_PI / 4.0f, (float)((double)WINDOW_WIDTH/WINDOW_HEIGHT), 1.0f, 30000.0f);//视截体远景设为30000.0f,这样就不怕看不到远处的物体了 122 m_pd3dDevice->SetTransform(D3DTS_PROJECTION, &m_matProj);//设置投影变换矩阵 123 } 124 125 //----------------------------------------------------------------------------- 126 // Name:CameraClass::MoveAlongRightVec( ) 127 // Desc: 沿右向量平移fUnits个单位 128 //----------------------------------------------------------------------------- 129 VOID CameraClass::MoveAlongRightVec(FLOAT fUnits) 130 { 131 //直接乘以fUnits的量来累加就行了 132 m_vCameraPosition += m_vRightVector * fUnits; 133 m_vTargetPosition += m_vRightVector * fUnits; 134 } 135 136 //----------------------------------------------------------------------------- 137 // Name:CameraClass::MoveAlongUpVec( ) 138 // Desc: 沿上向量平移fUnits个单位 139 //----------------------------------------------------------------------------- 140 VOID CameraClass::MoveAlongUpVec(FLOAT fUnits) 141 { 142 //直接乘以fUnits的量来累加就行了 143 m_vCameraPosition += m_vUpVector * fUnits; 144 m_vTargetPosition += m_vUpVector * fUnits; 145 } 146 147 //----------------------------------------------------------------------------- 148 // Name:CameraClass::MoveAlongLookVec( ) 149 // Desc: 沿观察向量平移fUnits个单位 150 //----------------------------------------------------------------------------- 151 VOID CameraClass::MoveAlongLookVec(FLOAT fUnits) 152 { 153 //直接乘以fUnits的量来累加就行了 154 m_vCameraPosition += m_vLookVector * fUnits; 155 m_vTargetPosition += m_vLookVector * fUnits; 156 } 157 158 //----------------------------------------------------------------------------- 159 // Name:CameraClass::RotationRightVec( ) 160 // Desc: 沿右向量旋转fAngle个弧度单位的角度 161 //----------------------------------------------------------------------------- 162 VOID CameraClass::RotationRightVec(FLOAT fAngle) 163 { 164 D3DXMATRIX R; 165 D3DXMatrixRotationAxis(&R, &m_vRightVector, fAngle);//创建出绕m_vRightVector旋转fAngle个角度的R矩阵 166 D3DXVec3TransformCoord(&m_vUpVector, &m_vUpVector, &R);//让m_vUpVector向量绕m_vRightVector旋转fAngle个角度 167 D3DXVec3TransformCoord(&m_vLookVector, &m_vLookVector, &R);//让m_vLookVector向量绕m_vRightVector旋转fAngle个角度 168 169 m_vTargetPosition = m_vLookVector * D3DXVec3Length(&m_vCameraPosition);//更新一下观察点的新位置(方向乘以模=向量) 170 } 171 172 //----------------------------------------------------------------------------- 173 // Name:CameraClass::RotationUpVec( ) 174 // Desc: 沿上向量旋转fAngle个弧度单位的角度 175 //----------------------------------------------------------------------------- 176 VOID CameraClass::RotationUpVec(FLOAT fAngle) 177 { 178 D3DXMATRIX R; 179 D3DXMatrixRotationAxis(&R, &m_vUpVector, fAngle);//创建出绕m_vUpVector旋转fAngle个角度的R矩阵 180 D3DXVec3TransformCoord(&m_vRightVector, &m_vRightVector, &R);//让m_vRightVector向量绕m_vUpVector旋转fAngle个角度 181 D3DXVec3TransformCoord(&m_vLookVector, &m_vLookVector, &R);//让m_vLookVector向量绕m_vUpVector旋转fAngle个角度 182 183 m_vTargetPosition = m_vLookVector * D3DXVec3Length(&m_vCameraPosition);//更新一下观察点的新位置(方向乘以模=向量) 184 } 185 186 //----------------------------------------------------------------------------- 187 // Name:CameraClass::RotationLookVec( ) 188 // Desc: 沿观察向量旋转fAngle个弧度单位的角度 189 //----------------------------------------------------------------------------- 190 VOID CameraClass::RotationLookVec(FLOAT fAngle) 191 { 192 D3DXMATRIX R; 193 D3DXMatrixRotationAxis(&R, &m_vLookVector, fAngle);//创建出绕m_vLookVector旋转fAngle个角度的R矩阵 194 D3DXVec3TransformCoord(&m_vRightVector, &m_vRightVector, &R);//让m_vRightVector向量绕m_vLookVector旋转fAngle个角度 195 D3DXVec3TransformCoord(&m_vUpVector, &m_vUpVector, &R);//让m_vUpVector向量绕m_vLookVector旋转fAngle个角度 196 197 m_vTargetPosition = m_vLookVector * D3DXVec3Length(&m_vCameraPosition);//更新一下观察点的新位置(方向乘以模=向量) 198 } 199 200 201 //----------------------------------------------------------------------------- 202 // Desc: 析构函数 203 //----------------------------------------------------------------------------- 204 CameraClass::~CameraClass(void) 205 { 206 }