directinput

第11章:1.完成界面,没有模型加载

复制代码
  1 //-----------------------------------【头文件包含部分】---------------------------------------
  2 #include<d3d9.h>
  3 #include <d3dx9.h>
  4 #include <tchar.h>
  5 #include <time.h>
  6 #include <dinput.h>
  7 
  8 
  9 //-----------------------------------【库文件包含部分】---------------------------------------
 10 #pragma comment(lib,"winmm.lib") 
 11 #pragma comment(lib,"d3d9.lib")
 12 #pragma comment(lib,"d3dx9.lib")
 13 #pragma comment(lib, "dinput8.lib") 
 14 #pragma comment(lib,"dxguid.lib")
 15 
 16 
 17 //-----------------------------------【宏定义部分】--------------------------------------------
 18 #define WINDOW_WIDTH    800
 19 #define WINDOW_HEIGHT    600
 20 #define WINDOW_TITLE    L"安康学院数字媒体技术"
 21 //#define DIRECTINPUT_VERSION 0x0800 
 22 #define SAFE_RELEASE(p) { if(p) { (p)->Release(); (p)=NULL; } }//释放的是COM资源
 23 #define SAFE_DELETE(p)  { if(p) { delete (p); (p)=NULL; } }    //释放的是指针
 24 
 25 
 26 //-----------------------------------【全局变量声明部分】-------------------------------------
 27 LPDIRECT3DDEVICE9       g_pd3dDevice            = NULL; 
 28 LPD3DXFONT                g_pTextFPS                =NULL;
 29 LPD3DXFONT                g_pTextAdaperName       = NULL;
 30 LPD3DXFONT                g_pTextHelper           = NULL; 
 31 LPD3DXFONT                g_pTextInfor            = NULL;
 32 float                   g_FPS=0.0f;
 33 wchar_t                    g_strFPS[50]={0}; 
 34 wchar_t                    g_strAdapterName[60]={0};
 35 LPDIRECTINPUT8            g_pDirectInput      = NULL;
 36 LPDIRECTINPUTDEVICE8    g_pMouseDevice      = NULL;
 37 DIMOUSESTATE            g_diMouseState      = {0};
 38 LPDIRECTINPUTDEVICE8    g_pKeyboardDevice   = NULL;
 39 char                    g_pKeyStateBuffer[256] = {0};
 40 D3DXMATRIX                g_matWorld;
 41 LPD3DXMESH                g_pMesh     = NULL; 
 42 D3DMATERIAL9*            g_pMaterials    = NULL; 
 43 LPDIRECT3DTEXTURE9*        g_pTextures     = NULL;
 44 DWORD                    g_dwNumMtrls    = 0; 
 45 
 46 //-----------------------------------【全局函数声明部分】-------------------------------------
 47 LRESULT CALLBACK    WndProc( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam );
 48 HRESULT                    Direct3D_Init(HWND hwnd);
 49 HRESULT                    Objects_Init(HWND hwnd);
 50 void                    Direct3D_Render(HWND hwnd);
 51 void                    Direct3D_Update( HWND hwnd);
 52 void                    Direct3D_CleanUp( );
 53 float                    Get_FPS();
 54 void                    Matrix_Set();
 55 BOOL                    Device_Read(IDirectInputDevice8 *pDIDevice, void* pBuffer, long lSize) ;
 56 
 57 //-----------------------------------【WinMain( )函数】--------------------------------------
 58 //    描述:Windows应用程序的入口函数,我们的程序从这里开始
 59 int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nShowCmd)
 60 {
 61     //【1】开始设计一个完整的窗口类
 62     WNDCLASSEX wndClass = { 0 };
 63     wndClass.cbSize = sizeof( WNDCLASSEX ) ;
 64     wndClass.style = CS_HREDRAW | CS_VREDRAW;
 65     wndClass.lpfnWndProc = WndProc;
 66     wndClass.cbClsExtra        = 0;
 67     wndClass.cbWndExtra        = 0;
 68     wndClass.hInstance = hInstance;    
 69     wndClass.hIcon=(HICON)::LoadImage(NULL,L"icon.ico",IMAGE_ICON,0,0,LR_DEFAULTSIZE|LR_LOADFROMFILE);
 70     wndClass.hCursor = LoadCursor( NULL, IDC_ARROW );
 71     wndClass.hbrBackground=(HBRUSH)GetStockObject(GRAY_BRUSH);
 72     wndClass.lpszMenuName = NULL;
 73     wndClass.lpszClassName = L"ForTheDreamOfGameDevelop";
 74 
 75     //【2】注册窗口类
 76     if( !RegisterClassEx( &wndClass ) )    
 77         return -1;
 78 
 79     //【3】正式创建窗口
 80     HWND hwnd = CreateWindow( L"ForTheDreamOfGameDevelop",WINDOW_TITLE,    
 81         WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, WINDOW_WIDTH,
 82         WINDOW_HEIGHT, NULL, NULL, hInstance, NULL );
 83 
 84     if (S_OK==Direct3D_Init (hwnd))
 85         {
 86         MessageBox(hwnd, L"Direct3D初始化完成~!", L"消息窗口", 0);
 87         }
 88     else
 89         {
 90         MessageBox(hwnd, L"Direct3D初始化失败~!", L"消息窗口", 0);
 91         }
 92 
 93     //【4】窗口的移动、显示与更新
 94     MoveWindow(hwnd,250,80,WINDOW_WIDTH,WINDOW_HEIGHT,true);
 95     ShowWindow( hwnd, nShowCmd );
 96     UpdateWindow(hwnd);
 97 
 98     PlaySound(L"GameMedia//directinput//刻限.wav", NULL, SND_FILENAME | SND_ASYNC|SND_LOOP); 
 99 
100     //【5】消息循环过程
101     MSG msg = { 0 };
102     while( msg.message != WM_QUIT )
103         {
104         if( PeekMessage( &msg, 0, 0, 0, PM_REMOVE ) )   //查看应用程序消息队列,有消息时将队列中的消息派发出去。
105         {
106             TranslateMessage( &msg );        //将虚拟键消息转换为字符消息
107             DispatchMessage( &msg );        //该函数分发一个消息给窗口程序。
108         }
109         else
110         {
111             Direct3D_Render(hwnd);   //进行渲染
112         }
113     }
114 
115     //【6】窗口类的注销
116     UnregisterClass(L"ForTheDreamOfGameDevelop", wndClass.hInstance); 
117         return 0;  
118 }
119 
120 //-----------------------------------【WndProc( )函数】--------------------------------------
121 LRESULT CALLBACK WndProc( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam )      
122 {
123     switch( message )
124     {
125         case WM_PAINT:
126             Direct3D_Render(hwnd);
127             ValidateRect(hwnd, NULL);
128             break;
129 
130         case WM_KEYDOWN:
131             if (wParam == VK_ESCAPE)
132                 DestroyWindow(hwnd);
133             break;
134 
135         case WM_DESTROY:
136             Direct3D_CleanUp();
137             PostQuitMessage( 0 );
138             break;    
139 
140         default:
141             return DefWindowProc( hwnd, message, wParam, lParam );
142     }
143     return 0;
144 }
145 
146 //-----------------------------------【Direct3D_Init( )函数】--------------------------------------
147 HRESULT                    Direct3D_Init(HWND hwnd)
148 {
149     //Direct3D初始化,第一步
150     LPDIRECT3D9 pD3D=NULL;
151     if(NULL==(pD3D=Direct3DCreate9(D3D_SDK_VERSION)))
152         return E_FAIL;
153 
154     //Direct3D初始化,第二步
155     D3DCAPS9 caps; int vp = 0;
156     if( FAILED( pD3D->GetDeviceCaps( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, &caps ) ) )
157     {
158         return E_FAIL;
159     }
160     if( caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT )
161 
162         vp = D3DCREATE_HARDWARE_VERTEXPROCESSING; 
163     else
164         vp = D3DCREATE_SOFTWARE_VERTEXPROCESSING;
165 
166 
167     //Direct3D初始化,第三步,D3DPRESENT_PARAMETERS结构体
168 
169     D3DPRESENT_PARAMETERS d3dpp; 
170     ZeroMemory(&d3dpp, sizeof(d3dpp));
171     d3dpp.BackBufferWidth            = WINDOW_WIDTH;
172     d3dpp.BackBufferHeight           = WINDOW_HEIGHT;
173     d3dpp.BackBufferFormat           = D3DFMT_A8R8G8B8;
174     d3dpp.BackBufferCount            = 1;
175     d3dpp.MultiSampleType            = D3DMULTISAMPLE_NONE;
176     d3dpp.MultiSampleQuality         = 0;
177     d3dpp.SwapEffect                 = D3DSWAPEFFECT_DISCARD; 
178     d3dpp.hDeviceWindow              = hwnd;
179     d3dpp.Windowed                   = true;
180     d3dpp.EnableAutoDepthStencil     = true; 
181     d3dpp.AutoDepthStencilFormat     = D3DFMT_D24S8;
182     d3dpp.Flags                      = 0;
183     d3dpp.FullScreen_RefreshRateInHz = 0;
184     d3dpp.PresentationInterval       = D3DPRESENT_INTERVAL_IMMEDIATE;
185 
186     //Direct3D初始化,第四步
187 
188     if(FAILED(pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, 
189         hwnd, vp, &d3dpp, &g_pd3dDevice)))
190         return E_FAIL;
191 
192     wchar_t TempName[60]=L"当前显卡型号:";
193     D3DADAPTER_IDENTIFIER9 Adapter;
194     pD3D->GetAdapterIdentifier(0,0,&Adapter);
195     int len = MultiByteToWideChar(CP_ACP,0, Adapter.Description, -1, NULL, 0);
196     MultiByteToWideChar(CP_ACP, 0, Adapter.Description, -1, g_strAdapterName, len);
197     wcscat_s(TempName,g_strAdapterName);
198     wcscpy_s(g_strAdapterName,TempName);
199 
200     //// 1.创建DirectInput接口和设备
201     //DirectInput8Create(hInstance, 0x0800, IID_IDirectInput8, (void**)&g_pDirectInput, NULL);
202     //g_pDirectInput->CreateDevice(GUID_SysKeyboard, &g_pMouseDevice, NULL);
203 
204     ////2.数据格式
205     //g_pDirectInput->CreateDevice(GUID_SysMouse, &g_pMouseDevice, NULL);
206     //g_pMouseDevice->SetDataFormat(&c_dfDIMouse);
207     //g_pMouseDevice->SetCooperativeLevel(hwnd, DISCL_FOREGROUND | DISCL_NONEXCLUSIVE);
208 
209     ////3.获取设备控制权
210     //g_pMouseDevice->Acquire();
211 
212     //DirectInput8Create(hInstance, 0x0800, IID_IDirectInput8, (void**)&g_pDirectInput, NULL);
213     //g_pDirectInput->CreateDevice(GUID_SysKeyboard, &g_pKeyboardDevice, NULL);
214 
215     //g_pKeyboardDevice->SetDataFormat(&c_dfDIKeyboard);
216     //g_pKeyboardDevice->SetCooperativeLevel(hwnd, DISCL_FOREGROUND | DISCL_NONEXCLUSIVE);
217 
218     //g_pKeyboardDevice->Acquire();
219 
220     
221 
222     if(!(S_OK==Objects_Init(hwnd))) return E_FAIL;
223     SAFE_RELEASE(pD3D); 
224     return S_OK;
225 
226 }
227 
228 
229 //-----------------------------------【Object_Init( )函数】--------------------------------------
230 HRESULT Objects_Init(HWND hwnd)
231 {
232         D3DXCreateFont(g_pd3dDevice, 36, 0, 0, 1000, false, DEFAULT_CHARSET, 
233         OUT_DEFAULT_PRECIS, DEFAULT_QUALITY, 0, _T("Calibri"), &g_pTextFPS);
234 
235         D3DXCreateFont(g_pd3dDevice, 20, 0, 1000, 0, false, DEFAULT_CHARSET, 
236         OUT_DEFAULT_PRECIS, DEFAULT_QUALITY, 0, L"华文中宋", &g_pTextAdaperName); 
237 
238         D3DXCreateFont(g_pd3dDevice, 23, 0, 1000, 0, false, DEFAULT_CHARSET, 
239         OUT_DEFAULT_PRECIS, DEFAULT_QUALITY, 0, L"微软雅黑", &g_pTextHelper); 
240     
241         D3DXCreateFont(g_pd3dDevice, 26, 0, 1000, 0, false, DEFAULT_CHARSET, 
242         OUT_DEFAULT_PRECIS, DEFAULT_QUALITY, 0, L"黑体", &g_pTextInfor); 
243 
244 
245     // 从X文件中加载网格数据
246     LPD3DXBUFFER pAdjBuffer  = NULL;
247     LPD3DXBUFFER pMtrlBuffer = NULL;
248     D3DXLoadMeshFromX(L"GameMedia//directinput//loli.x", D3DXMESH_MANAGED, g_pd3dDevice, 
249         &pAdjBuffer, &pMtrlBuffer, NULL, &g_dwNumMtrls, &g_pMesh);
250 
251     D3DXMATERIAL *pMtrls = (D3DXMATERIAL*)pMtrlBuffer->GetBufferPointer();
252     g_pMaterials = new D3DMATERIAL9[g_dwNumMtrls];
253     g_pTextures  = new LPDIRECT3DTEXTURE9[g_dwNumMtrls];
254 
255     for (DWORD i=0; i<g_dwNumMtrls; i++) 
256     {
257         g_pMaterials[i] = pMtrls[i].MatD3D;
258         g_pMaterials[i].Ambient = g_pMaterials[i].Diffuse;
259         g_pTextures[i]  = NULL;
260         D3DXCreateTextureFromFileA(g_pd3dDevice, pMtrls[i].pTextureFilename, &g_pTextures[i]);
261     }
262     pAdjBuffer->Release();
263     pMtrlBuffer->Release();
264 
265     g_pd3dDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW);
266     g_pd3dDevice->SetRenderState(D3DRS_AMBIENT, D3DXCOLOR(1.0f, 1.0f, 1.0f, 1.0f));
267     return S_OK;
268 }
269 
270 //-----------------------------------【Direct3D_Render( )函数】--------------------------------------
271 void Direct3D_Render(HWND hwnd)
272 {//1
273     g_pd3dDevice->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0);
274     RECT formatRect;
275     GetClientRect(hwnd, &formatRect);
276     //2
277     g_pd3dDevice->BeginScene();   
278     //3
279     /*for (DWORD i = 0; i < g_dwNumMtrls; i++)
280             {
281                 g_pd3dDevice->SetMaterial(&g_pMaterials[i]);
282                 g_pd3dDevice->SetTexture(0, g_pTextures[i]);
283                 g_pMesh->DrawSubset(i);
284             }*/
285 
286      int charCount = swprintf_s(g_strFPS, 20, _T("FPS:%0.3f"), Get_FPS() );
287             g_pTextFPS->DrawText(NULL, g_strFPS, charCount , &formatRect, DT_TOP | DT_RIGHT, D3DCOLOR_RGBA(0,239,136,255));
288     
289             g_pTextAdaperName->DrawText(NULL,g_strAdapterName, -1, &formatRect, 
290                 DT_TOP | DT_LEFT, D3DXCOLOR(1.0f, 0.5f, 0.0f, 1.0f));
291 
292             formatRect.top = 30;
293             static wchar_t strInfo[256] = {0};
294             swprintf_s(strInfo,-1, L"模型坐标: (%.2f, %.2f, %.2f)", g_matWorld._41, g_matWorld._42, g_matWorld._43);
295             g_pTextHelper->DrawText(NULL, strInfo, -1, &formatRect, DT_SINGLELINE | DT_NOCLIP | DT_LEFT, D3DCOLOR_RGBA(135,239,136,255));
296 
297 
298 
299             formatRect.left = 0,formatRect.top = 380;
300             g_pTextInfor->DrawText(NULL, L"控制说明:", -1, &formatRect, 
301                 DT_SINGLELINE | DT_NOCLIP | DT_LEFT, D3DCOLOR_RGBA(235,123,230,255));
302             formatRect.top += 35;
303             g_pTextHelper->DrawText(NULL, L"    按住鼠标左键并拖动:平移模型", -1, &formatRect, 
304                 DT_SINGLELINE | DT_NOCLIP | DT_LEFT, D3DCOLOR_RGBA(255,200,0,255));
305             formatRect.top += 25;
306             g_pTextHelper->DrawText(NULL, L"    按住鼠标右键并拖动:旋转模型", -1, &formatRect, 
307                 DT_SINGLELINE | DT_NOCLIP | DT_LEFT, D3DCOLOR_RGBA(255,200,0,255));
308             formatRect.top += 25;
309             g_pTextHelper->DrawText(NULL, L"    滑动鼠标滚轮:拉伸模型", -1, &formatRect, 
310                 DT_SINGLELINE | DT_NOCLIP | DT_LEFT, D3DCOLOR_RGBA(255,200,0,255));
311             formatRect.top += 25;
312             g_pTextHelper->DrawText(NULL, L"    W、S、A、D键:平移模型 ", -1, &formatRect, 
313                 DT_SINGLELINE | DT_NOCLIP | DT_LEFT, D3DCOLOR_RGBA(255,200,0,255));
314             formatRect.top += 25;
315             g_pTextHelper->DrawText(NULL, L"    上、下、左、右方向键:旋转模型 ", -1, &formatRect, 
316                 DT_SINGLELINE | DT_NOCLIP | DT_LEFT, D3DCOLOR_RGBA(255,200,0,255));
317             formatRect.top += 25;
318             g_pTextHelper->DrawText(NULL, L"    ESC键 : 退出程序", -1, &formatRect, 
319                 DT_SINGLELINE | DT_NOCLIP | DT_LEFT, D3DCOLOR_RGBA(255,200,0,255));
320     //4
321     g_pd3dDevice->EndScene(); 
322     //5
323     g_pd3dDevice->Present(NULL, NULL, NULL, NULL); 
324 }
325 
326 //-----------------------------------【Matrix_Set( )函数】--------------------------------------
327 void Matrix_Set()
328 {
329        D3DXMATRIX matView; 
330     D3DXVECTOR3 vEye(0.0f, 0.0f, -250.0f);
331     D3DXVECTOR3 vAt(0.0f, 0.0f, 0.0f); 
332     D3DXVECTOR3 vUp(0.0f, 1.0f, 0.0f);
333     D3DXMatrixLookAtLH(&matView, &vEye, &vAt, &vUp);
334     g_pd3dDevice->SetTransform(D3DTS_VIEW, &matView);
335 
336 
337     D3DXMATRIX matProj;
338     D3DXMatrixPerspectiveFovLH(&matProj, D3DX_PI / 4.0f,(float)((double)WINDOW_WIDTH/WINDOW_HEIGHT),1.0f, 1000.0f);
339     g_pd3dDevice->SetTransform(D3DTS_PROJECTION, &matProj); 
340 
341     D3DVIEWPORT9 vp;
342     vp.X      = 0;
343     vp.Y      = 0;
344     vp.Width  = WINDOW_WIDTH;
345     vp.Height = WINDOW_HEIGHT;
346     vp.MinZ   = 0.0f;
347     vp.MaxZ   = 1.0f;
348     g_pd3dDevice->SetViewport(&vp);
349 }
350 //-----------------------------------【Direct3D_Update( )函数】--------------------------------
351 void    Direct3D_Update( HWND hwnd)
352 {
353 
354 
355 
356 }
357 
358 
359 //-----------------------------------【Get_FPS( )函数】------------------------------------------
360 float    Get_FPS()
361 {
362     static float  fps = 0;//fps值
363     static int     frameCount = 0;//帧数
364     static float  currentTime =0.0f;//当前时间
365     static float  lastTime = 0.0f;//持续时间
366 
367     frameCount++;
368     currentTime=timeGetTime()*0.001f;//获取系统时间
369 
370     if(currentTime-lastTime>1.0f)
371     {
372         fps = (float)frameCount /(currentTime - lastTime);
373         lastTime=currentTime;
374         frameCount=0;
375 
376     }
377     return fps;
378 
379 }
380 //-----------------------------------【Direct3D_CleanUp( )函数】--------------------------------
381 void Direct3D_CleanUp()
382 {
383     //释放COM接口对象
384     //g_pMouseDevice->Unacquire();
385     //g_pKeyboardDevice->Unacquire();
386     for (DWORD i = 0; i<g_dwNumMtrls; i++) 
387         SAFE_RELEASE(g_pTextures[i]);
388     SAFE_DELETE(g_pTextures)
389     SAFE_DELETE(g_pMaterials)
390     SAFE_RELEASE(g_pMesh)
391     SAFE_RELEASE(g_pTextFPS)
392     SAFE_RELEASE(g_pd3dDevice)    
393     SAFE_RELEASE(g_pMouseDevice)
394     SAFE_RELEASE(g_pKeyboardDevice)
395 }
View Code
复制代码

