修改DX代码:实现按方向键上下能控制摄像机的距离

Code:
  1. //  
  2. // 2011/1/20  
  3. // cube.cpp文件:  
  4. //  
  5. // 渲染组旋转立方体在网格模式。演示了顶点和索引缓存,世界和观点变换  
  6. //       *新增功能:按方向键能上下左右能调整摄像机距离和目标的距离  
  7. //  
  8.   
  9. #include "d3dUtility.h"  
  10.   
  11. //  
  12. // 全局设置  
  13. //  
  14.   
  15. IDirect3DDevice9* Device = 0;   //dx设备对象  
  16.   
  17. const int Width  = 640;  
  18. const int Height = 480;  
  19.   
  20. IDirect3DVertexBuffer9* VB = 0;  
  21. IDirect3DIndexBuffer9*  IB = 0;  
  22.   
  23. D3DXVECTOR3 position(0.0f, 0.0f, -5.0f);    //视角位置  
  24. D3DXVECTOR3 target(0.0f, 0.0f, 0.0f);       //目标  
  25. D3DXVECTOR3 up(0.0f, 1.0f, 0.0f);           //高度  
  26. D3DXMATRIX V;                               //表面,看到的东西  
  27.   
  28. //  
  29. // 顶点/类和结构  
  30. //  
  31.   
  32. struct Vertex  
  33. {  
  34.     Vertex(){}  
  35.     Vertex(float x, float y, float z)  
  36.     {  
  37.         _x = x;  _y = y;  _z = z;  
  38.     }  
  39.     float _x, _y, _z;  
  40.     static const DWORD FVF;  
  41. };  
  42. const DWORD Vertex::FVF = D3DFVF_XYZ;  
  43.   
  44. //  
  45. //框架功能  
  46. //  
  47. bool Setup()  
  48. {  
  49.     //  
  50.     // 创建顶点和索引缓冲.  
  51.     //  
  52.   
  53.     Device->CreateVertexBuffer(  
  54.         8 * sizeof(Vertex),   
  55.         D3DUSAGE_WRITEONLY,  
  56.         Vertex::FVF,  
  57.         D3DPOOL_MANAGED,  
  58.         &VB,  
  59.         0);  
  60.   
  61.     Device->CreateIndexBuffer(  
  62.         36 * sizeof(WORD),  
  63.         D3DUSAGE_WRITEONLY,  
  64.         D3DFMT_INDEX16,  
  65.         D3DPOOL_MANAGED,  
  66.         &IB,  
  67.         0);  
  68.   
  69.     //  
  70.     // 填补缓冲器与立方体数据。  
  71.     //  
  72.   
  73.     // 定义独特的顶点。  
  74.     Vertex* vertices;  
  75.     VB->Lock(0, 0, (void**)&vertices, 0);  
  76.   
  77.     // vertices of a unit cube  
  78.     vertices[0] = Vertex(-1.0f, -1.0f, -1.0f);  
  79.     vertices[1] = Vertex(-1.0f,  1.0f, -1.0f);  
  80.     vertices[2] = Vertex( 1.0f,  1.0f, -1.0f);  
  81.     vertices[3] = Vertex( 1.0f, -1.0f, -1.0f);  
  82.     vertices[4] = Vertex(-1.0f, -1.0f,  1.0f);  
  83.     vertices[5] = Vertex(-1.0f,  1.0f,  1.0f);  
  84.     vertices[6] = Vertex( 1.0f,  1.0f,  1.0f);  
  85.     vertices[7] = Vertex( 1.0f, -1.0f,  1.0f);  
  86.   
  87.     VB->Unlock();  
  88.   
  89.     // 定义三角面的立方体:  
  90.     WORD* indices = 0;  
  91.     IB->Lock(0, 0, (void**)&indices, 0);  
  92.   
  93.     //正面  
  94.     indices[0]  = 0; indices[1]  = 1; indices[2]  = 2;  
  95.     indices[3]  = 0; indices[4]  = 2; indices[5]  = 3;  
  96.   
  97.     //背面  
  98.     indices[6]  = 4; indices[7]  = 6; indices[8]  = 5;  
  99.     indices[9]  = 4; indices[10] = 7; indices[11] = 6;  
  100.   
  101.     //左面  
  102.     indices[12] = 4; indices[13] = 5; indices[14] = 1;  
  103.     indices[15] = 4; indices[16] = 1; indices[17] = 0;  
  104.   
  105.     //右面  
  106.     indices[18] = 3; indices[19] = 2; indices[20] = 6;  
  107.     indices[21] = 3; indices[22] = 6; indices[23] = 7;  
  108.   
  109.     //顶面  
  110.     indices[24] = 1; indices[25] = 5; indices[26] = 6;  
  111.     indices[27] = 1; indices[28] = 6; indices[29] = 2;  
  112.   
  113.     //底面  
  114.     indices[30] = 4; indices[31] = 0; indices[32] = 3;  
  115.     indices[33] = 4; indices[34] = 3; indices[35] = 7;  
  116.   
  117.     IB->Unlock();  
  118.   
  119.     //  
  120.     // 位置和目标照相机。  
  121.     //  
  122.   
  123.     D3DXMatrixLookAtLH(&V, &position, &target, &up);    //摄像机函数  
  124.     Device->SetTransform(D3DTS_VIEW, &V);       //转换为试图  
  125.     //  
  126.     // 投影矩阵的.  
  127.     //  
  128.   
  129.     D3DXMATRIX proj;  
  130.     D3DXMatrixPerspectiveFovLH(  
  131.             &proj,  
  132.             D3DX_PI * 0.5f, // 90 - degree  
  133.             (float)Width / (float)Height,  
  134.             1.0f,  
  135.             1000.0f);  
  136.     Device->SetTransform(D3DTS_PROJECTION, &proj);  
  137.   
  138.     //  
  139.     // 切换到网格模式。  
  140.     //  
  141.   
  142.     Device->SetRenderState(D3DRS_FILLMODE, D3DFILL_WIREFRAME);      //设置渲染方式  
  143.   
  144.     return true;  
  145. }  
  146.   
  147. void Cleanup()  
  148. {  
  149.     d3d::Release<IDirect3DVertexBuffer9*>(VB);  
  150.     d3d::Release<IDirect3DIndexBuffer9*>(IB);  
  151. }  
  152.   
  153. void SetMatrixLookAt(D3DXVECTOR3 position,D3DXVECTOR3 target,D3DXVECTOR3 up,D3DXMATRIX V)  
  154. {  
  155.     D3DXMatrixLookAtLH(&V, &position, &target, &up);    //摄像机函数  
  156.     Device->SetTransform(D3DTS_VIEW, &V);       //转换为试图  
  157. }  
  158.   
  159. bool Display(float timeDelta)  
  160. {  
  161.     if( Device )  
  162.     {  
  163.         //  
  164.         // 旋转立方体:  
  165.         //  
  166.         D3DXMATRIX Rx, Ry;  
  167.   
  168.         // 定义x轴要旋转的角度  
  169.         static  float x = 0.0f;  
  170.         D3DXMatrixRotationX(&Rx, x);  
  171.         x+=timeDelta;  
  172.         // 重置的角度对零当角度达到 2*PI也就是360°  
  173.         if(x > 2*D3DX_PI)     
  174.         { x = 0.0f; }  
  175.   
  176.         // 定义y轴要旋转的角度  
  177.         static float y = 0.0f;  
  178.         D3DXMatrixRotationY(&Ry, y);  
  179.         y += timeDelta;  
  180.   
  181.         // 重置的角度对零当角度达到 2*PI也就是360°  
  182.         if( y >= 2*D3DX_PI )  
  183.             y = 0.0f;  
  184.   
  185.         // 结合x -和y维度旋转变换.  
  186.         D3DXMATRIX p = Rx * Ry;  
  187.   
  188.         Device->SetTransform(D3DTS_WORLD, &p);  
  189.   
  190.         //  
  191.         // 画现场:  
  192.         //  
  193.         Device->Clear(0, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0);  
  194.         Device->BeginScene();  
  195.   
  196.         Device->SetStreamSource(0, VB, 0, sizeof(Vertex));  
  197.         Device->SetIndices(IB);  
  198.         Device->SetFVF(Vertex::FVF);  
  199.   
  200.         // 画立方体.  
  201.         Device->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, 8, 0, 12);  
  202.   
  203.         Device->EndScene();  
  204.         Device->Present(0, 0, 0, 0);  
  205.     }  
  206.     return true;  
  207. }  
  208.   
  209.   
  210. //  
  211. // 消息处理  
  212. //  
  213. LRESULT CALLBACK d3d::WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)  
  214. {  
  215.     switch( msg )  
  216.     {  
  217.     case WM_DESTROY:  
  218.         ::PostQuitMessage(0);  
  219.         break;  
  220.           
  221.     case WM_KEYDOWN:  
  222.         switch(wParam)  
  223.         {  
  224.         case VK_ESCAPE:  
  225.             ::DestroyWindow(hwnd);break;  
  226.   
  227.         case VK_UP:             //摄像机位置靠近目标  
  228.             position.z+1<-1?position.z+=1:position.z;  
  229.             SetMatrixLookAt(position,target,up,V);  
  230.                 break;  
  231.         case VK_DOWN:           //摄像机位置远离目标  
  232.             position.z-=1;  
  233.             SetMatrixLookAt(position,target,up,V);  
  234.                 break;  
  235.         case VK_LEFT:  
  236.             position.x+=0.1;        //摄像机向左移动,同时观察点也相应移动  
  237.             target.x+=0.1;  
  238.             SetMatrixLookAt(position,target,up,V);  
  239.                 break;  
  240.         case VK_RIGHT:  
  241.             position.x-=0.1;        //摄像机向右移动,同时观察点也相应移动  
  242.             target.x-=0.1;  
  243.             SetMatrixLookAt(position,target,up,V);  
  244.                 break;  
  245.         }  
  246.     }  
  247.     return ::DefWindowProc(hwnd, msg, wParam, lParam);  
  248. }  
  249.   
  250. //  
  251. // 入口函数  
  252. //  
  253. int WINAPI WinMain(HINSTANCE hinstance,  
  254.                    HINSTANCE prevInstance,   
  255.                    PSTR cmdLine,  
  256.                    int showCmd)  
  257. {  
  258.     if(!d3d::InitD3D(hinstance,  
  259.         Width, Height, true, D3DDEVTYPE_HAL, &Device))  
  260.     {  
  261.         ::MessageBox(0, "InitD3D() - FAILED", 0, 0);  
  262.         return 0;  
  263.     }  
  264.           
  265.     if(!Setup())  
  266.     {  
  267.         ::MessageBox(0, "Setup() - FAILED", 0, 0);  
  268.         return 0;  
  269.     }  
  270.   
  271.     d3d::EnterMsgLoop( Display );  
  272.   
  273.     Cleanup();  
  274.   
  275.     Device->Release();  
  276.   
  277.     return 0;  
  278. }  

 

