开启辅助访问 切换到宽版

精易论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

用微信号发送消息登录论坛

新人指南 邀请好友注册 - 我关注人的新帖 教你赚取精币 - 每日签到


求职/招聘- 论坛接单- 开发者大厅

论坛版规 总版规 - 建议/投诉 - 应聘版主 - 精华帖总集 积分说明 - 禁言标准 - 有奖举报

查看: 2063|回复: 0
收起左侧

[源码分享] 游戏开发学习笔记-5.摄像机自动导航

[复制链接]
结帖率:96% (24/25)
发表于 2015-6-17 11:09:51 | 显示全部楼层 |阅读模式   广东省深圳市
本帖最后由 小生怕怕啊 于 2015-6-17 11:11 编辑

这次为引擎增加了一个3D摄像机类,便于场景的游览。

本次利用摄像机类实现了简单的场景漫游自动导航。

下面是摄像机类的具体细节!
p2.jpg

  1. #include "Camera.h"

  2. //计算取景矩阵
  3. void CCamera::CalcViewMatrix( D3DXMATRIX* pMatrix )
  4. {
  5. //规格化向量
  6. D3DXVec3Normalize(&m_vLook,&m_vLook); //规范化观察向量
  7. D3DXVec3Cross(&m_vUp,&m_vLook,&m_vRight); //上向量垂直观察向量
  8. D3DXVec3Normalize(&m_vUp,&m_vUp); //规范化上向量
  9. D3DXVec3Cross(&m_vRight,&m_vUp,&m_vLook); //右向量垂直上向量
  10. D3DXVec3Normalize(&m_vRight,&m_vRight); //规范化右向量

  11. //取景变换矩阵
  12. pMatrix->_11=m_vRight.x;
  13. pMatrix->_12=m_vUp.x;
  14. pMatrix->_13=m_vLook.x;
  15. pMatrix->_14=0.0f;

  16. pMatrix->_21=m_vRight.y;
  17. pMatrix->_22=m_vUp.y;
  18. pMatrix->_23=m_vLook.y;
  19. pMatrix->_24=0.0f;

  20. pMatrix->_31=m_vRight.z;
  21. pMatrix->_32=m_vUp.z;
  22. pMatrix->_33=m_vLook.z;
  23. pMatrix->_34=0.0f;

  24. pMatrix->_41=-D3DXVec3Dot(&m_vRight,&m_vCameraPosition);
  25. pMatrix->_42=-D3DXVec3Dot(&m_vUp,&m_vCameraPosition);
  26. pMatrix->_43=-D3DXVec3Dot(&m_vLook,&m_vCameraPosition);
  27. pMatrix->_44=1.0f;
  28. }

  29. //构造函数
  30. CCamera::CCamera( LPDIRECT3DDEVICE9 pDev )
  31. {
  32. m_Dev=pDev;
  33. m_vRight=D3DXVECTOR3(1.0f,0.0f,0.0f);
  34. m_vUp=D3DXVECTOR3(0.0f,1.0f,0.0f);
  35. m_vLook=D3DXVECTOR3(0.0f,0.0f,1.0f);
  36. m_vCameraPosition=D3DXVECTOR3(0.0f,0.0f,-300.0f);
  37. m_vLookPosition=D3DXVECTOR3(0.0f,0.0f,0.0f);
  38. }

  39. //设置观察位置
  40. void CCamera::SetLookPosition( D3DXVECTOR3* pVector/*=NULL*/ )
  41. {
  42. if (pVector!=NULL)
  43. {
  44. m_vLookPosition=*pVector;
  45. }
  46. else
  47. {
  48. m_vLookPosition=D3DXVECTOR3(0.0f,0.0f,1.0f);
  49. }
  50. m_vLook=m_vLookPosition-m_vCameraPosition;
  51. D3DXVec3Normalize(&m_vLook,&m_vLook);

  52. D3DXVec3Cross(&m_vUp,&m_vLook,&m_vRight);
  53. D3DXVec3Normalize(&m_vUp,&m_vUp);
  54. D3DXVec3Cross(&m_vRight,&m_vUp,&m_vLook);
  55. D3DXVec3Normalize(&m_vRight,&m_vRight);
  56. }

  57. //设置摄像机位置
  58. void CCamera::SetCameraPosition( D3DXVECTOR3* pVector/*=NULL*/ )
  59. {
  60. D3DXVECTOR3 camera=D3DXVECTOR3(0.0f,0.0f,-300.0f);
  61. m_vCameraPosition=pVector?(*pVector):camera;
  62. }

  63. void CCamera::SetViewMatrix( D3DXMATRIX* pMatrix/*=NULL*/ )
  64. {
  65. if(pMatrix) m_MatrixView=*pMatrix;
  66. else CalcViewMatrix(&m_MatrixView);
  67. m_Dev->SetTransform(D3DTS_VIEW,&m_MatrixView);
  68. m_vRight=D3DXVECTOR3(m_MatrixView._11,m_MatrixView._12,m_MatrixView._13);
  69. m_vUp=D3DXVECTOR3(m_MatrixView._21,m_MatrixView._22,m_MatrixView._23);
  70. m_vLook=D3DXVECTOR3(m_MatrixView._31,m_MatrixView._32,m_MatrixView._33);
  71. }

  72. void CCamera::SetProjMatrix( int nWidth,int nHeight,D3DXMATRIX* pMatrix/*=NULL*/ )
  73. {
  74. if(pMatrix!=NULL) m_Projection=*pMatrix;
  75. else D3DXMatrixPerspectiveFovLH(&m_Projection,45.0f,(float)nWidth/nHeight,0.1f,3000.0f);
  76. m_Dev->SetTransform(D3DTS_PROJECTION,&m_Projection);
  77. }

  78. //沿右向量移动
  79. void CCamera::MoveAlongRight( float amount )
  80. {
  81. m_vCameraPosition+=m_vRight*amount;
  82. m_vLookPosition+=m_vRight*amount;
  83. }

  84. //沿上向量移动
  85. void CCamera::MoveAlongUp( float amount )
  86. {
  87. m_vCameraPosition+=m_vUp*amount;
  88. m_vLookPosition+=m_vUp*amount;
  89. }

  90. //沿观察向量移动
  91. void CCamera::MoveAlongLook( float amount )
  92. {
  93. m_vCameraPosition+=m_vLook*amount;
  94. m_vLookPosition+=m_vLook*amount;
  95. }

  96. //绕右向量旋转
  97. void CCamera::RotationRieght( float angle )
  98. {
  99. D3DXMATRIX Rotation;
  100. D3DXMatrixRotationAxis(&Rotation,&m_vRight,angle); //创建绕右向量旋转angel度的矩阵
  101. D3DXVec3TransformCoord(&m_vUp,&m_vUp,&Rotation); //让上向量绕右向量旋转angle个角度
  102. D3DXVec3TransformCoord(&m_vLook,&m_vLook,&Rotation); //让观察向量绕右向量旋转angle个角度
  103. m_vLookPosition=m_vLook*D3DXVec3Length(&m_vCameraPosition);
  104. }

  105. //绕上向量旋转
  106. void CCamera::RotationUp( float angle )
  107. {
  108. D3DXMATRIX Rotation;
  109. D3DXMatrixRotationAxis(&Rotation,&m_vUp,angle); //创建绕上向量旋转angel度的矩阵
  110. D3DXVec3TransformCoord(&m_vRight,&m_vRight,&Rotation); //让右向量绕上向量旋转angle个角度
  111. D3DXVec3TransformCoord(&m_vLook,&m_vLook,&Rotation); //让观察向量绕上向量旋转angle个角度
  112. m_vLookPosition=m_vLook*D3DXVec3Length(&m_vCameraPosition);
  113. }

  114. //绕观察向量旋转
  115. void CCamera::RotationLook( float angle )
  116. {
  117. D3DXMATRIX Rotation;
  118. D3DXMatrixRotationAxis(&Rotation,&m_vLook,angle); //创建绕观察向量旋转angel度的矩阵
  119. D3DXVec3TransformCoord(&m_vUp,&m_vUp,&Rotation); //让上向量绕观察向量旋转angle个角度
  120. D3DXVec3TransformCoord(&m_vRight,&m_vRight,&Rotation); //让右向量绕观察向量旋转angle个角度
  121. m_vLookPosition=m_vLook*D3DXVec3Length(&m_vCameraPosition);
  122. }

  123. CCamera::~CCamera()
  124. {

  125. }

  126. void CCamera::GetCameraPosition( D3DXVECTOR3* pVector )
  127. {
  128. *pVector=m_vCameraPosition;
  129. }