第11章:2.完成界面,有模型加载

复制代码
  1 //第2步,宏定义部分移动到最前面
  2 //-----------------------------------【宏定义部分】--------------------------------------------
  3 #define WINDOW_WIDTH    800
  4 #define WINDOW_HEIGHT    600
  5 #define WINDOW_TITLE    L"安康学院数字媒体技术"
  6 #define DIRECTINPUT_VERSION 0x0800 
  7 #define SAFE_RELEASE(p) { if(p) { (p)->Release(); (p)=NULL; } }//释放的是COM资源
  8 #define SAFE_DELETE(p)  { if(p) { delete (p); (p)=NULL; } }    //释放的是指针
  9 
 10 //-----------------------------------【头文件包含部分】---------------------------------------
 11 #include<d3d9.h>
 12 #include <d3dx9.h>
 13 #include <tchar.h>
 14 #include <time.h>
 15 #include <dinput.h>
 16 
 17 
 18 //-----------------------------------【库文件包含部分】---------------------------------------
 19 #pragma comment(lib,"winmm.lib") 
 20 #pragma comment(lib,"d3d9.lib")
 21 #pragma comment(lib,"d3dx9.lib")
 22 #pragma comment(lib, "dinput8.lib") 
 23 #pragma comment(lib,"dxguid.lib")
 24 
 25 /*
 26 //-----------------------------------【宏定义部分】--------------------------------------------
 27 #define WINDOW_WIDTH    800
 28 #define WINDOW_HEIGHT    600
 29 #define WINDOW_TITLE    L"安康学院数字媒体技术"
 30 //第1步,因为老出现这个报错。所有加这一句,同时要把宏定义部分移动到最前面,在#include <dinput.h>的前面以免重复定义。
 31 /*c:\program files (x86)\microsoft directx sdk (june 2010)\include\dinput.h: DIRECTINPUT_VERSION undefined. Defaulting to version 0x0800
 32 1>c:\users\zhj\desktop\123\dx111\demo\demo\main.cpp(21): warning C4005: “°DIRECTINPUT_VERSION”±: 宏重定义
 33 
 34 #define DIRECTINPUT_VERSION 0x0800 
 35 #define SAFE_RELEASE(p) { if(p) { (p)->Release(); (p)=NULL; } }//释放的是COM资源
 36 #define SAFE_DELETE(p)  { if(p) { delete (p); (p)=NULL; } }    //释放的是指针
 37 
 38 */
 39 
 40 //-----------------------------------【全局变量声明部分】-------------------------------------
 41 LPDIRECT3DDEVICE9       g_pd3dDevice            = NULL; 
 42 LPD3DXFONT                g_pTextFPS                =NULL;
 43 LPD3DXFONT                g_pTextAdaperName       = NULL;
 44 LPD3DXFONT                g_pTextHelper           = NULL; 
 45 LPD3DXFONT                g_pTextInfor            = NULL;
 46 float                   g_FPS=0.0f;
 47 wchar_t                    g_strFPS[50]={0}; 
 48 wchar_t                    g_strAdapterName[60]={0};
 49 LPDIRECTINPUT8            g_pDirectInput      = NULL;
 50 LPDIRECTINPUTDEVICE8    g_pMouseDevice      = NULL;
 51 DIMOUSESTATE            g_diMouseState      = {0};
 52 LPDIRECTINPUTDEVICE8    g_pKeyboardDevice   = NULL;
 53 char                    g_pKeyStateBuffer[256] = {0};
 54 D3DXMATRIX                g_matWorld;
 55 LPD3DXMESH                g_pMesh     = NULL; 
 56 D3DMATERIAL9*            g_pMaterials    = NULL; 
 57 LPDIRECT3DTEXTURE9*        g_pTextures     = NULL;
 58 DWORD                    g_dwNumMtrls    = 0; 
 59 
 60 //-----------------------------------【全局函数声明部分】-------------------------------------
 61 LRESULT CALLBACK    WndProc( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam );
 62 HRESULT                    Direct3D_Init(HWND hwnd);
 63 HRESULT                    Objects_Init(HWND hwnd);
 64 void                    Direct3D_Render(HWND hwnd);
 65 void                    Direct3D_Update(HWND hwnd);
 66 void                    Direct3D_CleanUp( );
 67 float                    Get_FPS();
 68 void                    Matrix_Set();
 69 BOOL                    Device_Read(IDirectInputDevice8 *pDIDevice, void* pBuffer, long lSize) ;
 70 
 71 //-----------------------------------【WinMain( )函数】--------------------------------------
 72 //    描述:Windows应用程序的入口函数,我们的程序从这里开始
 73 int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nShowCmd)
 74 {
 75     //【1】开始设计一个完整的窗口类
 76     WNDCLASSEX wndClass = { 0 };
 77     wndClass.cbSize = sizeof( WNDCLASSEX ) ;
 78     wndClass.style = CS_HREDRAW | CS_VREDRAW;
 79     wndClass.lpfnWndProc = WndProc;
 80     wndClass.cbClsExtra        = 0;
 81     wndClass.cbWndExtra        = 0;
 82     wndClass.hInstance = hInstance;    
 83     wndClass.hIcon=(HICON)::LoadImage(NULL,L"icon.ico",IMAGE_ICON,0,0,LR_DEFAULTSIZE|LR_LOADFROMFILE);
 84     wndClass.hCursor = LoadCursor( NULL, IDC_ARROW );
 85     wndClass.hbrBackground=(HBRUSH)GetStockObject(GRAY_BRUSH);
 86     wndClass.lpszMenuName = NULL;
 87     wndClass.lpszClassName = L"ForTheDreamOfGameDevelop";
 88 
 89     //【2】注册窗口类
 90     if( !RegisterClassEx( &wndClass ) )    
 91         return -1;
 92 
 93     //【3】正式创建窗口
 94     HWND hwnd = CreateWindow( L"ForTheDreamOfGameDevelop",WINDOW_TITLE,    
 95         WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, WINDOW_WIDTH,
 96         WINDOW_HEIGHT, NULL, NULL, hInstance, NULL );
 97 
 98     if (S_OK==Direct3D_Init(hwnd))
 99         {
100         MessageBox(hwnd, L"Direct3D初始化完成~!", L"消息窗口", 0);
101         }
102     else
103         {
104         MessageBox(hwnd, L"Direct3D初始化失败~!", L"消息窗口", 0);
105         }
106 
107     //【4】窗口的移动、显示与更新
108     MoveWindow(hwnd,250,80,WINDOW_WIDTH,WINDOW_HEIGHT,true);
109     ShowWindow(hwnd, nShowCmd );
110     UpdateWindow(hwnd);
111 
112     PlaySound(L"刻限.wav", NULL, SND_FILENAME | SND_ASYNC|SND_LOOP); 
113 
114     //【5】消息循环过程
115     MSG msg = { 0 };
116     while( msg.message != WM_QUIT )
117         {
118         if( PeekMessage( &msg, 0, 0, 0, PM_REMOVE ) )   //查看应用程序消息队列,有消息时将队列中的消息派发出去。
119         {
120             TranslateMessage( &msg );        //将虚拟键消息转换为字符消息
121             DispatchMessage( &msg );        //该函数分发一个消息给窗口程序。
122         }
123         else
124         {
125             Direct3D_Render(hwnd);   //进行渲染
126         }
127     }
128 
129     //【6】窗口类的注销
130     UnregisterClass(L"ForTheDreamOfGameDevelop", wndClass.hInstance); 
131         return 0;  
132 }
133 
134 //-----------------------------------【WndProc( )函数】--------------------------------------
135 LRESULT CALLBACK WndProc( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam )      
136 {
137     switch( message )
138     {
139         case WM_PAINT:
140             Direct3D_Render(hwnd);
141             ValidateRect(hwnd, NULL);
142             break;
143 
144         case WM_KEYDOWN:
145             if (wParam == VK_ESCAPE)
146                 DestroyWindow(hwnd);
147             break;
148 
149         case WM_DESTROY:
150             Direct3D_CleanUp();
151             PostQuitMessage( 0 );
152             break;    
153 
154         default:
155             return DefWindowProc( hwnd, message, wParam, lParam );
156     }
157     return 0;
158 }
159 
160 //-----------------------------------【Direct3D_Init( )函数】--------------------------------------
161 HRESULT    Direct3D_Init(HWND hwnd)
162 {
163     //Direct3D初始化,第一步
164     LPDIRECT3D9 pD3D=NULL;
165     if(NULL==(pD3D=Direct3DCreate9(D3D_SDK_VERSION)))
166         return E_FAIL;
167 
168     //Direct3D初始化,第二步
169     D3DCAPS9 caps; int vp = 0;
170     if( FAILED( pD3D->GetDeviceCaps( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, &caps ) ) )
171     {
172         return E_FAIL;
173     }
174     if( caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT )
175 
176         vp = D3DCREATE_HARDWARE_VERTEXPROCESSING; 
177     else
178         vp = D3DCREATE_SOFTWARE_VERTEXPROCESSING;
179 
180 
181     //Direct3D初始化,第三步,D3DPRESENT_PARAMETERS结构体
182 
183     D3DPRESENT_PARAMETERS d3dpp; 
184     ZeroMemory(&d3dpp, sizeof(d3dpp));
185     d3dpp.BackBufferWidth            = WINDOW_WIDTH;
186     d3dpp.BackBufferHeight           = WINDOW_HEIGHT;
187     d3dpp.BackBufferFormat           = D3DFMT_A8R8G8B8;
188     d3dpp.BackBufferCount            = 1;
189     d3dpp.MultiSampleType            = D3DMULTISAMPLE_NONE;
190     d3dpp.MultiSampleQuality         = 0;
191     d3dpp.SwapEffect                 = D3DSWAPEFFECT_DISCARD; 
192     d3dpp.hDeviceWindow              = hwnd;
193     d3dpp.Windowed                   = true;
194     d3dpp.EnableAutoDepthStencil     = true; 
195     d3dpp.AutoDepthStencilFormat     = D3DFMT_D24S8;
196     d3dpp.Flags                      = 0;
197     d3dpp.FullScreen_RefreshRateInHz = 0;
198     d3dpp.PresentationInterval       = D3DPRESENT_INTERVAL_IMMEDIATE;
199 
200     //Direct3D初始化,第四步
201 
202     if(FAILED(pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, 
203         hwnd, vp, &d3dpp, &g_pd3dDevice)))
204         return E_FAIL;
205 
206     wchar_t TempName[60]=L"当前显卡型号:";
207     D3DADAPTER_IDENTIFIER9 Adapter;
208     pD3D->GetAdapterIdentifier(0,0,&Adapter);
209     int len = MultiByteToWideChar(CP_ACP,0, Adapter.Description, -1, NULL, 0);
210     MultiByteToWideChar(CP_ACP, 0, Adapter.Description, -1, g_strAdapterName, len);
211     wcscat_s(TempName,g_strAdapterName);
212     wcscpy_s(g_strAdapterName,TempName);
213 
214     //// 1.创建DirectInput接口和设备
215     //DirectInput8Create(hInstance, 0x0800, IID_IDirectInput8, (void**)&g_pDirectInput, NULL);
216     //g_pDirectInput->CreateDevice(GUID_SysKeyboard, &g_pMouseDevice, NULL);
217 
218     ////2.数据格式
219     //g_pDirectInput->CreateDevice(GUID_SysMouse, &g_pMouseDevice, NULL);
220     //g_pMouseDevice->SetDataFormat(&c_dfDIMouse);
221     //g_pMouseDevice->SetCooperativeLevel(hwnd, DISCL_FOREGROUND | DISCL_NONEXCLUSIVE);
222 
223     ////3.获取设备控制权
224     //g_pMouseDevice->Acquire();
225 
226     //DirectInput8Create(hInstance, 0x0800, IID_IDirectInput8, (void**)&g_pDirectInput, NULL);
227     //g_pDirectInput->CreateDevice(GUID_SysKeyboard, &g_pKeyboardDevice, NULL);
228 
229     //g_pKeyboardDevice->SetDataFormat(&c_dfDIKeyboard);
230     //g_pKeyboardDevice->SetCooperativeLevel(hwnd, DISCL_FOREGROUND | DISCL_NONEXCLUSIVE);
231 
232     //g_pKeyboardDevice->Acquire();
233 
234     
235 
236     if(!(S_OK==Objects_Init(hwnd))) return E_FAIL;
237     SAFE_RELEASE(pD3D); 
238     return S_OK;
239 
240 }
241 
242 
243 //-----------------------------------【Object_Init( )函数】--------------------------------------
244 HRESULT Objects_Init(HWND hwnd)
245 {
246         D3DXCreateFont(g_pd3dDevice, 36, 0, 0, 1000, false, DEFAULT_CHARSET, 
247         OUT_DEFAULT_PRECIS, DEFAULT_QUALITY, 0, _T("Calibri"), &g_pTextFPS);
248 
249         D3DXCreateFont(g_pd3dDevice, 20, 0, 1000, 0, false, DEFAULT_CHARSET, 
250         OUT_DEFAULT_PRECIS, DEFAULT_QUALITY, 0, L"华文中宋", &g_pTextAdaperName); 
251 
252         D3DXCreateFont(g_pd3dDevice, 23, 0, 1000, 0, false, DEFAULT_CHARSET, 
253         OUT_DEFAULT_PRECIS, DEFAULT_QUALITY, 0, L"微软雅黑", &g_pTextHelper); 
254     
255         D3DXCreateFont(g_pd3dDevice, 26, 0, 1000, 0, false, DEFAULT_CHARSET, 
256         OUT_DEFAULT_PRECIS, DEFAULT_QUALITY, 0, L"黑体", &g_pTextInfor); 
257 
258 
259     // 从X文件中加载网格数据
260     LPD3DXBUFFER pAdjBuffer  = NULL;
261     LPD3DXBUFFER pMtrlBuffer = NULL;
262     D3DXLoadMeshFromX(L"loli.x", D3DXMESH_MANAGED, g_pd3dDevice, 
263         &pAdjBuffer, &pMtrlBuffer, NULL, &g_dwNumMtrls, &g_pMesh);
264     // 读取材质和纹理数据
265     D3DXMATERIAL *pMtrls = (D3DXMATERIAL*)pMtrlBuffer->GetBufferPointer();//创建一个D3DXMATERIAL结构体用于读取材质和纹理信息
266     g_pMaterials = new D3DMATERIAL9[g_dwNumMtrls];
267     g_pTextures  = new LPDIRECT3DTEXTURE9[g_dwNumMtrls];
268 
269     for (DWORD i=0; i<g_dwNumMtrls; i++) 
270     {
271         //获取材质,并设置一下环境光的颜色值
272         g_pMaterials[i] = pMtrls[i].MatD3D;
273         g_pMaterials[i].Ambient = g_pMaterials[i].Diffuse;
274         //创建一下纹理对象
275         g_pTextures[i]  = NULL;
276         D3DXCreateTextureFromFileA(g_pd3dDevice, pMtrls[i].pTextureFilename, &g_pTextures[i]);
277     }
278     pAdjBuffer->Release();
279     pMtrlBuffer->Release();
280 
281 
282 
283     // 设置渲染状态
284     g_pd3dDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW);   //开启背面消隐
285     g_pd3dDevice->SetRenderState(D3DRS_AMBIENT, D3DXCOLOR(1.0f, 1.0f, 1.0f, 1.0f)); //设置环境光
286     //第3步
287     Matrix_Set();//调用封装了四大变换的函数,对Direct3D世界变换,取景变换,投影变换,视口变换进行设置
288 
289     return S_OK;
290 }
291 //-----------------------------------【Matrix_Set( )函数】--------------------------------------
292 void Matrix_Set()
293 {
294 //第4步 世界变换矩阵的设置
295 
296     //--------------------------------------------------------------------------------------
297     //【四大变换之一】:世界变换矩阵的设置
298     //--------------------------------------------------------------------------------------
299     D3DXMATRIX matWorld, Rx, Ry, Rz;
300     D3DXMatrixIdentity(&matWorld);                  // 单位化世界矩阵
301     D3DXMatrixRotationX(&Rx, D3DX_PI *(::timeGetTime() / 1000.0f));    // 绕X轴旋转
302     D3DXMatrixRotationY(&Ry, D3DX_PI *( ::timeGetTime() / 1000.0f/2));    // 绕Y轴旋转
303     D3DXMatrixRotationZ(&Rz, D3DX_PI *( ::timeGetTime() / 1000.0f/3));   // 绕Z轴旋转
304     matWorld = Rx * Ry * Rz * matWorld;             // 得到最终的组合矩阵
305     g_pd3dDevice->SetTransform(D3DTS_WORLD, &matWorld);  //设置世界变换矩阵
306 
307     //--------------------------------------------------------------------------------------
308     //【四大变换之二】:取景变换矩阵的设置
309     //--------------------------------------------------------------------------------------
310     D3DXMATRIX matView; //定义一个矩阵
311     D3DXVECTOR3 vEye(0.0f, 0.0f, -250.0f);  //摄像机的位置
312     D3DXVECTOR3 vAt(0.0f, 0.0f, 0.0f); //观察点的位置
313     D3DXVECTOR3 vUp(0.0f, 1.0f, 0.0f);//向上的向量
314     D3DXMatrixLookAtLH(&matView, &vEye, &vAt, &vUp); //计算出取景变换矩阵
315     g_pd3dDevice->SetTransform(D3DTS_VIEW, &matView); //应用取景变换矩阵
316 
317     //--------------------------------------------------------------------------------------
318     //【四大变换之三】:投影变换矩阵的设置
319     //--------------------------------------------------------------------------------------
320     D3DXMATRIX matProj; //定义一个矩阵
321     D3DXMatrixPerspectiveFovLH(&matProj, D3DX_PI / 4.0f,(float)((double)WINDOW_WIDTH/WINDOW_HEIGHT),1.0f, 1000.0f); //计算投影变换矩阵
322     g_pd3dDevice->SetTransform(D3DTS_PROJECTION, &matProj);  //设置投影变换矩阵
323 
324     //--------------------------------------------------------------------------------------
325     //【四大变换之四】:视口变换的设置
326     //--------------------------------------------------------------------------------------
327     D3DVIEWPORT9 vp; //实例化一个D3DVIEWPORT9结构体,然后做填空题给各个参数赋值就可以了
328     vp.X      = 0;        //表示视口相对于窗口的X坐标
329     vp.Y      = 0;        //视口相对对窗口的Y坐标
330     vp.Width  = WINDOW_WIDTH;    //视口的宽度
331     vp.Height = WINDOW_HEIGHT; //视口的高度
332     vp.MinZ   = 0.0f; //视口在深度缓存中的最小深度值
333     vp.MaxZ   = 1.0f;    //视口在深度缓存中的最大深度值
334     g_pd3dDevice->SetViewport(&vp); //视口的设置
335 }
336 //-----------------------------------【Direct3D_Render( )函数】--------------------------------------
337 void Direct3D_Render(HWND hwnd)
338 {//1
339 //第5步,清除buffer
340     g_pd3dDevice->Clear(0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(150, 150, 100), 1.0f, 0);
341     RECT formatRect;
342     GetClientRect(hwnd, &formatRect);
343     //2
344     g_pd3dDevice->BeginScene();   
345     //3
346 
347     for (DWORD i = 0; i < g_dwNumMtrls; i++)
348             {
349                 g_pd3dDevice->SetMaterial(&g_pMaterials[i]);
350                 g_pd3dDevice->SetTexture(0, g_pTextures[i]);
351                 g_pMesh->DrawSubset(i);
352             }
353 
354             int charCount = swprintf_s(g_strFPS, 20, _T("FPS:%0.3f"), Get_FPS() );
355             g_pTextFPS->DrawText(NULL, g_strFPS, charCount , &formatRect, DT_TOP | DT_RIGHT, D3DCOLOR_RGBA(0,239,136,255));
356     
357             g_pTextAdaperName->DrawText(NULL,g_strAdapterName, -1, &formatRect, 
358                 DT_TOP | DT_LEFT, D3DXCOLOR(1.0f, 0.5f, 0.0f, 1.0f));
359 
360             formatRect.top = 30;
361             static wchar_t strInfo[256] = {0};
362             swprintf_s(strInfo,-1, L"模型坐标: (%.2f, %.2f, %.2f)", g_matWorld._41, g_matWorld._42, g_matWorld._43);
363             g_pTextHelper->DrawText(NULL, strInfo, -1, &formatRect, DT_SINGLELINE | DT_NOCLIP | DT_LEFT, D3DCOLOR_RGBA(135,239,136,255));
364 
365 
366 
367             formatRect.left = 0,formatRect.top = 380;
368             g_pTextInfor->DrawText(NULL, L"控制说明:", -1, &formatRect, 
369                 DT_SINGLELINE | DT_NOCLIP | DT_LEFT, D3DCOLOR_RGBA(235,123,230,255));
370             formatRect.top += 35;
371             g_pTextHelper->DrawText(NULL, L"    按住鼠标左键并拖动:平移模型", -1, &formatRect, 
372                 DT_SINGLELINE | DT_NOCLIP | DT_LEFT, D3DCOLOR_RGBA(255,200,0,255));
373             formatRect.top += 25;
374             g_pTextHelper->DrawText(NULL, L"    按住鼠标右键并拖动:旋转模型", -1, &formatRect, 
375                 DT_SINGLELINE | DT_NOCLIP | DT_LEFT, D3DCOLOR_RGBA(255,200,0,255));
376             formatRect.top += 25;
377             g_pTextHelper->DrawText(NULL, L"    滑动鼠标滚轮:拉伸模型", -1, &formatRect, 
378                 DT_SINGLELINE | DT_NOCLIP | DT_LEFT, D3DCOLOR_RGBA(255,200,0,255));
379             formatRect.top += 25;
380             g_pTextHelper->DrawText(NULL, L"    W、S、A、D键:平移模型 ", -1, &formatRect, 
381                 DT_SINGLELINE | DT_NOCLIP | DT_LEFT, D3DCOLOR_RGBA(255,200,0,255));
382             formatRect.top += 25;
383             g_pTextHelper->DrawText(NULL, L"    上、下、左、右方向键:旋转模型 ", -1, &formatRect, 
384                 DT_SINGLELINE | DT_NOCLIP | DT_LEFT, D3DCOLOR_RGBA(255,200,0,255));
385             formatRect.top += 25;
386             g_pTextHelper->DrawText(NULL, L"    ESC键 : 退出程序", -1, &formatRect, 
387                 DT_SINGLELINE | DT_NOCLIP | DT_LEFT, D3DCOLOR_RGBA(255,200,0,255));
388     //4
389     g_pd3dDevice->EndScene(); 
390     //5
391     g_pd3dDevice->Present(NULL, NULL, NULL, NULL); 
392 }
393 
394 
395 //-----------------------------------【Direct3D_Update( )函数】--------------------------------
396 void    Direct3D_Update( HWND hwnd)
397 {
398 
399 
400 
401 }
402 
403 
404 //-----------------------------------【Get_FPS( )函数】------------------------------------------
405 float    Get_FPS()
406 {
407     static float  fps = 0;//fps值
408     static int     frameCount = 0;//帧数
409     static float  currentTime =0.0f;//当前时间
410     static float  lastTime = 0.0f;//持续时间
411 
412     frameCount++;
413     currentTime=timeGetTime()*0.001f;//获取系统时间
414 
415     if(currentTime-lastTime>1.0f)
416     {
417         fps = (float)frameCount /(currentTime - lastTime);
418         lastTime=currentTime;
419         frameCount=0;
420 
421     }
422     return fps;
423 
424 }
425 //-----------------------------------【Direct3D_CleanUp( )函数】--------------------------------
426 void Direct3D_CleanUp()
427 {
428     //释放COM接口对象
429     //g_pMouseDevice->Unacquire();
430     //g_pKeyboardDevice->Unacquire();
431     for (DWORD i = 0; i<g_dwNumMtrls; i++) 
432         SAFE_RELEASE(g_pTextures[i]);
433     SAFE_DELETE(g_pTextures)
434     SAFE_DELETE(g_pMaterials)
435     SAFE_RELEASE(g_pMesh)
436     SAFE_RELEASE(g_pTextFPS)
437     SAFE_RELEASE(g_pd3dDevice)    
438     SAFE_RELEASE(g_pMouseDevice)
439     SAFE_RELEASE(g_pKeyboardDevice)
440 }
View Code
复制代码

