赞
踩
//----------------------------------------------------------------------------- // 文件: D3DCamera.h // // 描述: D3DCamera类的头文件,定义变量,函数。 // // 更新: 2009-03-19 by Ninsun //----------------------------------------------------------------------------- #pragma once #include <d3dx9.h> #pragma comment (lib, "d3d9.lib") #pragma comment (lib, "d3dx9.lib") #include "D3DWindow.h" class D3DCamera { public: D3DCamera(LPDIRECT3DDEVICE9 _pd3dDevice); public: ~D3DCamera(void); public: VOID resetCamera(); VOID applyCamera(); LRESULT mouseProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam ); VOID keyProc(); private: VOID setCamera(); public: private: LPDIRECT3DDEVICE9 m_pd3dDevice; // D3D设备 BOOL m_bIsRotaion; // 是否旋转 D3DXVECTOR3 m_vPos; // 摄像机位置 D3DXVECTOR3 m_vLookAt; // 摄像机视点 D3DXVECTOR3 m_vUp; // 摄像机顶方向 D3DXVECTOR3 m_vRight; // 摄像机右方向 D3DXVECTOR3 m_vDirection; // 摄像机面向方向 FLOAT m_fNear; // 视角最近距离 FLOAT m_fFar; // 视角最远距离 FLOAT m_fFOV; // 视角可视角度 FLOAT m_fAspect; // 视角宽高比 FLOAT m_fMaxPitch; // 视角仰视最大值 FLOAT m_fMinPitch; // 视角俯视最大值 FLOAT m_fCameraYawAngle; // 摄像机Y轴旋转角度 FLOAT m_fCameraPitchAngle; // 摄像机X轴旋转角度 D3DXVECTOR3 m_vDelta; // 摄像机移动向量 FLOAT m_fSpeed; // 摄像机移动速度 POINT m_LastPoint; // 上一个鼠标位置 }; //----------------------------------------------------------------------------- // 文件: D3DCamera.cpp // // 描述: D3DCamera类,用于架设一个可以操纵的摄像机 // // 更新: 2009-03-19 by Ninsun //----------------------------------------------------------------------------- #include "D3DCamera.h" #include "D3DImage.h" //----------------------------------------------------------------------------- // 名称: D3DCamera() // 描述: 自定义构造函数 //----------------------------------------------------------------------------- D3DCamera::D3DCamera(LPDIRECT3DDEVICE9 _pd3dDevice) { m_pd3dDevice = _pd3dDevice; // 设置摄像机位置,视点,顶方向 D3DXMATRIXA16 matView; m_vPos = D3DXVECTOR3(0.0f, 0.0f, -WND_HEIGHT/2*ZOOM); // 摄像机位置 m_vLookAt = D3DXVECTOR3(0.0f, 0.0f, 0.0f); // 摄像机视点 m_vUp = D3DXVECTOR3(0.0f, 1.0f, 0.0f); // 摄像机顶方向 D3DXMatrixLookAtLH( &matView, &m_vPos, &m_vLookAt, &m_vUp ); m_pd3dDevice->SetTransform( D3DTS_VIEW, &matView ); // 使用透视投影矩阵,设置摄像机视角, D3DXMATRIXA16 matProj; D3DXMatrixPerspectiveFovLH( &matProj, D3DX_PI / 4, 4.0f/3.0f, 0.0001f, 2000.0f ); m_pd3dDevice->SetTransform( D3DTS_PROJECTION, &matProj ); // 设置其他变量 m_vDirection = m_vLookAt - m_vPos; D3DXVec3Cross( &m_vRight, &m_vUp, &m_vDirection ); m_fCameraYawAngle = D3DX_PI; m_fCameraPitchAngle = 0; m_fSpeed = ZOOM*0.5; m_bIsRotaion = FALSE; } D3DCamera::~D3DCamera(void) { } //----------------------------------------------------------------------------- // 名称: setCamera() // 描述: 设置摄像机位置,看点 //----------------------------------------------------------------------------- VOID D3DCamera::setCamera() { D3DXMATRIXA16 matView; D3DXMatrixLookAtLH( &matView, &m_vPos, &m_vLookAt, &m_vUp ); m_pd3dDevice->SetTransform( D3DTS_VIEW, &matView ); } //----------------------------------------------------------------------------- // 名称: resetCamera() // 描述: 设置摄像机位置,看点 //----------------------------------------------------------------------------- VOID D3DCamera::resetCamera() { m_vPos = D3DXVECTOR3(0.0f, 0.0f, -WND_HEIGHT/2*ZOOM); // 摄像机位置 m_vLookAt = D3DXVECTOR3(0.0f, 0.0f, 0.0f); // 摄像机视点 m_vUp = D3DXVECTOR3(0.0f, 1.0f, 0.0f); // 摄像机顶方向 m_vDirection = m_vLookAt - m_vPos; D3DXVec3Cross( &m_vRight, &m_vUp, &m_vDirection ); m_fCameraYawAngle = D3DX_PI; m_fCameraPitchAngle = 0; setCamera(); } //----------------------------------------------------------------------------- // 名称: applyCamera() // 描述: 应用摄像机变换 //----------------------------------------------------------------------------- VOID D3DCamera::applyCamera() { POINT ptCurrentPos; POINT ptDeltaPos; if(m_bIsRotaion) { // 计算鼠标偏移 GetCursorPos(&ptCurrentPos); ptDeltaPos.x = ptCurrentPos.x - m_LastPoint.x; ptDeltaPos.y = ptCurrentPos.y - m_LastPoint.y; SetCursorPos(m_LastPoint.x,m_LastPoint.y); //m_LastPoint = ptCurrentPos; float fYaw = ptDeltaPos.x*0.0025f; float fPitch = ptDeltaPos.y*0.0025f; // 根据鼠标偏移计算欧拉角 m_fCameraYawAngle += fYaw; m_fCameraPitchAngle -= fPitch; // 限定俯仰角大小 if(m_fCameraPitchAngle > D3DX_PI*0.49f) m_fCameraPitchAngle = D3DX_PI*0.49f; else if(m_fCameraPitchAngle < -D3DX_PI*0.49f) m_fCameraPitchAngle = -D3DX_PI*0.49f; } // 根据欧拉角Yaw,Pitch计算摄像机的旋转矩阵 D3DXMATRIX matCameraRotation; ZeroMemory(&matCameraRotation, sizeof(D3DXMATRIX)); D3DXMatrixRotationYawPitchRoll(&matCameraRotation, m_fCameraYawAngle, m_fCameraPitchAngle,0.0f); // 根据旋转矩阵将摄像机的朝向和顶方向变换 D3DXVECTOR3 vWorldUp, vWorldAhead; D3DXVECTOR3 vLocalUp = D3DXVECTOR3(0,1,0); D3DXVECTOR3 vLocalAhead = D3DXVECTOR3(0,0,-WND_HEIGHT/2*ZOOM); D3DXVec3TransformCoord( &vWorldUp, &vLocalUp, &matCameraRotation ); D3DXVec3TransformCoord( &vWorldAhead, &vLocalAhead, &matCameraRotation ); // 将局部偏移量转到全局坐标 D3DXVECTOR3 vWorldDelta; D3DXVec3TransformCoord( &vWorldDelta, &m_vDelta, &matCameraRotation ); // 根据偏移量计算视点位置 m_vPos += vWorldDelta; if(m_vPos.y < 0) m_vPos.y = 0; if(m_vPos.y > ZOOM*200) m_vPos.y = ZOOM*200; m_vLookAt = m_vPos + vWorldAhead; // 设置摄像机 setCamera(); // 更新变量 m_vDirection = m_vLookAt - m_vPos; m_vUp = vWorldUp; D3DXVec3Cross( &m_vRight, &m_vUp, &m_vDirection ); } //----------------------------------------------------------------------------- // 名称: mouseProc() // 描述: 鼠标消息处理 //----------------------------------------------------------------------------- LRESULT D3DCamera::mouseProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam ) { switch( msg ) { case WM_RBUTTONDOWN: { m_bIsRotaion = true; SetCapture(hWnd); GetCursorPos(&m_LastPoint); } break; case WM_RBUTTONUP: { m_bIsRotaion = false; ReleaseCapture(); } break; } return 0; } //----------------------------------------------------------------------------- // 名称: keyProc() // 描述: 键盘消息处理 //----------------------------------------------------------------------------- VOID D3DCamera::keyProc() { static char _up = VK_SPACE; static char _down = 'X'; static char _left = 'A'; static char _right = 'D'; static char _head = 'W'; static char _back = 'S'; static char _reset = 'R'; m_vDelta = D3DXVECTOR3(0, 0, 0); if( GetKeyState(_head) & 0x80 ) { m_vDelta.z -= m_fSpeed; } if( GetKeyState(_back) & 0x80 ) { m_vDelta.z += m_fSpeed; } if( GetKeyState(_left) & 0x80 ) { m_vDelta.x += m_fSpeed; } if( GetKeyState(_right) & 0x80 ) { m_vDelta.x -= m_fSpeed; } if( GetKeyState(_up) & 0x80 ) { m_vPos.y += m_fSpeed; } if( GetKeyState(_down) & 0x80 ) { m_vPos.y -= m_fSpeed; } if( GetKeyState(_reset) & 0x80 ) { resetCamera(); } }