复制代码

  1. <P> </P>
  2. <DIV class=blockcode>
  3. <BLOCKQUOTE>#include <windows.h>
  4. #include "Engine.h"

  5. #define WIN_CLASS "dx01"//窗体类名
  6. #define WIN_NAME "3D摄像机自动导航" //窗体标题
  7. #define WIN_WIDTH 800 //窗体宽度
  8. #define WIN_HEIGHT 600 //窗体高度
  9. #define WIN_FULLSCREEN false //是否全屏


  10. Engine engine; //引擎对象
  11. Model pModel; //模型
  12. LPDIRECT3DDEVICE9 dev=NULL;
  13. CCamera* g_pCamera=NULL; //摄像机

  14. //游戏初始化
  15. bool GameInit(HWND hwnd);
  16. //游戏循环
  17. void GameLoop();
  18. //更新
  19. void GameUpdate();
  20. //游戏结束
  21. void GameEnd();


  22. //Windows消息回调函数
  23. LRESULT CALLBACK WndProc(HWND hwnd,UINT msg,WPARAM wparam,LPARAM lparam)
  24. {
  25. switch(msg)
  26. {
  27. case WM_DESTROY:
  28. PostQuitMessage(0);
  29. break;
  30. case WM_KEYUP:
  31. if (wparam==VK_ESCAPE)
  32. {
  33. PostQuitMessage(0);
  34. }
  35. break;
  36. }
  37. return DefWindowProc(hwnd,msg,wparam,lparam);
  38. }

  39. //Window入口函数
  40. int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd )
  41. {
  42. //设置窗口结构类属性
  43. WNDCLASSEX wc={sizeof(WNDCLASSEX),CS_CLASSDC,WndProc,0,0,hInstance,NULL,NULL,NULL,NULL,WIN_CLASS,NULL};
  44. //注册窗口类型
  45. RegisterClassEx(&wc);
  46. //创建窗口
  47. HWND hwnd= CreateWindow(WIN_CLASS,WIN_NAME,WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,CW_USEDEFAULT,WIN_WIDTH,WIN_HEIGHT,NULL,NULL,hInstance,NULL);
  48. if (hwnd)
  49. {
  50. ShowWindow(hwnd,nShowCmd); //显示窗口
  51. UpdateWindow(hwnd); //更新窗口

  52. if (GameInit(hwnd))
  53. {
  54. MSG msg;
  55. ZeroMemory(&msg,sizeof(msg));
  56. //窗口消息循环
  57. while (msg.message!=WM_QUIT)
  58. {
  59. if (PeekMessage(&msg,NULL,0U,0U,PM_REMOVE))
  60. {
  61. TranslateMessage(&msg); //转换消息
  62. DispatchMessage(&msg); //分派消息
  63. }
  64. else
  65. {
  66. GameLoop();
  67. }
  68. }
  69. GameEnd();
  70. }
  71. }
  72. UnregisterClass(WIN_CLASS,wc.hInstance);
  73. return 0;
  74. }
  75. //Game循环
  76. void GameLoop()
  77. {
  78. engine.ClearScreen();
  79. GameUpdate();
  80. engine.StartRender(); //开始渲染

  81. engine.DrawModel(&pModel);

  82. engine.EndRender(); //结束渲染
  83. }

  84. //Game开始
  85. bool GameInit(HWND hwnd)
  86. {
  87. if (!engine.Init(hwnd,WIN_WIDTH,WIN_HEIGHT))
  88. {
  89. return false;
  90. }
  91. if (!engine.LoadModel("edificio1.X",&pModel))
  92. {
  93. ShowMessage("载入模型失败!");
  94. return false;
  95. }
  96. dev= engine.GetDev();

  97. dev->SetRenderState(D3DRS_LIGHTING,false); //关闭光照
  98. dev->SetRenderState(D3DRS_CULLMODE,D3DCULL_NONE); //背面消隐

  99. g_pCamera=new CCamera(dev);
  100. g_pCamera->SetCameraPosition(&D3DXVECTOR3(0.0f,50.0f,-300.0f)); //设置初始摄像机位置
  101. g_pCamera->SetLookPosition(&D3DXVECTOR3(0.0f,50.0f,0.0f)); //设置初始观察点位置
  102. g_pCamera->SetViewMatrix(); //初始化取景变换矩阵
  103. g_pCamera->SetProjMatrix(WIN_WIDTH,WIN_HEIGHT); //初始化投影变换矩阵
  104. return true;
  105. }

  106. //GameOver
  107. void GameEnd()
  108. {
  109. //模型释放
  110. pModel.Release();
  111. //关闭引擎
  112. engine.Shutdown();
  113. SAFE_DELETE(g_pCamera);
  114. }
  115. float angle=0.0f;
  116. UINT uStep=1;
  117. float RotationSpeed=0.005f;
  118. float ForwardSpeed=1.0f;
  119. void GameUpdate()
  120. {
  121. D3DXVECTOR3 vPosition;
  122. g_pCamera->GetCameraPosition(&vPosition); //获取当前摄像机位置
  123. switch(uStep)
  124. {
  125. //1.前进
  126. case 1:
  127. if (vPosition.z<35.0f)
  128. {
  129. uStep=1;
  130. g_pCamera->MoveAlongLook(1.0f);
  131. }
  132. else uStep=2;
  133. break;

  134. //2.旋转
  135. case 2:
  136. if (angle<1.5f)
  137. {
  138. g_pCamera->RotationUp(RotationSpeed);
  139. angle+=RotationSpeed;
  140. }else
  141. {
  142. uStep=3;
  143. angle=0.0f;
  144. }
  145. break;
  146. //3.进入房间
  147. case 3:
  148. if (vPosition.z<45.0f)
  149. {
  150. g_pCamera->MoveAlongLook(1.0f);
  151. }
  152. else uStep=4;
  153. break;
  154. //4.左旋转
  155. case 4:
  156. if (angle<1.5f)
  157. {
  158. g_pCamera->RotationUp(-RotationSpeed);
  159. angle+=RotationSpeed;
  160. }else uStep=5;
  161. break;
  162. //5.前进
  163. case 5:
  164. if (vPosition.z<80)
  165. {
  166. g_pCamera->MoveAlongLook(ForwardSpeed);
  167. }else uStep=6;
  168. break;
  169. }
  170. D3DXMATRIX MatrixView;
  171. g_pCamera->CalcViewMatrix(&MatrixView);
  172. dev->SetTransform(D3DTS_VIEW,&MatrixView);
  173. }
复制代码


运行截图:





同步博客:http://blog.csdn.net/qq578023708/article/details/46521273
交流群:87341183

dx01.rar

1.6 MB, 下载次数: 8, 下载积分: 精币 -2 枚

您需要登录后才可以回帖 登录 | 注册

本版积分规则 致发广告者

发布主题 收藏帖子 返回列表

sitemap| 易语言源码| 易语言教程| 易语言论坛| 易语言模块| 手机版| 广告投放| 精易论坛
拒绝任何人以任何形式在本论坛发表与中华人民共和国法律相抵触的言论,本站内容均为会员发表,并不代表精易立场!
论坛帖子内容仅用于技术交流学习和研究的目的,严禁用于非法目的,否则造成一切后果自负!如帖子内容侵害到你的权益,请联系我们!
防范网络诈骗,远离网络犯罪 违法和不良信息举报电话0663-3422125,QQ: 793400750,邮箱:wp@125.la
Powered by Discuz! X3.4 揭阳市揭东区精易科技有限公司 ( 粤ICP备12094385号-1) 粤公网安备 44522102000125 增值电信业务经营许可证 粤B2-20192173

快速回复 返回顶部 返回列表