第11章:3.添加键盘鼠标对象,控制世界坐标变换

复制代码
  1 //第2步,宏定义部分移动到最前面
  2 //-----------------------------------【宏定义部分】--------------------------------------------
  3 #define WINDOW_WIDTH    800
  4 #define WINDOW_HEIGHT    600
  5 #define WINDOW_TITLE    L"安康学院数字媒体技术"
  6 #define DIRECTINPUT_VERSION 0x0800 
  7 #define SAFE_RELEASE(p) { if(p) { (p)->Release(); (p)=NULL; } }//释放的是COM资源
  8 #define SAFE_DELETE(p)  { if(p) { delete (p); (p)=NULL; } }    //释放的是指针
  9 
 10 //-----------------------------------【头文件包含部分】---------------------------------------
 11 #include<d3d9.h>
 12 #include <d3dx9.h>
 13 #include <tchar.h>
 14 #include <time.h>
 15 #include <dinput.h>
 16 
 17 
 18 //-----------------------------------【库文件包含部分】---------------------------------------
 19 #pragma comment(lib,"winmm.lib") 
 20 #pragma comment(lib,"d3d9.lib")
 21 #pragma comment(lib,"d3dx9.lib")
 22 #pragma comment(lib, "dinput8.lib") 
 23 #pragma comment(lib,"dxguid.lib")
 24 
 25 /*
 26 //-----------------------------------【宏定义部分】--------------------------------------------
 27 #define WINDOW_WIDTH    800
 28 #define WINDOW_HEIGHT    600
 29 #define WINDOW_TITLE    L"安康学院数字媒体技术"
 30 //第1步,因为老出现这个报错。所有加这一句,同时要把宏定义部分移动到最前面,在#include <dinput.h>的前面以免重复定义。
 31 /*c:\program files (x86)\microsoft directx sdk (june 2010)\include\dinput.h: DIRECTINPUT_VERSION undefined. Defaulting to version 0x0800
 32 1>c:\users\zhj\desktop\123\dx111\demo\demo\main.cpp(21): warning C4005: “°DIRECTINPUT_VERSION”±: 宏重定义
 33 */
 34 /*
 35 #define DIRECTINPUT_VERSION 0x0800 
 36 #define SAFE_RELEASE(p) { if(p) { (p)->Release(); (p)=NULL; } }//释放的是COM资源
 37 #define SAFE_DELETE(p)  { if(p) { delete (p); (p)=NULL; } }    //释放的是指针
 38 
 39 */
 40 
 41 //-----------------------------------【全局变量声明部分】-------------------------------------
 42 LPDIRECT3DDEVICE9       g_pd3dDevice            = NULL; 
 43 LPD3DXFONT                g_pTextFPS                =NULL;
 44 LPD3DXFONT                g_pTextAdaperName       = NULL;
 45 LPD3DXFONT                g_pTextHelper           = NULL; 
 46 LPD3DXFONT                g_pTextInfor            = NULL;
 47 float                   g_FPS=0.0f;
 48 wchar_t                    g_strFPS[50]={0}; 
 49 wchar_t                    g_strAdapterName[60]={0};
 50 LPDIRECTINPUT8            g_pDirectInput      = NULL;
 51 LPDIRECTINPUTDEVICE8    g_pMouseDevice      = NULL;
 52 DIMOUSESTATE            g_diMouseState      = {0};
 53 LPDIRECTINPUTDEVICE8    g_pKeyboardDevice   = NULL;
 54 char                    g_pKeyStateBuffer[256] = {0};
 55 D3DXMATRIX                g_matWorld;
 56 LPD3DXMESH                g_pMesh     = NULL; 
 57 D3DMATERIAL9*            g_pMaterials    = NULL; 
 58 LPDIRECT3DTEXTURE9*        g_pTextures     = NULL;
 59 DWORD                    g_dwNumMtrls    = 0; 
 60 
 61 //-----------------------------------【全局函数声明部分】-------------------------------------
 62 LRESULT CALLBACK    WndProc( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam );
 63 //第1步 添加对象句柄
 64 HRESULT                    Direct3D_Init(HWND hwnd,HINSTANCE hInstance);
 65 HRESULT                    Objects_Init(HWND hwnd);
 66 void                    Direct3D_Render(HWND hwnd);
 67 void                    Direct3D_Update(HWND hwnd);
 68 void                    Direct3D_CleanUp( );
 69 float                    Get_FPS();
 70 void                    Matrix_Set();
 71 //第2步 添加设备读取函数
 72 BOOL                    Device_Read(IDirectInputDevice8 *pDIDevice, void* pBuffer, long lSize) ;
 73 
 74 //-----------------------------------【WinMain( )函数】--------------------------------------
 75 //    描述:Windows应用程序的入口函数,我们的程序从这里开始
 76 int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nShowCmd)
 77 {
 78     //【1】开始设计一个完整的窗口类
 79     WNDCLASSEX wndClass = { 0 };
 80     wndClass.cbSize = sizeof( WNDCLASSEX ) ;
 81     wndClass.style = CS_HREDRAW | CS_VREDRAW;
 82     wndClass.lpfnWndProc = WndProc;
 83     wndClass.cbClsExtra        = 0;
 84     wndClass.cbWndExtra        = 0;
 85     wndClass.hInstance = hInstance;    
 86     wndClass.hIcon=(HICON)::LoadImage(NULL,L"icon.ico",IMAGE_ICON,0,0,LR_DEFAULTSIZE|LR_LOADFROMFILE);
 87     wndClass.hCursor = LoadCursor( NULL, IDC_ARROW );
 88     wndClass.hbrBackground=(HBRUSH)GetStockObject(GRAY_BRUSH);
 89     wndClass.lpszMenuName = NULL;
 90     wndClass.lpszClassName = L"ForTheDreamOfGameDevelop";
 91 
 92     //【2】注册窗口类
 93     if( !RegisterClassEx( &wndClass ) )    
 94         return -1;
 95 
 96     //【3】正式创建窗口
 97     HWND hwnd = CreateWindow( L"ForTheDreamOfGameDevelop",WINDOW_TITLE,    
 98         WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, WINDOW_WIDTH,
 99         WINDOW_HEIGHT, NULL, NULL, hInstance, NULL );
100 //第3步 对应修改参数
101     if (S_OK==Direct3D_Init(hwnd,hInstance))
102         {
103         MessageBox(hwnd, L"Direct3D初始化完成~!", L"消息窗口", 0);
104         }
105     else
106         {
107         MessageBox(hwnd, L"Direct3D初始化失败~!", L"消息窗口", 0);
108         }
109     //Direct3D资源的初始化,调用失败用messagebox予以显示
110     if (!(S_OK==Direct3D_Init (hwnd,hInstance)))
111     {
112         MessageBox(hwnd, _T("Direct3D初始化失败~!"), _T("消息窗口"), 0); //使用MessageBox函数,创建一个消息窗口 
113     }
114 
115 
116     //【4】窗口的移动、显示与更新
117     MoveWindow(hwnd,250,80,WINDOW_WIDTH,WINDOW_HEIGHT,true);
118     ShowWindow(hwnd, nShowCmd );
119     UpdateWindow(hwnd);
120 
121     PlaySound(L"刻限.wav", NULL, SND_FILENAME | SND_ASYNC|SND_LOOP); 
122 
123     //【5】消息循环过程
124     MSG msg = { 0 };
125     while( msg.message != WM_QUIT )
126         {
127         if( PeekMessage( &msg, 0, 0, 0, PM_REMOVE ) )   //查看应用程序消息队列,有消息时将队列中的消息派发出去。
128         {
129             TranslateMessage( &msg );        //将虚拟键消息转换为字符消息
130             DispatchMessage( &msg );        //该函数分发一个消息给窗口程序。
131         }
132         else
133         {
134 //第6步 添加调用更新函数,进行画面的更新
135             Direct3D_Update(hwnd);            //调用更新函数,进行画面的更新
136             Direct3D_Render(hwnd);   //进行渲染
137         }
138     }
139 
140     //【6】窗口类的注销
141     UnregisterClass(L"ForTheDreamOfGameDevelop", wndClass.hInstance); 
142         return 0;  
143 }
144 
145 //-----------------------------------【WndProc( )函数】--------------------------------------
146 LRESULT CALLBACK WndProc( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam )      
147 {
148     switch( message )
149     {
150         case WM_PAINT:
151             Direct3D_Render(hwnd);
152             ValidateRect(hwnd, NULL);
153             break;
154 
155         case WM_KEYDOWN:
156             if (wParam == VK_ESCAPE)
157                 DestroyWindow(hwnd);
158             break;
159 
160         case WM_DESTROY:
161             Direct3D_CleanUp();
162             PostQuitMessage( 0 );
163             break;    
164 
165         default:
166             return DefWindowProc( hwnd, message, wParam, lParam );
167     }
168     return 0;
169 }
170 
171 //-----------------------------------【Direct3D_Init( )函数】--------------------------------------
172 //第4步:对应修改Direct3D_Init参数
173 HRESULT    Direct3D_Init(HWND hwnd,HINSTANCE hInstance)
174 {
175     //Direct3D初始化,第一步
176     LPDIRECT3D9 pD3D=NULL;
177     if(NULL==(pD3D=Direct3DCreate9(D3D_SDK_VERSION)))
178         return E_FAIL;
179 
180     //Direct3D初始化,第二步
181     D3DCAPS9 caps; int vp = 0;
182     if( FAILED( pD3D->GetDeviceCaps( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, &caps ) ) )
183     {
184         return E_FAIL;
185     }
186     if( caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT )
187 
188         vp = D3DCREATE_HARDWARE_VERTEXPROCESSING; 
189     else
190         vp = D3DCREATE_SOFTWARE_VERTEXPROCESSING;
191 
192 
193     //Direct3D初始化,第三步,D3DPRESENT_PARAMETERS结构体
194 
195     D3DPRESENT_PARAMETERS d3dpp; 
196     ZeroMemory(&d3dpp, sizeof(d3dpp));
197     d3dpp.BackBufferWidth            = WINDOW_WIDTH;
198     d3dpp.BackBufferHeight           = WINDOW_HEIGHT;
199     d3dpp.BackBufferFormat           = D3DFMT_A8R8G8B8;
200 //第7步 对应一个参数
201     d3dpp.BackBufferCount            = 2;
202     d3dpp.MultiSampleType            = D3DMULTISAMPLE_NONE;
203     d3dpp.MultiSampleQuality         = 0;
204     d3dpp.SwapEffect                 = D3DSWAPEFFECT_DISCARD; 
205     d3dpp.hDeviceWindow              = hwnd;
206     d3dpp.Windowed                   = true;
207     d3dpp.EnableAutoDepthStencil     = true; 
208     d3dpp.AutoDepthStencilFormat     = D3DFMT_D24S8;
209     d3dpp.Flags                      = 0;
210     d3dpp.FullScreen_RefreshRateInHz = 0;
211     d3dpp.PresentationInterval       = D3DPRESENT_INTERVAL_IMMEDIATE;
212 
213     //Direct3D初始化,第四步
214 
215     if(FAILED(pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, 
216         hwnd, vp, &d3dpp, &g_pd3dDevice)))
217         return E_FAIL;
218 
219     wchar_t TempName[60]=L"当前显卡型号:";
220     D3DADAPTER_IDENTIFIER9 Adapter;
221     pD3D->GetAdapterIdentifier(0,0,&Adapter);
222     int len = MultiByteToWideChar(CP_ACP,0, Adapter.Description, -1, NULL, 0);
223     MultiByteToWideChar(CP_ACP, 0, Adapter.Description, -1, g_strAdapterName, len);
224     wcscat_s(TempName,g_strAdapterName);
225     wcscpy_s(g_strAdapterName,TempName);
226 //第8步 创建DirectInput
227 
228     // 1.创建DirectInput接口和设备
229     DirectInput8Create(hInstance, 0x0800, IID_IDirectInput8, (void**)&g_pDirectInput, NULL);
230     
231     //2.数据格式
232     g_pDirectInput->CreateDevice(GUID_SysMouse, &g_pMouseDevice, NULL);
233     g_pMouseDevice->SetDataFormat(&c_dfDIMouse);
234     g_pMouseDevice->SetCooperativeLevel(hwnd, DISCL_FOREGROUND | DISCL_NONEXCLUSIVE);
235 
236     //3.获取设备控制权
237     g_pMouseDevice->Acquire();
238 
239     DirectInput8Create(hInstance, 0x0800, IID_IDirectInput8, (void**)&g_pDirectInput, NULL);
240     g_pDirectInput->CreateDevice(GUID_SysKeyboard, &g_pKeyboardDevice, NULL);
241 
242     g_pKeyboardDevice->SetDataFormat(&c_dfDIKeyboard);
243     g_pKeyboardDevice->SetCooperativeLevel(hwnd, DISCL_FOREGROUND | DISCL_NONEXCLUSIVE);
244 
245     g_pKeyboardDevice->Acquire();
246 
247     
248 //第9步 对应修改参数
249 
250     if(!(S_OK==Objects_Init(hwnd))) return E_FAIL;
251     SAFE_RELEASE(pD3D); 
252     return S_OK;
253 
254 }
255 
256 
257 //-----------------------------------【Object_Init( )函数】--------------------------------------
258 //第5步:对应修改Objects_Init参数
259 HRESULT Objects_Init(HWND hwnd)
260 {
261         D3DXCreateFont(g_pd3dDevice, 36, 0, 0, 1000, false, DEFAULT_CHARSET, 
262         OUT_DEFAULT_PRECIS, DEFAULT_QUALITY, 0, _T("Calibri"), &g_pTextFPS);
263 
264         D3DXCreateFont(g_pd3dDevice, 20, 0, 1000, 0, false, DEFAULT_CHARSET, 
265         OUT_DEFAULT_PRECIS, DEFAULT_QUALITY, 0, L"华文中宋", &g_pTextAdaperName); 
266 
267         D3DXCreateFont(g_pd3dDevice, 23, 0, 1000, 0, false, DEFAULT_CHARSET, 
268         OUT_DEFAULT_PRECIS, DEFAULT_QUALITY, 0, L"微软雅黑", &g_pTextHelper); 
269     
270         D3DXCreateFont(g_pd3dDevice, 26, 0, 1000, 0, false, DEFAULT_CHARSET, 
271         OUT_DEFAULT_PRECIS, DEFAULT_QUALITY, 0, L"黑体", &g_pTextInfor); 
272 
273 
274     // 从X文件中加载网格数据
275     LPD3DXBUFFER pAdjBuffer  = NULL;
276     LPD3DXBUFFER pMtrlBuffer = NULL;
277     D3DXLoadMeshFromX(L"loli.x", D3DXMESH_MANAGED, g_pd3dDevice, 
278         &pAdjBuffer, &pMtrlBuffer, NULL, &g_dwNumMtrls, &g_pMesh);
279     // 读取材质和纹理数据
280     D3DXMATERIAL *pMtrls = (D3DXMATERIAL*)pMtrlBuffer->GetBufferPointer();//创建一个D3DXMATERIAL结构体用于读取材质和纹理信息
281     g_pMaterials = new D3DMATERIAL9[g_dwNumMtrls];
282     g_pTextures  = new LPDIRECT3DTEXTURE9[g_dwNumMtrls];
283 
284     for (DWORD i=0; i<g_dwNumMtrls; i++) 
285     {
286         //获取材质,并设置一下环境光的颜色值
287         g_pMaterials[i] = pMtrls[i].MatD3D;
288         g_pMaterials[i].Ambient = g_pMaterials[i].Diffuse;
289         //创建一下纹理对象
290         g_pTextures[i]  = NULL;
291         D3DXCreateTextureFromFileA(g_pd3dDevice, pMtrls[i].pTextureFilename, &g_pTextures[i]);
292     }
293     pAdjBuffer->Release();
294     pMtrlBuffer->Release();
295 
296 
297 
298     // 设置渲染状态
299     g_pd3dDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW);   //开启背面消隐
300     g_pd3dDevice->SetRenderState(D3DRS_AMBIENT, D3DXCOLOR(1.0f, 1.0f, 1.0f, 1.0f)); //设置环境光
301     //第10步,移入update函数中
302     //Matrix_Set();//调用封装了四大变换的函数,对Direct3D世界变换,取景变换,投影变换,视口变换进行设置
303 
304     return S_OK;
305 }
306 //-----------------------------------【Matrix_Set( )函数】--------------------------------------
307 void Matrix_Set()
308 {
309 //第11步 世界变换矩阵的设置,改动到鼠标键盘操作后对世界变换矩阵修改
310 
311     //--------------------------------------------------------------------------------------
312     //【四大变换之一】:世界变换矩阵的设置
313     //--------------------------------------------------------------------------------------
314 /*
315     D3DXMATRIX matWorld, Rx, Ry, Rz;
316     D3DXMatrixIdentity(&matWorld);                  // 单位化世界矩阵
317     D3DXMatrixRotationX(&Rx, D3DX_PI *(::timeGetTime() / 1000.0f));    // 绕X轴旋转
318     D3DXMatrixRotationY(&Ry, D3DX_PI *( ::timeGetTime() / 1000.0f/2));    // 绕Y轴旋转
319     D3DXMatrixRotationZ(&Rz, D3DX_PI *( ::timeGetTime() / 1000.0f/3));   // 绕Z轴旋转
320     matWorld = Rx * Ry * Rz * matWorld;             // 得到最终的组合矩阵
321     g_pd3dDevice->SetTransform(D3DTS_WORLD, &matWorld);  //设置世界变换矩阵
322 */
323     //--------------------------------------------------------------------------------------
324     //【四大变换之二】:取景变换矩阵的设置
325     //--------------------------------------------------------------------------------------
326     D3DXMATRIX matView; //定义一个矩阵
327     D3DXVECTOR3 vEye(0.0f, 0.0f, -250.0f);  //摄像机的位置
328     D3DXVECTOR3 vAt(0.0f, 0.0f, 0.0f); //观察点的位置
329     D3DXVECTOR3 vUp(0.0f, 1.0f, 0.0f);//向上的向量
330     D3DXMatrixLookAtLH(&matView, &vEye, &vAt, &vUp); //计算出取景变换矩阵
331     g_pd3dDevice->SetTransform(D3DTS_VIEW, &matView); //应用取景变换矩阵
332 
333     //--------------------------------------------------------------------------------------
334     //【四大变换之三】:投影变换矩阵的设置
335     //--------------------------------------------------------------------------------------
336     D3DXMATRIX matProj; //定义一个矩阵
337     D3DXMatrixPerspectiveFovLH(&matProj, D3DX_PI / 4.0f,(float)((double)WINDOW_WIDTH/WINDOW_HEIGHT),1.0f, 1000.0f); //计算投影变换矩阵
338     g_pd3dDevice->SetTransform(D3DTS_PROJECTION, &matProj);  //设置投影变换矩阵
339 
340     //--------------------------------------------------------------------------------------
341     //【四大变换之四】:视口变换的设置
342     //--------------------------------------------------------------------------------------
343     D3DVIEWPORT9 vp; //实例化一个D3DVIEWPORT9结构体,然后做填空题给各个参数赋值就可以了
344     vp.X      = 0;        //表示视口相对于窗口的X坐标
345     vp.Y      = 0;        //视口相对对窗口的Y坐标
346     vp.Width  = WINDOW_WIDTH;    //视口的宽度
347     vp.Height = WINDOW_HEIGHT; //视口的高度
348     vp.MinZ   = 0.0f; //视口在深度缓存中的最小深度值
349     vp.MaxZ   = 1.0f;    //视口在深度缓存中的最大深度值
350     g_pd3dDevice->SetViewport(&vp); //视口的设置
351 }
352 //第12步 Direct3D_Update( )函数
353 //-----------------------------------【Direct3D_Update( )函数】--------------------------------
354 //    描述:不是即时渲染代码但是需要即时调用的,如按键后的坐标的更改,都放在这里
355 //--------------------------------------------------------------------------------------------------
356 void    Direct3D_Update( HWND hwnd)
357 {
358     // 获取键盘消息并给予设置相应的填充模式  
359     if (g_pKeyStateBuffer[DIK_1]    & 0x80)         // 若数字键1被按下,进行实体填充  
360         g_pd3dDevice->SetRenderState(D3DRS_FILLMODE,D3DFILL_SOLID);
361     if (g_pKeyStateBuffer[DIK_2]    & 0x80)         // 若数字键2被按下,进行线框填充  
362         g_pd3dDevice->SetRenderState(D3DRS_FILLMODE,D3DFILL_WIREFRAME);  
363 
364     // 读取鼠标输入
365     ::ZeroMemory(&g_diMouseState, sizeof(g_diMouseState));
366     Device_Read(g_pMouseDevice, (LPVOID)&g_diMouseState, sizeof(g_diMouseState));
367 
368     // 读取键盘输入
369     ::ZeroMemory(g_pKeyStateBuffer, sizeof(g_pKeyStateBuffer));
370     Device_Read(g_pKeyboardDevice, (LPVOID)g_pKeyStateBuffer, sizeof(g_pKeyStateBuffer));
371 
372 
373     // 按住鼠标左键并拖动,为平移操作
374     static FLOAT fPosX = 0.0f, fPosY = 30.0f, fPosZ = 0.0f;
375     if (g_diMouseState.rgbButtons[0] & 0x80) 
376     {
377         fPosX += g_diMouseState.lX *  0.08f;
378         fPosY += g_diMouseState.lY * -0.08f;
379     }
380 
381     //鼠标滚轮,为观察点收缩操作
382     fPosZ += g_diMouseState.lZ * 0.02f;
383 
384     // 平移物体
385     if (g_pKeyStateBuffer[DIK_A] & 0x80) fPosX -= 0.005f;
386     if (g_pKeyStateBuffer[DIK_D] & 0x80) fPosX += 0.005f;
387     if (g_pKeyStateBuffer[DIK_W] & 0x80) fPosY += 0.005f;
388     if (g_pKeyStateBuffer[DIK_S] & 0x80) fPosY -= 0.005f;
389 
390 
391     D3DXMatrixTranslation(&g_matWorld, fPosX, fPosY, fPosZ);
392 
393 
394     // 按住鼠标右键并拖动,为旋转操作
395     static float fAngleX = 0.15f, fAngleY = -(float)D3DX_PI ;
396     if (g_diMouseState.rgbButtons[1] & 0x80) 
397     {
398         fAngleX += g_diMouseState.lY * -0.01f;
399         fAngleY += g_diMouseState.lX * -0.01f;
400     }
401     // 旋转物体
402     if (g_pKeyStateBuffer[DIK_UP]    & 0x80) fAngleX += 0.005f;
403     if (g_pKeyStateBuffer[DIK_DOWN]  & 0x80) fAngleX -= 0.005f;
404     if (g_pKeyStateBuffer[DIK_LEFT]  & 0x80) fAngleY -= 0.005f;
405     if (g_pKeyStateBuffer[DIK_RIGHT] & 0x80) fAngleY += 0.005f;
406 
407 
408     D3DXMATRIX Rx, Ry;
409     D3DXMatrixRotationX(&Rx, fAngleX);
410     D3DXMatrixRotationY(&Ry, fAngleY);
411 
412     //得到最终的矩阵并设置
413     g_matWorld = Rx * Ry * g_matWorld;//得到最终的矩阵
414     g_pd3dDevice->SetTransform(D3DTS_WORLD, &g_matWorld);//设置世界矩阵
415     Matrix_Set();
416 }
417 
418 //-----------------------------------【Direct3D_Render( )函数】--------------------------------------
419 void Direct3D_Render(HWND hwnd)
420 {//1
421 //第5步,清除buffer
422     g_pd3dDevice->Clear(0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(150, 150, 100), 1.0f, 0);
423     RECT formatRect;
424     GetClientRect(hwnd, &formatRect);
425     //2
426     g_pd3dDevice->BeginScene();   
427     //3
428 
429     for (DWORD i = 0; i < g_dwNumMtrls; i++)
430             {
431                 g_pd3dDevice->SetMaterial(&g_pMaterials[i]);
432                 g_pd3dDevice->SetTexture(0, g_pTextures[i]);
433                 g_pMesh->DrawSubset(i);
434             }
435 
436             int charCount = swprintf_s(g_strFPS, 20, _T("FPS:%0.3f"), Get_FPS() );
437             g_pTextFPS->DrawText(NULL, g_strFPS, charCount , &formatRect, DT_TOP | DT_RIGHT, D3DCOLOR_RGBA(0,239,136,255));
438     
439             g_pTextAdaperName->DrawText(NULL,g_strAdapterName, -1, &formatRect, 
440                 DT_TOP | DT_LEFT, D3DXCOLOR(1.0f, 0.5f, 0.0f, 1.0f));
441 
442             formatRect.top = 30;
443             static wchar_t strInfo[256] = {0};
444             swprintf_s(strInfo,-1, L"模型坐标: (%.2f, %.2f, %.2f)", g_matWorld._41, g_matWorld._42, g_matWorld._43);
445             g_pTextHelper->DrawText(NULL, strInfo, -1, &formatRect, DT_SINGLELINE | DT_NOCLIP | DT_LEFT, D3DCOLOR_RGBA(135,239,136,255));
446 
447 
448 
449             formatRect.left = 0,formatRect.top = 380;
450             g_pTextInfor->DrawText(NULL, L"控制说明:", -1, &formatRect, 
451                 DT_SINGLELINE | DT_NOCLIP | DT_LEFT, D3DCOLOR_RGBA(235,123,230,255));
452             formatRect.top += 35;
453             g_pTextHelper->DrawText(NULL, L"    按住鼠标左键并拖动:平移模型", -1, &formatRect, 
454                 DT_SINGLELINE | DT_NOCLIP | DT_LEFT, D3DCOLOR_RGBA(255,200,0,255));
455             formatRect.top += 25;
456             g_pTextHelper->DrawText(NULL, L"    按住鼠标右键并拖动:旋转模型", -1, &formatRect, 
457                 DT_SINGLELINE | DT_NOCLIP | DT_LEFT, D3DCOLOR_RGBA(255,200,0,255));
458             formatRect.top += 25;
459             g_pTextHelper->DrawText(NULL, L"    滑动鼠标滚轮:拉伸模型", -1, &formatRect, 
460                 DT_SINGLELINE | DT_NOCLIP | DT_LEFT, D3DCOLOR_RGBA(255,200,0,255));
461             formatRect.top += 25;
462             g_pTextHelper->DrawText(NULL, L"    W、S、A、D键:平移模型 ", -1, &formatRect, 
463                 DT_SINGLELINE | DT_NOCLIP | DT_LEFT, D3DCOLOR_RGBA(255,200,0,255));
464             formatRect.top += 25;
465             g_pTextHelper->DrawText(NULL, L"    上、下、左、右方向键:旋转模型 ", -1, &formatRect, 
466                 DT_SINGLELINE | DT_NOCLIP | DT_LEFT, D3DCOLOR_RGBA(255,200,0,255));
467             formatRect.top += 25;
468             g_pTextHelper->DrawText(NULL, L"    ESC键 : 退出程序", -1, &formatRect, 
469                 DT_SINGLELINE | DT_NOCLIP | DT_LEFT, D3DCOLOR_RGBA(255,200,0,255));
470     //4
471     g_pd3dDevice->EndScene(); 
472     //5
473     g_pd3dDevice->Present(NULL, NULL, NULL, NULL); 
474 }
475 
476 
477 
478 
479 //-----------------------------------【Get_FPS( )函数】------------------------------------------
480 float    Get_FPS()
481 {
482     static float  fps = 0;//fps值
483     static int     frameCount = 0;//帧数
484     static float  currentTime =0.0f;//当前时间
485     static float  lastTime = 0.0f;//持续时间
486 
487     frameCount++;
488     currentTime=timeGetTime()*0.001f;//获取系统时间
489 
490     if(currentTime-lastTime>1.0f)
491     {
492         fps = (float)frameCount /(currentTime - lastTime);
493         lastTime=currentTime;
494         frameCount=0;
495 
496     }
497     return fps;
498 
499 }
500 //第13步Device_Read( )函数
501 //-----------------------------------【Device_Read( )函数】------------------------------------
502 // Desc: 智能读取设备的输入数据
503 //--------------------------------------------------------------------------------------------------
504 BOOL Device_Read(IDirectInputDevice8 *pDIDevice, void* pBuffer, long lSize) 
505 {
506     HRESULT hr;
507     while (true) 
508     {
509         pDIDevice->Poll();              // 轮询设备
510         pDIDevice->Acquire();           // 获取设备的控制权
511         if (SUCCEEDED(hr = pDIDevice->GetDeviceState(lSize, pBuffer))) break;
512         if (hr != DIERR_INPUTLOST || hr != DIERR_NOTACQUIRED) return FALSE;
513         if (FAILED(pDIDevice->Acquire())) return FALSE;
514     }
515     return TRUE;
516 }
517 
518 //-----------------------------------【Direct3D_CleanUp( )函数】--------------------------------
519 void Direct3D_CleanUp()
520 {
521     //释放COM接口对象
522 //第14步 取消注释
523 
524     //g_pMouseDevice->Unacquire();
525     //g_pKeyboardDevice->Unacquire();
526     for (DWORD i = 0; i<g_dwNumMtrls; i++) 
527         SAFE_RELEASE(g_pTextures[i]);
528     SAFE_DELETE(g_pTextures)
529     SAFE_DELETE(g_pMaterials)
530     SAFE_RELEASE(g_pMesh)
531     SAFE_RELEASE(g_pTextFPS)
532     SAFE_RELEASE(g_pd3dDevice)    
533     SAFE_RELEASE(g_pMouseDevice)
534     SAFE_RELEASE(g_pKeyboardDevice)
535 }
View Code
复制代码

