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 }
第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 }
第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 }
第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
//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 };
//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 }
//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 }
//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) }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· .NET10 - 预览版1新功能体验(一)