d3dUtility.cpp文件:

Code:
  1. //  
  2. //   
  3. // d3dUtility.cpp文件:  
  4. //   
  5. // 作者:弗兰克露娜(C)保留所有权利  
  6. //  
  7. // 系统:的AMD Athlon 1800 + XP,512 DDR的Geforce 3日,Windows XP,MSVC + + 7.0  
  8. //  
  9. // 组:提供效用函数简化大体任务。  
  10. //            
  11. //  
  12.   
  13. #include "d3dUtility.h"  
  14.   
  15. bool d3d::InitD3D(  
  16.     HINSTANCE hInstance,  
  17.     int width, int height,  
  18.     bool windowed,  
  19.     D3DDEVTYPE deviceType,  
  20.     IDirect3DDevice9** device)  
  21. {  
  22.     //  
  23.     //创造应用的主窗口.  
  24.     //  
  25.   
  26.     WNDCLASS wc;  
  27.   
  28.     wc.style         = CS_HREDRAW | CS_VREDRAW;  
  29.     wc.lpfnWndProc   = (WNDPROC)d3d::WndProc;   
  30.     wc.cbClsExtra    = 0;  
  31.     wc.cbWndExtra    = 0;  
  32.     wc.hInstance     = hInstance;  
  33.     wc.hIcon         = LoadIcon(0, IDI_APPLICATION);  
  34.     wc.hCursor       = LoadCursor(0, IDC_ARROW);  
  35.     wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);  
  36.     wc.lpszMenuName  = 0;  
  37.     wc.lpszClassName = "Direct3D9App";  
  38.   
  39.     if( !RegisterClass(&wc) )   
  40.     {  
  41.         ::MessageBox(0, "RegisterClass() - FAILED", 0, 0);  
  42.         return false;  
  43.     }  
  44.           
  45.     HWND hwnd = 0;  
  46.     hwnd = ::CreateWindow("Direct3D9App""Direct3D9App",   
  47.         WS_EX_TOPMOST,  
  48.         0, 0, width, height,  
  49.         0 /*父窗口句柄*/, 0 /* 菜单 */, hInstance, 0 /*扩展*/);   
  50.   
  51.     if( !hwnd )  
  52.     {  
  53.         ::MessageBox(0, "CreateWindow() - FAILED", 0, 0);  
  54.         return false;  
  55.     }  
  56.   
  57.     ::ShowWindow(hwnd, SW_SHOW);  
  58.     ::UpdateWindow(hwnd);  
  59.   
  60.     //  
  61.     // 初始 D3D:   
  62.     //  
  63.   
  64.     HRESULT hr = 0;  
  65.   
  66.     // Step 1: 创建 IDirect3D9 对象.  
  67.   
  68.     IDirect3D9* d3d9 = 0;  
  69.     d3d9 = Direct3DCreate9(D3D_SDK_VERSION);  
  70.   
  71.     if( !d3d9 )  
  72.     {  
  73.         ::MessageBox(0, "Direct3DCreate9() - FAILED", 0, 0);  
  74.         return false;  
  75.     }  
  76.   
  77.     // Step 2: 检查硬件能否支持硬件顶点处理.  
  78.   
  79.     D3DCAPS9 caps;  
  80.     d3d9->GetDeviceCaps(D3DADAPTER_DEFAULT, deviceType, &caps);  
  81.   
  82.     int vp = 0;  
  83.     if( caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT )  
  84.         vp = D3DCREATE_HARDWARE_VERTEXPROCESSING;  
  85.     else  
  86.         vp = D3DCREATE_SOFTWARE_VERTEXPROCESSING;  
  87.   
  88.     // Step 3: 填满 the D3DPRESENT_PARAMETERS 结构体.  
  89.    
  90.     D3DPRESENT_PARAMETERS d3dpp;  
  91.     d3dpp.BackBufferWidth            = width;  
  92.     d3dpp.BackBufferHeight           = height;  
  93.     d3dpp.BackBufferFormat           = D3DFMT_A8R8G8B8;  
  94.     d3dpp.BackBufferCount            = 1;  
  95.     d3dpp.MultiSampleType            = D3DMULTISAMPLE_NONE;  
  96.     d3dpp.MultiSampleQuality         = 0;  
  97.     d3dpp.SwapEffect                 = D3DSWAPEFFECT_DISCARD;   
  98.     d3dpp.hDeviceWindow              = hwnd;  
  99.     d3dpp.Windowed                   = windowed;  
  100.     d3dpp.EnableAutoDepthStencil     = true;   
  101.     d3dpp.AutoDepthStencilFormat     = D3DFMT_D24S8;  
  102.     d3dpp.Flags                      = 0;  
  103.     d3dpp.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT;  
  104.     d3dpp.PresentationInterval       = D3DPRESENT_INTERVAL_IMMEDIATE;  
  105.   
  106.     // Step 4:创建设备.  
  107.   
  108.     hr = d3d9->CreateDevice(  
  109.         D3DADAPTER_DEFAULT, // 主要适配器显卡(省缺值)  
  110.         deviceType,         // 设备类型  
  111.         hwnd,               // 和设备相关的窗口句柄  
  112.         vp,                 // 顶点处理类型  
  113.         &d3dpp,             // D3DPRESENT_PARAMETERS参数结构体  
  114.         device);            // 返回已经创建的设备对象  
  115.   
  116.     if( FAILED(hr) )  
  117.     {  
  118.         // 再试一次使用16位深度缓冲  
  119.         d3dpp.AutoDepthStencilFormat = D3DFMT_D16;  
  120.           
  121.         hr = d3d9->CreateDevice(  
  122.             D3DADAPTER_DEFAULT,  
  123.             deviceType,  
  124.             hwnd,  
  125.             vp,  
  126.             &d3dpp,  
  127.             device);  
  128.   
  129.         if( FAILED(hr) )  
  130.         {  
  131.             d3d9->Release(); // 释放D3D对象  
  132.             ::MessageBox(0, "CreateDevice() - FAILED", 0, 0);  
  133.             return false;  
  134.         }  
  135.     }  
  136.   
  137.     d3d9->Release(); // done with d3d9 object  
  138.       
  139.     return true;  
  140. }  
  141.   
  142. int d3d::EnterMsgLoop( bool (*ptr_display)(float timeDelta))  
  143. {  
  144.     MSG msg;  
  145.     ::ZeroMemory(&msg, sizeof(MSG));  
  146.   
  147.     static float lastTime = (float)timeGetTime();           //得到最近(相对过去)时间  
  148.   
  149.     while(msg.message != WM_QUIT)  
  150.     {  
  151.         if(::PeekMessage(&msg, 0, 0, 0, PM_REMOVE))  
  152.         {  
  153.             ::TranslateMessage(&msg);  
  154.             ::DispatchMessage(&msg);  
  155.         }  
  156.         else  
  157.         {     
  158.             float currTime  = (float)timeGetTime();             //得到当前时间  
  159.             float timeDelta = (currTime - lastTime)*0.0018;     //相当于控制物体的旋转速度0.001~0.002之间为好  
  160.   
  161.             ptr_display(timeDelta);     //不解释  
  162.   
  163.             lastTime = currTime;        //将当前时间传给最近(过去)时间  
  164.         }  
  165.     }  
  166.     return msg.wParam;  
  167. }  