第11章:4.对DirectInput的封装

//D3DUtil.h

复制代码
 1 //=============================================================================
 2 // Desc: D3DUtil.h头文件,用于公共辅助宏的定义
 3 //=============================================================================
 4 
 5 #pragma once
 6 
 7 
 8 #ifndef HR
 9 #define HR(x)    { hr = x; if( FAILED(hr) ) { return hr; } }         //自定义一个HR宏,方便执行错误的返回
10 #endif
11 
12 #ifndef SAFE_DELETE                    
13 #define SAFE_DELETE(p)       { if(p) { delete (p);     (p)=NULL; } }       //自定义一个SAFE_RELEASE()宏,便于指针资源的释放
14 #endif    
15 
16 #ifndef SAFE_RELEASE            
17 #define SAFE_RELEASE(p)      { if(p) { (p)->Release(); (p)=NULL; } }     //自定义一个SAFE_RELEASE()宏,便于COM资源的释放
18 #endif
View Code
复制代码

//DirectInputClass.h

 

复制代码
 1 //=============================================================================
 2 // Name: DirectInputClass.h
 3 //    Des: 封装了DirectInput键盘输入处理类的头文件
 4 //=============================================================================
 5 #pragma once
 6 #include "D3DUtil.h"
 7 #define DIRECTINPUT_VERSION 0x0800
 8 #include <dinput.h>
 9 
10 //DInputClass类定义开始
11 class DInputClass
12 {
13 private:
14     IDirectInput8                    * m_pDirectInput;   //IDirectInput8接口对象
15     IDirectInputDevice8        * m_KeyboardDevice;  //键盘设备接口对象
16     char                                m_keyBuffer[256];       //用于键盘键值存储的数组
17 
18     IDirectInputDevice8        *m_MouseDevice;      //鼠标设备接口对象
19     DIMOUSESTATE                m_MouseState;            //用于鼠标键值存储的一个结构体
20 
21 public:
22     HRESULT        Init( HWND hWnd,HINSTANCE hInstance,DWORD keyboardCoopFlags, DWORD mouseCoopFlags ); //初始化DirectInput键盘及鼠标输入设备
23     void                GetInput();   //用于获取输入信息的函数
24     bool                IsKeyDown(int iKey);   //判断键盘上某键是否按下
25     
26     bool                IsMouseButtonDown(int button);  //判断鼠标按键是否被按下
27     float                MouseDX();   //返回鼠标的X轴坐标值
28     float                MouseDY();    //返回鼠标的Y轴坐标值
29     float                MouseDZ();    //返回鼠标的Z轴坐标值
30 
31 
32 public:
33     DInputClass(void);        //构造函数
34     ~DInputClass(void);    //析构函数
35 };
View Code
复制代码

 

//DirectInputClass.cpp

复制代码
  1 //=============================================================================
  2 // Desc: DirectInput键盘输入处理类源文件
  3 //=============================================================================
  4 #include "DirectlnputClass.h"
  5 
  6 
  7 //-----------------------------------------------------------------------------
  8 // Desc: 构造函数
  9 //-----------------------------------------------------------------------------
 10 DInputClass::DInputClass()
 11 {
 12     m_pDirectInput = NULL;
 13     m_KeyboardDevice = NULL;
 14     ZeroMemory(m_keyBuffer,sizeof(char)*256);
 15     m_MouseDevice= NULL;
 16     ZeroMemory(&m_MouseState, sizeof(m_MouseState));
 17 }
 18 
 19 
 20 //-----------------------------------------------------------------------------
 21 // Name:DInputClass::Init()
 22 // Desc: 初始化DirectInput键盘及鼠标输入设备
 23 //-----------------------------------------------------------------------------
 24 HRESULT DInputClass::Init( HWND hWnd,HINSTANCE hInstance,DWORD keyboardCoopFlags, DWORD mouseCoopFlags )
 25 {
 26     HRESULT hr;
 27     //初始化一个IDirectInput8接口对象
 28     HR(DirectInput8Create( hInstance, DIRECTINPUT_VERSION, 
 29         IID_IDirectInput8,(void**)&m_pDirectInput,NULL ));
 30 
 31     //进行键盘设备的初始化
 32     HR( m_pDirectInput->CreateDevice( GUID_SysKeyboard, &m_KeyboardDevice, NULL ));
 33     HR( m_KeyboardDevice->SetCooperativeLevel( hWnd, keyboardCoopFlags));
 34     HR( m_KeyboardDevice->SetDataFormat( &c_dfDIKeyboard ));
 35     HR( m_KeyboardDevice->Acquire( ));
 36     HR( m_KeyboardDevice->Poll( ));
 37 
 38     //进行鼠标设备的初始化
 39     HR( m_pDirectInput->CreateDevice( GUID_SysMouse, &m_MouseDevice, NULL ));
 40     HR( m_MouseDevice->SetCooperativeLevel( hWnd,mouseCoopFlags));
 41     HR( m_MouseDevice->SetDataFormat( &c_dfDIMouse ));
 42     HR( m_MouseDevice->Acquire( ));
 43     HR( m_KeyboardDevice->Poll( ));
 44 
 45     return S_OK;
 46 }
 47 
 48 
 49 //-----------------------------------------------------------------------------
 50 // Name:DInputClass::GetInput()
 51 // Desc: 用于获取输入信息的函数
 52 //-----------------------------------------------------------------------------
 53 void DInputClass::GetInput()
 54 {
 55     HRESULT hr = m_KeyboardDevice->GetDeviceState(sizeof(m_keyBuffer), (void**)&m_keyBuffer); 
 56     //获取键盘输入消息
 57     if(hr)
 58     {
 59         m_KeyboardDevice->Acquire();  
 60         m_KeyboardDevice->GetDeviceState( sizeof(m_keyBuffer),(LPVOID)m_keyBuffer );
 61     }
 62 
 63     hr = m_MouseDevice->GetDeviceState(sizeof(DIMOUSESTATE), (void**)&m_MouseState); 
 64     //获取鼠标输入消息
 65     if(hr)
 66     {
 67         m_MouseDevice->Acquire();
 68         m_MouseDevice->GetDeviceState( sizeof(DIMOUSESTATE), (void**)&m_MouseState);
 69     }
 70 }
 71 
 72 //-----------------------------------------------------------------------------
 73 // Name:DInputClass::IsKeyDown()
 74 // Desc: 判断键盘上某个键是否按下
 75 //-----------------------------------------------------------------------------
 76 bool DInputClass::IsKeyDown(int iKey)
 77 {
 78     if(m_keyBuffer[iKey] & 0x80)
 79         return true;
 80     else
 81         return false;
 82 }
 83 
 84 
 85 //-----------------------------------------------------------------------------
 86 // Name:DInputClass::IsMouseButtonDown()
 87 // Desc: 判断鼠标上某键是否按下
 88 //-----------------------------------------------------------------------------
 89 bool DInputClass::IsMouseButtonDown(int button)
 90 {
 91     return (m_MouseState.rgbButtons[button] & 0x80) != 0;
 92 }
 93 
 94 //-----------------------------------------------------------------------------
 95 // Name:DInputClass::MouseDX
 96 // Desc: 返回鼠标指针的X轴坐标值
 97 //-----------------------------------------------------------------------------
 98 float DInputClass::MouseDX()
 99 {
100     return (float)m_MouseState.lX;
101 }
102 
103 //-----------------------------------------------------------------------------
104 // Name:DInputClass::MouseDY
105 // Desc: 返回鼠标指针的Y轴坐标值
106 //-----------------------------------------------------------------------------
107 float DInputClass::MouseDY()
108 {
109     return (float)m_MouseState.lY;
110 }
111 
112 //-----------------------------------------------------------------------------
113 // Name:DInputClass::MouseDZ
114 // Desc: 返回鼠标指针的Z轴坐标值(滚轮)
115 //-----------------------------------------------------------------------------
116 float DInputClass::MouseDZ()
117 {
118     return (float)m_MouseState.lZ;
119 }
120 
121 
122 
123 
124 //-----------------------------------------------------------------------------
125 // Desc: 析构函数
126 //-----------------------------------------------------------------------------
127 DInputClass::~DInputClass(void)
128 {
129     if(m_KeyboardDevice != NULL)
130         m_KeyboardDevice->Unacquire();
131     if(m_MouseDevice != NULL)
132         m_MouseDevice->Unacquire();
133     SAFE_RELEASE(m_KeyboardDevice);
134     SAFE_RELEASE(m_MouseDevice);
135     SAFE_RELEASE(m_pDirectInput);
136 }
View Code
复制代码

//main.cpp修改前