d3dUtility.h文件:

Code:
  1. //  
  2. //   
  3. // d3dUtility.h文件:  
  4. //   
  5. // 作者:弗兰克露娜(C)保留所有权利  
  6. //  
  7. // 系统:的AMD Athlon 1800 + XP,512 DDR的Geforce 3日,Windows XP,MSVC + + 7.0  
  8. //  
  9. // 组:提供效用函数简化大体任务。  
  10. //            
  11. //  
  12.   
  13. #ifndef __d3dUtilityH__  
  14. #define __d3dUtilityH__  
  15.   
  16. #include <d3dx9.h>  
  17. #include <string>  
  18.   
  19. namespace d3d  
  20. {  
  21.     bool InitD3D(  
  22.         HINSTANCE hInstance,       // [in]应用实例的.  
  23.         int width, int height,     // [in]后台缓存尺寸.  
  24.         bool windowed,             // [in]窗口或全屏.  
  25.         D3DDEVTYPE deviceType,     // [in] HAL or REF  
  26.         IDirect3DDevice9** device);// [out]指定创建的设备.  
  27.   
  28.     int EnterMsgLoop(   
  29.         bool (*ptr_display)(float timeDelta));  
  30.   
  31.     LRESULT CALLBACK WndProc(  
  32.         HWND hwnd,  
  33.         UINT msg,   
  34.         WPARAM wParam,  
  35.         LPARAM lParam);  
  36.   
  37.     template<class T> void Release(T t)  
  38.     {  
  39.         if( t )  
  40.         {  
  41.             t->Release();  
  42.             t = 0;  
  43.         }  
  44.     }  
  45.           
  46.     template<class T> void Delete(T t)  
  47.     {  
  48.         if( t )  
  49.         {  
  50.             delete t;  
  51.             t = 0;  
  52.         }  
  53.     }  
  54. }  
  55.   
  56. #endif // __d3dUtilityH__  

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值