复制代码
  1 //第2步,宏定义部分移动到最前面
  2 //-----------------------------------【宏定义部分】--------------------------------------------
  3 #define WINDOW_WIDTH    800
  4 #define WINDOW_HEIGHT    600
  5 #define WINDOW_TITLE    L"安康学院数字媒体技术"
  6 #define DIRECTINPUT_VERSION 0x0800 
  7 #define SAFE_RELEASE(p) { if(p) { (p)->Release(); (p)=NULL; } }//释放的是COM资源
  8 #define SAFE_DELETE(p)  { if(p) { delete (p); (p)=NULL; } }    //释放的是指针
  9 
 10 //-----------------------------------【头文件包含部分】---------------------------------------
 11 #include<d3d9.h>
 12 #include <d3dx9.h>
 13 #include <tchar.h>
 14 #include <time.h>
 15 #include <dinput.h>
 16 
 17 
 18 //-----------------------------------【库文件包含部分】---------------------------------------
 19 #pragma comment(lib,"winmm.lib") 
 20 #pragma comment(lib,"d3d9.lib")
 21 #pragma comment(lib,"d3dx9.lib")
 22 #pragma comment(lib, "dinput8.lib") 
 23 #pragma comment(lib,"dxguid.lib")
 24 
 25 /*
 26 //-----------------------------------【宏定义部分】--------------------------------------------
 27 #define WINDOW_WIDTH    800
 28 #define WINDOW_HEIGHT    600
 29 #define WINDOW_TITLE    L"安康学院数字媒体技术"
 30 //第1步,因为老出现这个报错。所有加这一句,同时要把宏定义部分移动到最前面,在#include <dinput.h>的前面以免重复定义。
 31 /*c:\program files (x86)\microsoft directx sdk (june 2010)\include\dinput.h: DIRECTINPUT_VERSION undefined. Defaulting to version 0x0800
 32 1>c:\users\zhj\desktop\123\dx111\demo\demo\main.cpp(21): warning C4005: “°DIRECTINPUT_VERSION”±: 宏重定义
 33 */
 34 /*
 35 #define DIRECTINPUT_VERSION 0x0800 
 36 #define SAFE_RELEASE(p) { if(p) { (p)->Release(); (p)=NULL; } }//释放的是COM资源
 37 #define SAFE_DELETE(p)  { if(p) { delete (p); (p)=NULL; } }    //释放的是指针
 38 
 39 */
 40 
 41 //-----------------------------------【全局变量声明部分】-------------------------------------
 42 LPDIRECT3DDEVICE9       g_pd3dDevice            = NULL; 
 43 LPD3DXFONT                g_pTextFPS                =NULL;
 44 LPD3DXFONT                g_pTextAdaperName       = NULL;
 45 LPD3DXFONT                g_pTextHelper           = NULL; 
 46 LPD3DXFONT                g_pTextInfor            = NULL;
 47 float                   g_FPS=0.0f;
 48 wchar_t                    g_strFPS[50]={0}; 
 49 wchar_t                    g_strAdapterName[60]={0};
 50 LPDIRECTINPUT8            g_pDirectInput      = NULL;
 51 LPDIRECTINPUTDEVICE8    g_pMouseDevice      = NULL;
 52 DIMOUSESTATE            g_diMouseState      = {0};
 53 LPDIRECTINPUTDEVICE8    g_pKeyboardDevice   = NULL;
 54 char                    g_pKeyStateBuffer[256] = {0};
 55 D3DXMATRIX                g_matWorld;
 56 LPD3DXMESH                g_pMesh     = NULL; 
 57 D3DMATERIAL9*            g_pMaterials    = NULL; 
 58 LPDIRECT3DTEXTURE9*        g_pTextures     = NULL;
 59 DWORD                    g_dwNumMtrls    = 0; 
 60 
 61 //-----------------------------------【全局函数声明部分】-------------------------------------
 62 LRESULT CALLBACK    WndProc( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam );
 63 //第1步 添加对象句柄
 64 HRESULT                    Direct3D_Init(HWND hwnd,HINSTANCE hInstance);
 65 HRESULT                    Objects_Init(HWND hwnd);
 66 void                    Direct3D_Render(HWND hwnd);
 67 void                    Direct3D_Update(HWND hwnd);
 68 void                    Direct3D_CleanUp( );
 69 float                    Get_FPS();
 70 void                    Matrix_Set();
 71 //第2步 添加设备读取函数
 72 BOOL                    Device_Read(IDirectInputDevice8 *pDIDevice, void* pBuffer, long lSize) ;
 73 
 74 //-----------------------------------【WinMain( )函数】--------------------------------------
 75 //    描述:Windows应用程序的入口函数,我们的程序从这里开始
 76 int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nShowCmd)
 77 {
 78     //【1】开始设计一个完整的窗口类
 79     WNDCLASSEX wndClass = { 0 };
 80     wndClass.cbSize = sizeof( WNDCLASSEX ) ;
 81     wndClass.style = CS_HREDRAW | CS_VREDRAW;
 82     wndClass.lpfnWndProc = WndProc;
 83     wndClass.cbClsExtra        = 0;
 84     wndClass.cbWndExtra        = 0;
 85     wndClass.hInstance = hInstance;    
 86     wndClass.hIcon=(HICON)::LoadImage(NULL,L"icon.ico",IMAGE_ICON,0,0,LR_DEFAULTSIZE|LR_LOADFROMFILE);
 87     wndClass.hCursor = LoadCursor( NULL, IDC_ARROW );
 88     wndClass.hbrBackground=(HBRUSH)GetStockObject(GRAY_BRUSH);
 89     wndClass.lpszMenuName = NULL;
 90     wndClass.lpszClassName = L"ForTheDreamOfGameDevelop";
 91 
 92     //【2】注册窗口类
 93     if( !RegisterClassEx( &wndClass ) )    
 94         return -1;
 95 
 96     //【3】正式创建窗口
 97     HWND hwnd = CreateWindow( L"ForTheDreamOfGameDevelop",WINDOW_TITLE,    
 98         WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, WINDOW_WIDTH,
 99         WINDOW_HEIGHT, NULL, NULL, hInstance, NULL );
100 //第3步 对应修改参数
101     if (S_OK==Direct3D_Init(hwnd,hInstance))
102         {
103         MessageBox(hwnd, L"Direct3D初始化完成~!", L"消息窗口", 0);
104         }
105     else
106         {
107         MessageBox(hwnd, L"Direct3D初始化失败~!", L"消息窗口", 0);
108         }
109     //Direct3D资源的初始化,调用失败用messagebox予以显示
110     if (!(S_OK==Direct3D_Init (hwnd,hInstance)))
111     {
112         MessageBox(hwnd, _T("Direct3D初始化失败~!"), _T("消息窗口"), 0); //使用MessageBox函数,创建一个消息窗口 
113     }
114 
115 
116     //【4】窗口的移动、显示与更新
117     MoveWindow(hwnd,250,80,WINDOW_WIDTH,WINDOW_HEIGHT,true);
118     ShowWindow(hwnd, nShowCmd );
119     UpdateWindow(hwnd);
120 
121     PlaySound(L"刻限.wav", NULL, SND_FILENAME | SND_ASYNC|SND_LOOP); 
122 
123     //【5】消息循环过程
124     MSG msg = { 0 };
125     while( msg.message != WM_QUIT )
126         {
127         if( PeekMessage( &msg, 0, 0, 0, PM_REMOVE ) )   //查看应用程序消息队列,有消息时将队列中的消息派发出去。
128         {
129             TranslateMessage( &msg );        //将虚拟键消息转换为字符消息
130             DispatchMessage( &msg );        //该函数分发一个消息给窗口程序。
131         }
132         else
133         {
134 //第6步 添加调用更新函数,进行画面的更新
135             Direct3D_Update(hwnd);            //调用更新函数,进行画面的更新
136             Direct3D_Render(hwnd);   //进行渲染
137         }
138     }
139 
140     //【6】窗口类的注销
141     UnregisterClass(L"ForTheDreamOfGameDevelop", wndClass.hInstance); 
142         return 0;  
143 }
144 
145 //-----------------------------------【WndProc( )函数】--------------------------------------
146 LRESULT CALLBACK WndProc( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam )      
147 {
148     switch( message )
149     {
150         case WM_PAINT:
151             Direct3D_Render(hwnd);
152             ValidateRect(hwnd, NULL);
153             break;
154 
155         case WM_KEYDOWN:
156             if (wParam == VK_ESCAPE)
157                 DestroyWindow(hwnd);
158             break;
159 
160         case WM_DESTROY:
161             Direct3D_CleanUp();
162             PostQuitMessage( 0 );
163             break;    
164 
165         default:
166             return DefWindowProc( hwnd, message, wParam, lParam );
167     }
168     return 0;
169 }
170 
171 //-----------------------------------【Direct3D_Init( )函数】--------------------------------------
172 //第4步:对应修改Direct3D_Init参数
173 HRESULT    Direct3D_Init(HWND hwnd,HINSTANCE hInstance)
174 {
175     //Direct3D初始化,第一步
176     LPDIRECT3D9 pD3D=NULL;
177     if(NULL==(pD3D=Direct3DCreate9(D3D_SDK_VERSION)))
178         return E_FAIL;
179 
180     //Direct3D初始化,第二步
181     D3DCAPS9 caps; int vp = 0;
182     if( FAILED( pD3D->GetDeviceCaps( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, &caps ) ) )
183     {
184         return E_FAIL;
185     }
186     if( caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT )
187 
188         vp = D3DCREATE_HARDWARE_VERTEXPROCESSING; 
189     else
190         vp = D3DCREATE_SOFTWARE_VERTEXPROCESSING;
191 
192 
193     //Direct3D初始化,第三步,D3DPRESENT_PARAMETERS结构体
194 
195     D3DPRESENT_PARAMETERS d3dpp; 
196     ZeroMemory(&d3dpp, sizeof(d3dpp));
197     d3dpp.BackBufferWidth            = WINDOW_WIDTH;
198     d3dpp.BackBufferHeight           = WINDOW_HEIGHT;
199     d3dpp.BackBufferFormat           = D3DFMT_A8R8G8B8;
200 //第7步 对应一个参数
201     d3dpp.BackBufferCount            = 2;
202     d3dpp.MultiSampleType            = D3DMULTISAMPLE_NONE;
203     d3dpp.MultiSampleQuality         = 0;
204     d3dpp.SwapEffect                 = D3DSWAPEFFECT_DISCARD; 
205     d3dpp.hDeviceWindow              = hwnd;
206     d3dpp.Windowed                   = true;
207     d3dpp.EnableAutoDepthStencil     = true; 
208     d3dpp.AutoDepthStencilFormat     = D3DFMT_D24S8;
209     d3dpp.Flags                      = 0;
210     d3dpp.FullScreen_RefreshRateInHz = 0;
211     d3dpp.PresentationInterval       = D3DPRESENT_INTERVAL_IMMEDIATE;
212 
213     //Direct3D初始化,第四步
214 
215     if(FAILED(pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, 
216         hwnd, vp, &d3dpp, &g_pd3dDevice)))
217         return E_FAIL;
218 
219     wchar_t TempName[60]=L"当前显卡型号:";
220     D3DADAPTER_IDENTIFIER9 Adapter;
221     pD3D->GetAdapterIdentifier(0,0,&Adapter);
222     int len = MultiByteToWideChar(CP_ACP,0, Adapter.Description, -1, NULL, 0);
223     MultiByteToWideChar(CP_ACP, 0, Adapter.Description, -1, g_strAdapterName, len);
224     wcscat_s(TempName,g_strAdapterName);
225     wcscpy_s(g_strAdapterName,TempName);
226 //第8步 创建DirectInput
227 
228     // 1.创建DirectInput接口和设备
229     DirectInput8Create(hInstance, 0x0800, IID_IDirectInput8, (void**)&g_pDirectInput, NULL);
230 
231 
232     //2.数据格式
233     g_pDirectInput->CreateDevice(GUID_SysMouse, &g_pMouseDevice, NULL);
234     g_pMouseDevice->SetDataFormat(&c_dfDIMouse);
235     g_pMouseDevice->SetCooperativeLevel(hwnd, DISCL_FOREGROUND | DISCL_NONEXCLUSIVE);
236 
237     //3.获取设备控制权
238     g_pMouseDevice->Acquire();
239 
240     DirectInput8Create(hInstance, 0x0800, IID_IDirectInput8, (void**)&g_pDirectInput, NULL);
241     g_pDirectInput->CreateDevice(GUID_SysKeyboard, &g_pKeyboardDevice, NULL);
242 
243     g_pKeyboardDevice->SetDataFormat(&c_dfDIKeyboard);
244     g_pKeyboardDevice->SetCooperativeLevel(hwnd, DISCL_FOREGROUND | DISCL_NONEXCLUSIVE);
245 
246     g_pKeyboardDevice->Acquire();
247 
248     
249 //第9步 对应修改参数
250 
251     if(!(S_OK==Objects_Init(hwnd))) return E_FAIL;
252     SAFE_RELEASE(pD3D); 
253     return S_OK;
254 
255 }
256 
257 
258 //-----------------------------------【Object_Init( )函数】--------------------------------------
259 //第5步:对应修改Objects_Init参数
260 HRESULT Objects_Init(HWND hwnd)
261 {
262         D3DXCreateFont(g_pd3dDevice, 36, 0, 0, 1000, false, DEFAULT_CHARSET, 
263         OUT_DEFAULT_PRECIS, DEFAULT_QUALITY, 0, _T("Calibri"), &g_pTextFPS);
264 
265         D3DXCreateFont(g_pd3dDevice, 20, 0, 1000, 0, false, DEFAULT_CHARSET, 
266         OUT_DEFAULT_PRECIS, DEFAULT_QUALITY, 0, L"华文中宋", &g_pTextAdaperName); 
267 
268         D3DXCreateFont(g_pd3dDevice, 23, 0, 1000, 0, false, DEFAULT_CHARSET, 
269         OUT_DEFAULT_PRECIS, DEFAULT_QUALITY, 0, L"微软雅黑", &g_pTextHelper); 
270     
271         D3DXCreateFont(g_pd3dDevice, 26, 0, 1000, 0, false, DEFAULT_CHARSET, 
272         OUT_DEFAULT_PRECIS, DEFAULT_QUALITY, 0, L"黑体", &g_pTextInfor); 
273 
274 
275     // 从X文件中加载网格数据
276     LPD3DXBUFFER pAdjBuffer  = NULL;
277     LPD3DXBUFFER pMtrlBuffer = NULL;
278     D3DXLoadMeshFromX(L"loli.x", D3DXMESH_MANAGED, g_pd3dDevice, 
279         &pAdjBuffer, &pMtrlBuffer, NULL, &g_dwNumMtrls, &g_pMesh);
280     // 读取材质和纹理数据
281     D3DXMATERIAL *pMtrls = (D3DXMATERIAL*)pMtrlBuffer->GetBufferPointer();//创建一个D3DXMATERIAL结构体用于读取材质和纹理信息
282     g_pMaterials = new D3DMATERIAL9[g_dwNumMtrls];
283     g_pTextures  = new LPDIRECT3DTEXTURE9[g_dwNumMtrls];
284 
285     for (DWORD i=0; i<g_dwNumMtrls; i++) 
286     {
287         //获取材质,并设置一下环境光的颜色值
288         g_pMaterials[i] = pMtrls[i].MatD3D;
289         g_pMaterials[i].Ambient = g_pMaterials[i].Diffuse;
290         //创建一下纹理对象
291         g_pTextures[i]  = NULL;
292         D3DXCreateTextureFromFileA(g_pd3dDevice, pMtrls[i].pTextureFilename, &g_pTextures[i]);
293     }
294     pAdjBuffer->Release();
295     pMtrlBuffer->Release();
296 
297 
298 
299     // 设置渲染状态
300     g_pd3dDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW);   //开启背面消隐
301     g_pd3dDevice->SetRenderState(D3DRS_AMBIENT, D3DXCOLOR(1.0f, 1.0f, 1.0f, 1.0f)); //设置环境光
302     //第10步,移入update函数中
303     //Matrix_Set();//调用封装了四大变换的函数,对Direct3D世界变换,取景变换,投影变换,视口变换进行设置
304 
305     return S_OK;
306 }
307 //-----------------------------------【Matrix_Set( )函数】--------------------------------------
308 void Matrix_Set()
309 {
310 //第11步 世界变换矩阵的设置,改动到鼠标键盘操作后对世界变换矩阵修改
311 
312     //--------------------------------------------------------------------------------------
313     //【四大变换之一】:世界变换矩阵的设置
314     //--------------------------------------------------------------------------------------
315 /*
316     D3DXMATRIX matWorld, Rx, Ry, Rz;
317     D3DXMatrixIdentity(&matWorld);                  // 单位化世界矩阵
318     D3DXMatrixRotationX(&Rx, D3DX_PI *(::timeGetTime() / 1000.0f));    // 绕X轴旋转
319     D3DXMatrixRotationY(&Ry, D3DX_PI *( ::timeGetTime() / 1000.0f/2));    // 绕Y轴旋转
320     D3DXMatrixRotationZ(&Rz, D3DX_PI *( ::timeGetTime() / 1000.0f/3));   // 绕Z轴旋转
321     matWorld = Rx * Ry * Rz * matWorld;             // 得到最终的组合矩阵
322     g_pd3dDevice->SetTransform(D3DTS_WORLD, &matWorld);  //设置世界变换矩阵
323 */
324     //--------------------------------------------------------------------------------------
325     //【四大变换之二】:取景变换矩阵的设置
326     //--------------------------------------------------------------------------------------
327     D3DXMATRIX matView; //定义一个矩阵
328     D3DXVECTOR3 vEye(0.0f, 0.0f, -250.0f);  //摄像机的位置
329     D3DXVECTOR3 vAt(0.0f, 0.0f, 0.0f); //观察点的位置
330     D3DXVECTOR3 vUp(0.0f, 1.0f, 0.0f);//向上的向量
331     D3DXMatrixLookAtLH(&matView, &vEye, &vAt, &vUp); //计算出取景变换矩阵
332     g_pd3dDevice->SetTransform(D3DTS_VIEW, &matView); //应用取景变换矩阵
333 
334     //--------------------------------------------------------------------------------------
335     //【四大变换之三】:投影变换矩阵的设置
336     //--------------------------------------------------------------------------------------
337     D3DXMATRIX matProj; //定义一个矩阵
338     D3DXMatrixPerspectiveFovLH(&matProj, D3DX_PI / 4.0f,(float)((double)WINDOW_WIDTH/WINDOW_HEIGHT),1.0f, 1000.0f); //计算投影变换矩阵
339     g_pd3dDevice->SetTransform(D3DTS_PROJECTION, &matProj);  //设置投影变换矩阵
340 
341     //--------------------------------------------------------------------------------------
342     //【四大变换之四】:视口变换的设置
343     //--------------------------------------------------------------------------------------
344     D3DVIEWPORT9 vp; //实例化一个D3DVIEWPORT9结构体,然后做填空题给各个参数赋值就可以了
345     vp.X      = 0;        //表示视口相对于窗口的X坐标
346     vp.Y      = 0;        //视口相对对窗口的Y坐标
347     vp.Width  = WINDOW_WIDTH;    //视口的宽度
348     vp.Height = WINDOW_HEIGHT; //视口的高度
349     vp.MinZ   = 0.0f; //视口在深度缓存中的最小深度值
350     vp.MaxZ   = 1.0f;    //视口在深度缓存中的最大深度值
351     g_pd3dDevice->SetViewport(&vp); //视口的设置
352 }
353 //第12步 Direct3D_Update( )函数
354 //-----------------------------------【Direct3D_Update( )函数】--------------------------------
355 //    描述:不是即时渲染代码但是需要即时调用的,如按键后的坐标的更改,都放在这里
356 //--------------------------------------------------------------------------------------------------
357 void    Direct3D_Update( HWND hwnd)
358 {
359     // 获取键盘消息并给予设置相应的填充模式  
360     if (g_pKeyStateBuffer[DIK_1]    & 0x80)         // 若数字键1被按下,进行实体填充  
361         g_pd3dDevice->SetRenderState(D3DRS_FILLMODE,D3DFILL_SOLID);
362     if (g_pKeyStateBuffer[DIK_2]    & 0x80)         // 若数字键2被按下,进行线框填充  
363         g_pd3dDevice->SetRenderState(D3DRS_FILLMODE,D3DFILL_WIREFRAME);  
364 
365     // 读取鼠标输入
366     ::ZeroMemory(&g_diMouseState, sizeof(g_diMouseState));
367     Device_Read(g_pMouseDevice, (LPVOID)&g_diMouseState, sizeof(g_diMouseState));
368 
369     // 读取键盘输入
370     ::ZeroMemory(g_pKeyStateBuffer, sizeof(g_pKeyStateBuffer));
371     Device_Read(g_pKeyboardDevice, (LPVOID)g_pKeyStateBuffer, sizeof(g_pKeyStateBuffer));
372 
373 
374     // 按住鼠标左键并拖动,为平移操作
375     static FLOAT fPosX = 0.0f, fPosY = 30.0f, fPosZ = 0.0f;
376     if (g_diMouseState.rgbButtons[0] & 0x80) 
377     {
378         fPosX += g_diMouseState.lX *  0.08f;
379         fPosY += g_diMouseState.lY * -0.08f;
380     }
381 
382     //鼠标滚轮,为观察点收缩操作
383     fPosZ += g_diMouseState.lZ * 0.02f;
384 
385     // 平移物体
386     if (g_pKeyStateBuffer[DIK_A] & 0x80) fPosX -= 0.005f;
387     if (g_pKeyStateBuffer[DIK_D] & 0x80) fPosX += 0.005f;
388     if (g_pKeyStateBuffer[DIK_W] & 0x80) fPosY += 0.005f;
389     if (g_pKeyStateBuffer[DIK_S] & 0x80) fPosY -= 0.005f;
390 
391 
392     D3DXMatrixTranslation(&g_matWorld, fPosX, fPosY, fPosZ);
393 
394 
395     // 按住鼠标右键并拖动,为旋转操作
396     static float fAngleX = 0.15f, fAngleY = -(float)D3DX_PI ;
397     if (g_diMouseState.rgbButtons[1] & 0x80) 
398     {
399         fAngleX += g_diMouseState.lY * -0.01f;
400         fAngleY += g_diMouseState.lX * -0.01f;
401     }
402     // 旋转物体
403     if (g_pKeyStateBuffer[DIK_UP]    & 0x80) fAngleX += 0.005f;
404     if (g_pKeyStateBuffer[DIK_DOWN]  & 0x80) fAngleX -= 0.005f;
405     if (g_pKeyStateBuffer[DIK_LEFT]  & 0x80) fAngleY -= 0.005f;
406     if (g_pKeyStateBuffer[DIK_RIGHT] & 0x80) fAngleY += 0.005f;
407 
408 
409     D3DXMATRIX Rx, Ry;
410     D3DXMatrixRotationX(&Rx, fAngleX);
411     D3DXMatrixRotationY(&Ry, fAngleY);
412 
413     //得到最终的矩阵并设置
414     g_matWorld = Rx * Ry * g_matWorld;//得到最终的矩阵
415     g_pd3dDevice->SetTransform(D3DTS_WORLD, &g_matWorld);//设置世界矩阵
416     Matrix_Set();
417 }
418 
419 //-----------------------------------【Direct3D_Render( )函数】--------------------------------------
420 void Direct3D_Render(HWND hwnd)
421 {//1
422 //第5步,清除buffer
423     g_pd3dDevice->Clear(0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(150, 150, 100), 1.0f, 0);
424     RECT formatRect;
425     GetClientRect(hwnd, &formatRect);
426     //2
427     g_pd3dDevice->BeginScene();   
428     //3
429 
430     for (DWORD i = 0; i < g_dwNumMtrls; i++)
431             {
432                 g_pd3dDevice->SetMaterial(&g_pMaterials[i]);
433                 g_pd3dDevice->SetTexture(0, g_pTextures[i]);
434                 g_pMesh->DrawSubset(i);
435             }
436 
437             int charCount = swprintf_s(g_strFPS, 20, _T("FPS:%0.3f"), Get_FPS() );
438             g_pTextFPS->DrawText(NULL, g_strFPS, charCount , &formatRect, DT_TOP | DT_RIGHT, D3DCOLOR_RGBA(0,239,136,255));
439     
440             g_pTextAdaperName->DrawText(NULL,g_strAdapterName, -1, &formatRect, 
441                 DT_TOP | DT_LEFT, D3DXCOLOR(1.0f, 0.5f, 0.0f, 1.0f));
442 
443             formatRect.top = 30;
444             static wchar_t strInfo[256] = {0};
445             swprintf_s(strInfo,-1, L"模型坐标: (%.2f, %.2f, %.2f)", g_matWorld._41, g_matWorld._42, g_matWorld._43);
446             g_pTextHelper->DrawText(NULL, strInfo, -1, &formatRect, DT_SINGLELINE | DT_NOCLIP | DT_LEFT, D3DCOLOR_RGBA(135,239,136,255));
447 
448 
449 
450             formatRect.left = 0,formatRect.top = 380;
451             g_pTextInfor->DrawText(NULL, L"控制说明:", -1, &formatRect, 
452                 DT_SINGLELINE | DT_NOCLIP | DT_LEFT, D3DCOLOR_RGBA(235,123,230,255));
453             formatRect.top += 35;
454             g_pTextHelper->DrawText(NULL, L"    按住鼠标左键并拖动:平移模型", -1, &formatRect, 
455                 DT_SINGLELINE | DT_NOCLIP | DT_LEFT, D3DCOLOR_RGBA(255,200,0,255));
456             formatRect.top += 25;
457             g_pTextHelper->DrawText(NULL, L"    按住鼠标右键并拖动:旋转模型", -1, &formatRect, 
458                 DT_SINGLELINE | DT_NOCLIP | DT_LEFT, D3DCOLOR_RGBA(255,200,0,255));
459             formatRect.top += 25;
460             g_pTextHelper->DrawText(NULL, L"    滑动鼠标滚轮:拉伸模型", -1, &formatRect, 
461                 DT_SINGLELINE | DT_NOCLIP | DT_LEFT, D3DCOLOR_RGBA(255,200,0,255));
462             formatRect.top += 25;
463             g_pTextHelper->DrawText(NULL, L"    W、S、A、D键:平移模型 ", -1, &formatRect, 
464                 DT_SINGLELINE | DT_NOCLIP | DT_LEFT, D3DCOLOR_RGBA(255,200,0,255));
465             formatRect.top += 25;
466             g_pTextHelper->DrawText(NULL, L"    上、下、左、右方向键:旋转模型 ", -1, &formatRect, 
467                 DT_SINGLELINE | DT_NOCLIP | DT_LEFT, D3DCOLOR_RGBA(255,200,0,255));
468             formatRect.top += 25;
469             g_pTextHelper->DrawText(NULL, L"    ESC键 : 退出程序", -1, &formatRect, 
470                 DT_SINGLELINE | DT_NOCLIP | DT_LEFT, D3DCOLOR_RGBA(255,200,0,255));
471     //4
472     g_pd3dDevice->EndScene(); 
473     //5
474     g_pd3dDevice->Present(NULL, NULL, NULL, NULL); 
475 }
476 
477 
478 
479 
480 //-----------------------------------【Get_FPS( )函数】------------------------------------------
481 float    Get_FPS()
482 {
483     static float  fps = 0;//fps值
484     static int     frameCount = 0;//帧数
485     static float  currentTime =0.0f;//当前时间
486     static float  lastTime = 0.0f;//持续时间
487 
488     frameCount++;
489     currentTime=timeGetTime()*0.001f;//获取系统时间
490 
491     if(currentTime-lastTime>1.0f)
492     {
493         fps = (float)frameCount /(currentTime - lastTime);
494         lastTime=currentTime;
495         frameCount=0;
496 
497     }
498     return fps;
499 
500 }
501 //第13步Device_Read( )函数
502 //-----------------------------------【Device_Read( )函数】------------------------------------
503 // Desc: 智能读取设备的输入数据
504 //--------------------------------------------------------------------------------------------------
505 BOOL Device_Read(IDirectInputDevice8 *pDIDevice, void* pBuffer, long lSize) 
506 {
507     HRESULT hr;
508     while (true) 
509     {
510         pDIDevice->Poll();              // 轮询设备
511         pDIDevice->Acquire();           // 获取设备的控制权
512         if (SUCCEEDED(hr = pDIDevice->GetDeviceState(lSize, pBuffer))) break;
513         if (hr != DIERR_INPUTLOST || hr != DIERR_NOTACQUIRED) return FALSE;
514         if (FAILED(pDIDevice->Acquire())) return FALSE;
515     }
516     return TRUE;
517 }
518 
519 //-----------------------------------【Direct3D_CleanUp( )函数】--------------------------------
520 void Direct3D_CleanUp()
521 {
522     //释放COM接口对象
523 //第14步 取消注释
524 
525     g_pMouseDevice->Unacquire();
526     g_pKeyboardDevice->Unacquire();
527     for (DWORD i = 0; i<g_dwNumMtrls; i++) 
528         SAFE_RELEASE(g_pTextures[i]);
529     SAFE_DELETE(g_pTextures)
530     SAFE_DELETE(g_pMaterials)
531     SAFE_RELEASE(g_pMesh)
532     SAFE_RELEASE(g_pTextFPS)
533     SAFE_RELEASE(g_pd3dDevice)    
534     SAFE_RELEASE(g_pMouseDevice)
535     SAFE_RELEASE(g_pKeyboardDevice)
536 }
View Code
复制代码

//main.cpp修改过程

 

复制代码
//第2步,宏定义部分移动到最前面
//-----------------------------------【宏定义部分】--------------------------------------------
#define WINDOW_WIDTH    800
#define WINDOW_HEIGHT    600
#define WINDOW_TITLE    L"安康学院数字媒体技术"
//第1步:注释掉,前面d3dutil.h已经定义过
//#define DIRECTINPUT_VERSION 0x0800 
//#define SAFE_RELEASE(p) { if(p) { (p)->Release(); (p)=NULL; } }//释放的是COM资源
//#define SAFE_DELETE(p)  { if(p) { delete (p); (p)=NULL; } }    //释放的是指针

//-----------------------------------【头文件包含部分】---------------------------------------
#include<d3d9.h>
#include <d3dx9.h>
#include <tchar.h>
#include <time.h>
//第2步:注释掉,改成
//#include <dinput.h>
#include "DirectInputClass.h"

//-----------------------------------【库文件包含部分】---------------------------------------
#pragma comment(lib,"winmm.lib") 
#pragma comment(lib,"d3d9.lib")
#pragma comment(lib,"d3dx9.lib")
#pragma comment(lib, "dinput8.lib") 
#pragma comment(lib,"dxguid.lib")

/*
//-----------------------------------【宏定义部分】--------------------------------------------
#define WINDOW_WIDTH    800
#define WINDOW_HEIGHT    600
#define WINDOW_TITLE    L"安康学院数字媒体技术"
//第1步,因为老出现这个报错。所有加这一句,同时要把宏定义部分移动到最前面,在#include <dinput.h>的前面以免重复定义。
/*c:\program files (x86)\microsoft directx sdk (june 2010)\include\dinput.h: DIRECTINPUT_VERSION undefined. Defaulting to version 0x0800
1>c:\users\zhj\desktop\123\dx111\demo\demo\main.cpp(21): warning C4005: “°DIRECTINPUT_VERSION”±: 宏重定义
*/
/*
#define DIRECTINPUT_VERSION 0x0800 
#define SAFE_RELEASE(p) { if(p) { (p)->Release(); (p)=NULL; } }//释放的是COM资源
#define SAFE_DELETE(p)  { if(p) { delete (p); (p)=NULL; } }    //释放的是指针

*/

//-----------------------------------【全局变量声明部分】-------------------------------------
LPDIRECT3DDEVICE9       g_pd3dDevice            = NULL; 
LPD3DXFONT                g_pTextFPS                =NULL;
LPD3DXFONT                g_pTextAdaperName       = NULL;
LPD3DXFONT                g_pTextHelper           = NULL; 
LPD3DXFONT                g_pTextInfor            = NULL;
float                   g_FPS=0.0f;
wchar_t                    g_strFPS[50]={0}; 
wchar_t                    g_strAdapterName[60]={0};
//第3步 注释掉input相关变量,类文件已经包含
//LPDIRECTINPUT8            g_pDirectInput      = NULL;
//LPDIRECTINPUTDEVICE8    g_pMouseDevice      = NULL;
//DIMOUSESTATE            g_diMouseState      = {0};
//LPDIRECTINPUTDEVICE8    g_pKeyboardDevice   = NULL;
//char                    g_pKeyStateBuffer[256] = {0};
D3DXMATRIX                g_matWorld;
//第4步 定义//一个DInputClass类的指针
DInputClass*            g_pDInput = NULL;         //一个DInputClass类的指针

LPD3DXMESH                g_pMesh     = NULL; 
D3DMATERIAL9*            g_pMaterials    = NULL; 
LPDIRECT3DTEXTURE9*        g_pTextures     = NULL;
DWORD                    g_dwNumMtrls    = 0; 

//-----------------------------------【全局函数声明部分】-------------------------------------
LRESULT CALLBACK    WndProc( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam );
//第1步 添加对象句柄
HRESULT                    Direct3D_Init(HWND hwnd,HINSTANCE hInstance);
//第10步:对应修改Objects_Init参数 ,参数申明也要改
HRESULT                    Objects_Init();//(HWND hwnd);
void                    Direct3D_Render(HWND hwnd);
void                    Direct3D_Update(HWND hwnd);
void                    Direct3D_CleanUp( );
float                    Get_FPS();
void                    Matrix_Set();
//第5步 注销设备读取函数
//BOOL                    Device_Read(IDirectInputDevice8 *pDIDevice, void* pBuffer, long lSize) ;



//-----------------------------------【WinMain( )函数】--------------------------------------
//    描述:Windows应用程序的入口函数,我们的程序从这里开始
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nShowCmd)
{
    //【1】开始设计一个完整的窗口类
    WNDCLASSEX wndClass = { 0 };
    wndClass.cbSize = sizeof( WNDCLASSEX ) ;
    wndClass.style = CS_HREDRAW | CS_VREDRAW;
    wndClass.lpfnWndProc = WndProc;
    wndClass.cbClsExtra        = 0;
    wndClass.cbWndExtra        = 0;
    wndClass.hInstance = hInstance;    
    wndClass.hIcon=(HICON)::LoadImage(NULL,L"icon.ico",IMAGE_ICON,0,0,LR_DEFAULTSIZE|LR_LOADFROMFILE);
    wndClass.hCursor = LoadCursor( NULL, IDC_ARROW );
    wndClass.hbrBackground=(HBRUSH)GetStockObject(GRAY_BRUSH);
    wndClass.lpszMenuName = NULL;
    wndClass.lpszClassName = L"ForTheDreamOfGameDevelop";

    //【2】注册窗口类
    if( !RegisterClassEx( &wndClass ) )    
        return -1;

    //【3】正式创建窗口
    HWND hwnd = CreateWindow( L"ForTheDreamOfGameDevelop",WINDOW_TITLE,    
        WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, WINDOW_WIDTH,
        WINDOW_HEIGHT, NULL, NULL, hInstance, NULL );
//第6步 注释掉
    //if (S_OK==Direct3D_Init(hwnd,hInstance))
    //    {
    //    MessageBox(hwnd, L"Direct3D初始化完成~!", L"消息窗口", 0);
    //    }
    //else
    //    {
    //    MessageBox(hwnd, L"Direct3D初始化失败~!", L"消息窗口", 0);
    //    }
    //Direct3D资源的初始化,调用失败用messagebox予以显示
    if (!(S_OK==Direct3D_Init (hwnd,hInstance)))
    {
        MessageBox(hwnd, _T("Direct3D初始化失败~!"), _T("消息窗口"), 0); //使用MessageBox函数,创建一个消息窗口 
    }


    //【4】窗口的移动、显示与更新
    MoveWindow(hwnd,250,80,WINDOW_WIDTH,WINDOW_HEIGHT,true);
    ShowWindow(hwnd, nShowCmd );
    UpdateWindow(hwnd);

//第7步 进行DirectInput类的初始化
    g_pDInput = new DInputClass();
    g_pDInput->Init(hwnd,hInstance,DISCL_FOREGROUND | DISCL_NONEXCLUSIVE,DISCL_FOREGROUND | DISCL_NONEXCLUSIVE);
    PlaySound(L"偽りの饗宴.wav", NULL, SND_FILENAME | SND_ASYNC|SND_LOOP); //循环播放背景音乐 

    //【5】消息循环过程
    MSG msg = { 0 };
    while( msg.message != WM_QUIT )
        {
        if( PeekMessage( &msg, 0, 0, 0, PM_REMOVE ) )   //查看应用程序消息队列,有消息时将队列中的消息派发出去。
        {
            TranslateMessage( &msg );        //将虚拟键消息转换为字符消息
            DispatchMessage( &msg );        //该函数分发一个消息给窗口程序。
        }
        else
        {
//第6步 添加调用更新函数,进行画面的更新
            Direct3D_Update(hwnd);            //调用更新函数,进行画面的更新
            Direct3D_Render(hwnd);   //进行渲染
        }
    }

    //【6】窗口类的注销
    UnregisterClass(L"ForTheDreamOfGameDevelop", wndClass.hInstance); 
        return 0;  
}

//-----------------------------------【WndProc( )函数】--------------------------------------
LRESULT CALLBACK WndProc( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam )      
{
    switch( message )
    {
        case WM_PAINT:
            Direct3D_Render(hwnd);
            ValidateRect(hwnd, NULL);
            break;

        case WM_KEYDOWN:
            if (wParam == VK_ESCAPE)
                DestroyWindow(hwnd);
            break;

        case WM_DESTROY:
            Direct3D_CleanUp();
            PostQuitMessage( 0 );
            break;    

        default:
            return DefWindowProc( hwnd, message, wParam, lParam );
    }
    return 0;
}

//-----------------------------------【Direct3D_Init( )函数】--------------------------------------
//第4步:对应修改Direct3D_Init参数
HRESULT    Direct3D_Init(HWND hwnd,HINSTANCE hInstance)
{
    //Direct3D初始化,第一步
    LPDIRECT3D9 pD3D=NULL;
    if(NULL==(pD3D=Direct3DCreate9(D3D_SDK_VERSION)))
        return E_FAIL;

    //Direct3D初始化,第二步
    D3DCAPS9 caps; int vp = 0;
    if( FAILED( pD3D->GetDeviceCaps( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, &caps ) ) )
    {
        return E_FAIL;
    }
    if( caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT )

        vp = D3DCREATE_HARDWARE_VERTEXPROCESSING; 
    else
        vp = D3DCREATE_SOFTWARE_VERTEXPROCESSING;


    //Direct3D初始化,第三步,D3DPRESENT_PARAMETERS结构体

    D3DPRESENT_PARAMETERS d3dpp; 
    ZeroMemory(&d3dpp, sizeof(d3dpp));
    d3dpp.BackBufferWidth            = WINDOW_WIDTH;
    d3dpp.BackBufferHeight           = WINDOW_HEIGHT;
    d3dpp.BackBufferFormat           = D3DFMT_A8R8G8B8;
//第7步 对应一个参数
    d3dpp.BackBufferCount            = 2;
    d3dpp.MultiSampleType            = D3DMULTISAMPLE_NONE;
    d3dpp.MultiSampleQuality         = 0;
    d3dpp.SwapEffect                 = D3DSWAPEFFECT_DISCARD; 
    d3dpp.hDeviceWindow              = hwnd;
    d3dpp.Windowed                   = true;
    d3dpp.EnableAutoDepthStencil     = true; 
    d3dpp.AutoDepthStencilFormat     = D3DFMT_D24S8;
    d3dpp.Flags                      = 0;
    d3dpp.FullScreen_RefreshRateInHz = 0;
    d3dpp.PresentationInterval       = D3DPRESENT_INTERVAL_IMMEDIATE;

    //Direct3D初始化,第四步

    if(FAILED(pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, 
        hwnd, vp, &d3dpp, &g_pd3dDevice)))
        return E_FAIL;

    wchar_t TempName[60]=L"当前显卡型号:";
    D3DADAPTER_IDENTIFIER9 Adapter;
    pD3D->GetAdapterIdentifier(0,0,&Adapter);
    int len = MultiByteToWideChar(CP_ACP,0, Adapter.Description, -1, NULL, 0);
    MultiByteToWideChar(CP_ACP, 0, Adapter.Description, -1, g_strAdapterName, len);
    wcscat_s(TempName,g_strAdapterName);
    wcscpy_s(g_strAdapterName,TempName);
//第8步 注销创建DirectInput

    //// 1.创建DirectInput接口和设备
    //DirectInput8Create(hInstance, 0x0800, IID_IDirectInput8, (void**)&g_pDirectInput, NULL);


    ////2.数据格式
    //g_pDirectInput->CreateDevice(GUID_SysMouse, &g_pMouseDevice, NULL);
    //g_pMouseDevice->SetDataFormat(&c_dfDIMouse);
    //g_pMouseDevice->SetCooperativeLevel(hwnd, DISCL_FOREGROUND | DISCL_NONEXCLUSIVE);

    ////3.获取设备控制权
    //g_pMouseDevice->Acquire();

    //DirectInput8Create(hInstance, 0x0800, IID_IDirectInput8, (void**)&g_pDirectInput, NULL);
    //g_pDirectInput->CreateDevice(GUID_SysKeyboard, &g_pKeyboardDevice, NULL);

    //g_pKeyboardDevice->SetDataFormat(&c_dfDIKeyboard);
    //g_pKeyboardDevice->SetCooperativeLevel(hwnd, DISCL_FOREGROUND | DISCL_NONEXCLUSIVE);

    //g_pKeyboardDevice->Acquire();

    
//第9步 对应修改参数

    //if(!(S_OK==Objects_Init(hwnd))) return E_FAIL;
    if(!(S_OK==Objects_Init())) return E_FAIL;
    SAFE_RELEASE(pD3D); 
    return S_OK;

}


//-----------------------------------【Object_Init( )函数】--------------------------------------
//第10步:对应修改Objects_Init参数 ,参数申明也要改
//HRESULT Objects_Init(HWND hwnd)
    HRESULT Objects_Init()
{
        D3DXCreateFont(g_pd3dDevice, 36, 0, 0, 1000, false, DEFAULT_CHARSET, 
        OUT_DEFAULT_PRECIS, DEFAULT_QUALITY, 0, _T("Calibri"), &g_pTextFPS);

        D3DXCreateFont(g_pd3dDevice, 20, 0, 1000, 0, false, DEFAULT_CHARSET, 
        OUT_DEFAULT_PRECIS, DEFAULT_QUALITY, 0, L"华文中宋", &g_pTextAdaperName); 

        D3DXCreateFont(g_pd3dDevice, 23, 0, 1000, 0, false, DEFAULT_CHARSET, 
        OUT_DEFAULT_PRECIS, DEFAULT_QUALITY, 0, L"微软雅黑", &g_pTextHelper); 
    
        D3DXCreateFont(g_pd3dDevice, 26, 0, 1000, 0, false, DEFAULT_CHARSET, 
        OUT_DEFAULT_PRECIS, DEFAULT_QUALITY, 0, L"黑体", &g_pTextInfor); 


    // 从X文件中加载网格数据
    LPD3DXBUFFER pAdjBuffer  = NULL;
    LPD3DXBUFFER pMtrlBuffer = NULL;
    //第11步:对应修改参数
    //D3DXLoadMeshFromX(L"loli.x", D3DXMESH_MANAGED, g_pd3dDevice, 
        D3DXLoadMeshFromX(L"Optimus.x", D3DXMESH_MANAGED, g_pd3dDevice, 
        &pAdjBuffer, &pMtrlBuffer, NULL, &g_dwNumMtrls, &g_pMesh);
    // 读取材质和纹理数据
    D3DXMATERIAL *pMtrls = (D3DXMATERIAL*)pMtrlBuffer->GetBufferPointer();//创建一个D3DXMATERIAL结构体用于读取材质和纹理信息
    g_pMaterials = new D3DMATERIAL9[g_dwNumMtrls];
    g_pTextures  = new LPDIRECT3DTEXTURE9[g_dwNumMtrls];

    for (DWORD i=0; i<g_dwNumMtrls; i++) 
    {
        //获取材质,并设置一下环境光的颜色值
        g_pMaterials[i] = pMtrls[i].MatD3D;
        g_pMaterials[i].Ambient = g_pMaterials[i].Diffuse;
        //创建一下纹理对象
        g_pTextures[i]  = NULL;
        D3DXCreateTextureFromFileA(g_pd3dDevice, pMtrls[i].pTextureFilename, &g_pTextures[i]);
    }
    pAdjBuffer->Release();
    pMtrlBuffer->Release();



    // 设置渲染状态
    g_pd3dDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW);   //开启背面消隐
    g_pd3dDevice->SetRenderState(D3DRS_AMBIENT, D3DXCOLOR(1.0f, 1.0f, 1.0f, 1.0f)); //设置环境光
//第12步,设置四大变换
    Matrix_Set();//调用封装了四大变换的函数,对Direct3D世界变换,取景变换,投影变换,视口变换进行设置

    return S_OK;
}
//-----------------------------------【Matrix_Set( )函数】--------------------------------------
void Matrix_Set()
{
//第11步 世界变换矩阵的设置,改动到鼠标键盘操作后对世界变换矩阵修改

    //--------------------------------------------------------------------------------------
    //【四大变换之一】:世界变换矩阵的设置
    //--------------------------------------------------------------------------------------
/*
    D3DXMATRIX matWorld, Rx, Ry, Rz;
    D3DXMatrixIdentity(&matWorld);                  // 单位化世界矩阵
    D3DXMatrixRotationX(&Rx, D3DX_PI *(::timeGetTime() / 1000.0f));    // 绕X轴旋转
    D3DXMatrixRotationY(&Ry, D3DX_PI *( ::timeGetTime() / 1000.0f/2));    // 绕Y轴旋转
    D3DXMatrixRotationZ(&Rz, D3DX_PI *( ::timeGetTime() / 1000.0f/3));   // 绕Z轴旋转
    matWorld = Rx * Ry * Rz * matWorld;             // 得到最终的组合矩阵
    g_pd3dDevice->SetTransform(D3DTS_WORLD, &matWorld);  //设置世界变换矩阵
*/
    //--------------------------------------------------------------------------------------
    //【四大变换之二】:取景变换矩阵的设置
    //--------------------------------------------------------------------------------------
    D3DXMATRIX matView; //定义一个矩阵
    //第13步,设置摄像机位置修改
    //D3DXVECTOR3 vEye(0.0f, 0.0f, -250.0f);  //摄像机的位置
    D3DXVECTOR3 vEye(0.0f, 0.0f, -1300.0f);  //摄像机的位置
    D3DXVECTOR3 vAt(0.0f, 0.0f, 0.0f); //观察点的位置
    D3DXVECTOR3 vUp(0.0f, 1.0f, 0.0f);//向上的向量
    D3DXMatrixLookAtLH(&matView, &vEye, &vAt, &vUp); //计算出取景变换矩阵
    g_pd3dDevice->SetTransform(D3DTS_VIEW, &matView); //应用取景变换矩阵

    //--------------------------------------------------------------------------------------
    //【四大变换之三】:投影变换矩阵的设置
    //--------------------------------------------------------------------------------------
    D3DXMATRIX matProj; //定义一个矩阵
    D3DXMatrixPerspectiveFovLH(&matProj, D3DX_PI / 
    //第13步,设置摄像机位置修改
4.0f,(float)((double)WINDOW_WIDTH/WINDOW_HEIGHT),1.0f,10000.0f);// 1000.0f); //计算投影变换矩阵
    g_pd3dDevice->SetTransform(D3DTS_PROJECTION, &matProj);  //设置投影变换矩阵

    //--------------------------------------------------------------------------------------
    //【四大变换之四】:视口变换的设置
    //--------------------------------------------------------------------------------------
    D3DVIEWPORT9 vp; //实例化一个D3DVIEWPORT9结构体,然后做填空题给各个参数赋值就可以了
    vp.X      = 0;        //表示视口相对于窗口的X坐标
    vp.Y      = 0;        //视口相对对窗口的Y坐标
    vp.Width  = WINDOW_WIDTH;    //视口的宽度
    vp.Height = WINDOW_HEIGHT; //视口的高度
    vp.MinZ   = 0.0f; //视口在深度缓存中的最小深度值
    vp.MaxZ   = 1.0f;    //视口在深度缓存中的最大深度值
    g_pd3dDevice->SetViewport(&vp); //视口的设置
}
//第12步 Direct3D_Update( )函数
//-----------------------------------【Direct3D_Update( )函数】--------------------------------
//    描述:不是即时渲染代码但是需要即时调用的,如按键后的坐标的更改,都放在这里
//--------------------------------------------------------------------------------------------------
void    Direct3D_Update( HWND hwnd)
{
    //第14步,使用DirectInput类读取数据
    //// 获取键盘消息并给予设置相应的填充模式  
    //if (g_pKeyStateBuffer[DIK_1]    & 0x80)         // 若数字键1被按下,进行实体填充  
    //    g_pd3dDevice->SetRenderState(D3DRS_FILLMODE,D3DFILL_SOLID);
    //if (g_pKeyStateBuffer[DIK_2]    & 0x80)         // 若数字键2被按下,进行线框填充  
    //    g_pd3dDevice->SetRenderState(D3DRS_FILLMODE,D3DFILL_WIREFRAME);  

    //// 读取鼠标输入
    //::ZeroMemory(&g_diMouseState, sizeof(g_diMouseState));
    //Device_Read(g_pMouseDevice, (LPVOID)&g_diMouseState, sizeof(g_diMouseState));

    //// 读取键盘输入
    //::ZeroMemory(g_pKeyStateBuffer, sizeof(g_pKeyStateBuffer));
    //Device_Read(g_pKeyboardDevice, (LPVOID)g_pKeyStateBuffer, sizeof(g_pKeyStateBuffer));
        g_pDInput->GetInput();


    // 按住鼠标左键并拖动,为平移操作
    //第15步 修改相关参数
    static FLOAT fPosX = 0.0f, fPosY = 0.0f, fPosZ = 0.0f;//fPosY = 30.0f, fPosZ = 0.0f;
    if (g_pDInput->IsMouseButtonDown(0))//(g_diMouseState.rgbButtons[0] & 0x80) 
    {
        fPosX += (g_pDInput->MouseDX())*  0.08f;//fPosX += g_diMouseState.lX *  0.08f;
        fPosY += (g_pDInput->MouseDY()) * -0.08f;//fPosY += g_diMouseState.lY * -0.08f;
    }

    //鼠标滚轮,为观察点收缩操作
    fPosZ +=(g_pDInput->MouseDZ())* 0.02f;// g_diMouseState.lZ * 0.02f;

    // 平移物体
    if (g_pDInput->IsKeyDown(DIK_A)) fPosX -= 0.005f;//(g_pKeyStateBuffer[DIK_A] & 0x80) fPosX -= 0.005f;
    if (g_pDInput->IsKeyDown(DIK_D)) fPosX += 0.005f;//(g_pKeyStateBuffer[DIK_D] & 0x80) fPosX += 0.005f;
    if (g_pDInput->IsKeyDown(DIK_W)) fPosY += 0.005f;//(g_pKeyStateBuffer[DIK_W] & 0x80) fPosY += 0.005f;
    if (g_pDInput->IsKeyDown(DIK_S)) fPosY -= 0.005f;//(g_pKeyStateBuffer[DIK_S] & 0x80) fPosY -= 0.005f;


    D3DXMatrixTranslation(&g_matWorld, fPosX, fPosY, fPosZ);


    // 按住鼠标右键并拖动,为旋转操作
    static float fAngleX = 0.0f, fAngleY =0.0f;//fAngleX = 0.15f, fAngleY = -(float)D3DX_PI ;
    if (g_pDInput->IsMouseButtonDown(1)) //(g_diMouseState.rgbButtons[1] & 0x80) 
    {
        fAngleX += (g_pDInput->MouseDY())* -0.01f;//fAngleX += g_diMouseState.lY * -0.01f;
        fAngleY += (g_pDInput->MouseDX()) * -0.01f;//fAngleY += g_diMouseState.lX * -0.01f;
    }
    // 旋转物体
    if (g_pDInput->IsKeyDown(DIK_UP)) fAngleX += 0.005f;//if (g_pKeyStateBuffer[DIK_UP]    & 0x80) fAngleX += 0.005f;
    if (g_pDInput->IsKeyDown(DIK_DOWN)) fAngleX -= 0.005f;//if (g_pKeyStateBuffer[DIK_DOWN]  & 0x80) fAngleX -= 0.005f;
    if (g_pDInput->IsKeyDown(DIK_LEFT)) fAngleY -= 0.005f;//if (g_pKeyStateBuffer[DIK_LEFT]  & 0x80) fAngleY -= 0.005f;
    if (g_pDInput->IsKeyDown(DIK_RIGHT)) fAngleY += 0.005f;//if (g_pKeyStateBuffer[DIK_RIGHT] & 0x80) fAngleY += 0.005f;


    D3DXMATRIX Rx, Ry;
    D3DXMatrixRotationX(&Rx, fAngleX);
    D3DXMatrixRotationY(&Ry, fAngleY);

    //得到最终的矩阵并设置
    g_matWorld = Rx * Ry * g_matWorld;//得到最终的矩阵
    g_pd3dDevice->SetTransform(D3DTS_WORLD, &g_matWorld);//设置世界矩阵
    //第16 注销此项
    //Matrix_Set();
}

//-----------------------------------【Direct3D_Render( )函数】--------------------------------------
void Direct3D_Render(HWND hwnd)
{//1
//第17步,修改背景参数
    g_pd3dDevice->Clear(0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(100, 100, 100), 1.0f, 0);//D3DCOLOR_XRGB(150, 150, 100), 1.0f, 0);
    RECT formatRect;
    GetClientRect(hwnd, &formatRect);
    //2
    g_pd3dDevice->BeginScene();   
    //3

    for (DWORD i = 0; i < g_dwNumMtrls; i++)
            {
                g_pd3dDevice->SetMaterial(&g_pMaterials[i]);
                g_pd3dDevice->SetTexture(0, g_pTextures[i]);
                g_pMesh->DrawSubset(i);
            }

            int charCount = swprintf_s(g_strFPS, 20, _T("FPS:%0.3f"), Get_FPS() );
            g_pTextFPS->DrawText(NULL, g_strFPS, charCount , &formatRect, DT_TOP | DT_RIGHT, D3DCOLOR_RGBA(0,239,136,255));
    
            g_pTextAdaperName->DrawText(NULL,g_strAdapterName, -1, &formatRect, 
                DT_TOP | DT_LEFT, D3DXCOLOR(1.0f, 0.5f, 0.0f, 1.0f));

            formatRect.top = 30;
            static wchar_t strInfo[256] = {0};
            swprintf_s(strInfo,-1, L"模型坐标: (%.2f, %.2f, %.2f)", g_matWorld._41, g_matWorld._42, g_matWorld._43);
            g_pTextHelper->DrawText(NULL, strInfo, -1, &formatRect, DT_SINGLELINE | DT_NOCLIP | DT_LEFT, D3DCOLOR_RGBA(135,239,136,255));



            formatRect.left = 0,formatRect.top = 380;
            g_pTextInfor->DrawText(NULL, L"控制说明:", -1, &formatRect, 
                DT_SINGLELINE | DT_NOCLIP | DT_LEFT, D3DCOLOR_RGBA(235,123,230,255));
            formatRect.top += 35;
            g_pTextHelper->DrawText(NULL, L"    按住鼠标左键并拖动:平移模型", -1, &formatRect, 
                DT_SINGLELINE | DT_NOCLIP | DT_LEFT, D3DCOLOR_RGBA(255,200,0,255));
            formatRect.top += 25;
            g_pTextHelper->DrawText(NULL, L"    按住鼠标右键并拖动:旋转模型", -1, &formatRect, 
                DT_SINGLELINE | DT_NOCLIP | DT_LEFT, D3DCOLOR_RGBA(255,200,0,255));
            formatRect.top += 25;
            g_pTextHelper->DrawText(NULL, L"    滑动鼠标滚轮:拉伸模型", -1, &formatRect, 
                DT_SINGLELINE | DT_NOCLIP | DT_LEFT, D3DCOLOR_RGBA(255,200,0,255));
            formatRect.top += 25;
            g_pTextHelper->DrawText(NULL, L"    W、S、A、D键:平移模型 ", -1, &formatRect, 
                DT_SINGLELINE | DT_NOCLIP | DT_LEFT, D3DCOLOR_RGBA(255,200,0,255));
            formatRect.top += 25;
            g_pTextHelper->DrawText(NULL, L"    上、下、左、右方向键:旋转模型 ", -1, &formatRect, 
                DT_SINGLELINE | DT_NOCLIP | DT_LEFT, D3DCOLOR_RGBA(255,200,0,255));
            formatRect.top += 25;
            g_pTextHelper->DrawText(NULL, L"    ESC键 : 退出程序", -1, &formatRect, 
                DT_SINGLELINE | DT_NOCLIP | DT_LEFT, D3DCOLOR_RGBA(255,200,0,255));
    //4
    g_pd3dDevice->EndScene(); 
    //5
    g_pd3dDevice->Present(NULL, NULL, NULL, NULL); 
}




//-----------------------------------【Get_FPS( )函数】------------------------------------------
float    Get_FPS()
{
    static float  fps = 0;//fps值
    static int     frameCount = 0;//帧数
    static float  currentTime =0.0f;//当前时间
    static float  lastTime = 0.0f;//持续时间

    frameCount++;
    currentTime=timeGetTime()*0.001f;//获取系统时间

    if(currentTime-lastTime>1.0f)
    {
        fps = (float)frameCount /(currentTime - lastTime);
        lastTime=currentTime;
        frameCount=0;

    }
    return fps;

}
//第18步 注销Device_Read( )函数
//-----------------------------------【Device_Read( )函数】------------------------------------
// Desc: 智能读取设备的输入数据
//--------------------------------------------------------------------------------------------------
//BOOL Device_Read(IDirectInputDevice8 *pDIDevice, void* pBuffer, long lSize) 
//{
//    HRESULT hr;
//    while (true) 
//    {
//        pDIDevice->Poll();              // 轮询设备
//        pDIDevice->Acquire();           // 获取设备的控制权
//        if (SUCCEEDED(hr = pDIDevice->GetDeviceState(lSize, pBuffer))) break;
//        if (hr != DIERR_INPUTLOST || hr != DIERR_NOTACQUIRED) return FALSE;
//        if (FAILED(pDIDevice->Acquire())) return FALSE;
//    }
//    return TRUE;
//}

//-----------------------------------【Direct3D_CleanUp( )函数】--------------------------------
void Direct3D_CleanUp()
{
    //释放COM接口对象
//第19步 注释掉
    //g_pMouseDevice->Unacquire();
    //g_pKeyboardDevice->Unacquire();
    //for (DWORD i = 0; i<g_dwNumMtrls; i++) 
    //    SAFE_RELEASE(g_pTextures[i]);
    //SAFE_DELETE(g_pTextures)
    //SAFE_DELETE(g_pMaterials)
    //SAFE_RELEASE(g_pMesh)
    //SAFE_RELEASE(g_pTextFPS)
    //SAFE_RELEASE(g_pd3dDevice)    
    //SAFE_RELEASE(g_pMouseDevice)
    //SAFE_RELEASE(g_pKeyboardDevice)
        //释放COM接口对象
    SAFE_RELEASE(g_pTextAdaperName)
    SAFE_RELEASE(g_pTextHelper)
    SAFE_RELEASE(g_pTextInfor)
    SAFE_RELEASE(g_pTextFPS)
    SAFE_RELEASE(g_pd3dDevice)
}
View Code
复制代码

 

posted @   szmtjs10  阅读(153)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· .NET10 - 预览版1新功能体验(一)
点击右上角即可分享
微信分享提示