一個簡單的物體旋轉代碼。 便於理解世界矩陣,視圖矩陣以及投影矩陣的意思。目前只有世界矩陣的用法。
#include "stdafx.h" #include < d3dx9.h > #include < Mmsystem.h > LPDIRECT3D9 g_pD3D = NULL; LPDIRECT3DDEVICE9 g_pD3DDevice = NULL; LPDIRECT3DVERTEXBUFFER9 g_pVertexBuffer = NULL; struct CUSTOMVERTEX { FLOAT x, y, z; DWORD color; }; #define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ | D3DFVF_DIFFUSE) #define SafeRelease(pObject) / if (pObject != NULL) {/ pObject->Release(); / pObject = NULL; / } HRESULT InitializeD3D(HWND hWnd) { g_pD3D = Direct3DCreate9(D3D_SDK_VERSION); if (g_pD3D == NULL) { return E_FAIL; } D3DDISPLAYMODE d3ddm; if (FAILED( g_pD3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &d3ddm))) { return E_FAIL; } D3DPRESENT_PARAMETERS d3dpp; ZeroMemory(&d3dpp, sizeof(d3dpp)); d3dpp.Windowed = TRUE; d3dpp.SwapEffect = D3DSWAPEFFECT_COPY; d3dpp.BackBufferFormat = d3ddm.Format; if (FAILED(g_pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &g_pD3DDevice))) { return E_FAIL; } // set cullmode use anti-circle-way g_pD3DDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW); g_pD3DDevice->SetRenderState(D3DRS_LIGHTING, FALSE); return S_OK; } HRESULT InitialiseVertexBuffer() { VOID* pVertex; CUSTOMVERTEX cvVertex[] = { //Top Face {-5.0f, 5.0f, -5.0f, D3DCOLOR_XRGB(0, 0, 255),}, //Vertex 0 - Blue {-5.0f, 5.0f, 5.0f, D3DCOLOR_XRGB(255, 0, 0),}, //Vertex 1 - Red {5.0f, 5.0f, -5.0f, D3DCOLOR_XRGB(255, 0, 0),}, //Vertex 2 - Red {5.0f, 5.0f, 5.0f, D3DCOLOR_XRGB(0, 255, 0),}, //Vertex 3 - Green //Face 1 {-5.0f, -5.0f, -5.0f, D3DCOLOR_XRGB(255, 0, 0),}, //Vertex 4 - Red {-5.0f, 5.0f, -5.0f, D3DCOLOR_XRGB(0, 0, 255),}, //Vertex 5 - Blue {5.0f, -5.0f, -5.0f, D3DCOLOR_XRGB(0, 255, 0),}, //Vertex 6 - Green {5.0f, 5.0f, -5.0f, D3DCOLOR_XRGB(255, 0, 0),}, //Vertex 7 - Red //Face 2 {5.0f, -5.0f, 5.0f, D3DCOLOR_XRGB(0, 0, 255),}, //Vertex 8 - Blue {5.0f, 5.0f, 5.0f, D3DCOLOR_XRGB(0, 255, 0),}, //Vertex 9 - Green //Face 3 {-5.0f, -5.0f, 5.0f, D3DCOLOR_XRGB(0, 255, 0),}, //Vertex 10 - Green {-5.0f, 5.0f, 5.0f, D3DCOLOR_XRGB(255, 0, 0),}, //Vertex 11 - Red //Face 4 {-5.0f, -5.0f, -5.0f, D3DCOLOR_XRGB(255, 0, 0),}, //Vertex 12 - Red {-5.0f, 5.0f, -5.0f, D3DCOLOR_XRGB(0, 0, 255),}, //Vertex 13 - Blue //Bottom Face {5.0f, -5.0f, -5.0f, D3DCOLOR_XRGB(0, 255, 0),}, //Vertex 14 - Green {5.0f, -5.0f, 5.0f, D3DCOLOR_XRGB(0, 0, 255),}, //Vertex 15 - Blue {-5.0f, -5.0f, -5.0f, D3DCOLOR_XRGB(255, 0, 0),}, //Vertex 16 - Red {-5.0f, -5.0f, 5.0f, D3DCOLOR_XRGB(0, 255, 0),}, //Vertex 17 - Green {10.0f, 10.0f, 0.0f, D3DCOLOR_XRGB(0, 0, 255),}, //Vertex 1 - Blue {15.0f, 10.0f, 0.0f, D3DCOLOR_XRGB(255, 0, 0),}, //Vertex 2 - Red {10.0f, 15.0f, 0.0f, D3DCOLOR_XRGB(0, 255, 0),}, //Vertex 3 - Green {10.0f, 10.0f, 5.0f, D3DCOLOR_XRGB(0, 255, 0),}, //Vertex 4 - Green {10.0f, 10.0f, 0.0f, D3DCOLOR_XRGB(0, 0, 255),}, //Vertex 1 - Blue {15.0f, 10.0f, 0.0f, D3DCOLOR_XRGB(255, 0, 0),}, //Vertex 2 - Red }; if (FAILED(g_pD3DDevice->CreateVertexBuffer(sizeof(cvVertex), 0, D3DFVF_CUSTOMVERTEX, D3DPOOL_DEFAULT, &g_pVertexBuffer, NULL))) { return E_FAIL; } if (FAILED(g_pVertexBuffer->Lock(0, sizeof(cvVertex), (void**)&pVertex, 0))) { return E_FAIL; } memcpy(pVertex, cvVertex, sizeof(cvVertex)); g_pVertexBuffer->Unlock(); return S_OK; } void SetupRotation() { //Here we will rotate our world around the x, y and z axis. D3DXMATRIX matWorld, matWorldX, matWorldY, matWorldZ; //Create the transformation matrices D3DXMatrixRotationX(&matWorldX, timeGetTime()/400.0f); D3DXMatrixRotationY(&matWorldY, timeGetTime()/400.0f); D3DXMatrixRotationZ(&matWorldZ, timeGetTime()/400.0f); //Combine the transformations by multiplying them together D3DXMatrixMultiply(&matWorld, &matWorldX, &matWorldY); D3DXMatrixMultiply(&matWorld, &matWorld, &matWorldZ); //Apply the tansformation g_pD3DDevice->SetTransform(D3DTS_WORLD, &matWorld); } void SetupCamera() { //Here we will setup the camera. //The camera has three settings: "Camera Position", "Look at Position" and //"Up Direction" //We have set the following: //Camera Position: (0, 0, -30) //Look at Position: (0, 0, 0) //Up direction: Y-Axis. D3DXMATRIX matView; D3DXMatrixLookAtLH(&matView, &D3DXVECTOR3(0.0f, 0.0f,-100.0f), //Camera Position &D3DXVECTOR3(0.0f, 0.0f, 0.0f), //Look At Position &D3DXVECTOR3(0.0f, 1.0f, 0.0f)); //Up Direction g_pD3DDevice->SetTransform(D3DTS_VIEW, &matView); } void SetupPerspective() { //Here we specify the field of view, aspect ration and near and //far clipping planes. D3DXMATRIX matProj; D3DXMatrixPerspectiveFovLH(&matProj, D3DX_PI/4, 1.0f, 1.0f, 500.0f); g_pD3DDevice->SetTransform(D3DTS_PROJECTION, &matProj); } void Render() { if (g_pD3DDevice == NULL) { return; } // background color g_pD3DDevice->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0); g_pD3DDevice->BeginScene(); //SetupRotation(); SetupCamera(); SetupPerspective(); g_pD3DDevice->SetStreamSource(0, g_pVertexBuffer, 0, sizeof(CUSTOMVERTEX)); g_pD3DDevice->SetFVF(D3DFVF_CUSTOMVERTEX); D3DXMATRIX matWorld, matWorldTranLeft10, matWorldTranRight10, matWorldX, matWorldZ; //Create the transformation matrices D3DXMatrixRotationX(&matWorldX, timeGetTime()/400.0f); D3DXMatrixRotationY(&matWorldZ, timeGetTime()/400.0f); D3DXMatrixTranslation(&matWorldTranLeft10, -10, 0, 0); D3DXMatrixTranslation(&matWorldTranRight10, 10, 0, 0); D3DXMatrixMultiply(&matWorld, &matWorldTranLeft10, &matWorldZ); D3DXMatrixMultiply(&matWorld, &matWorld, &matWorldTranRight10); g_pD3DDevice->SetTransform(D3DTS_WORLD, &matWorldX); g_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2); g_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, 4, 8); g_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, 14, 2); g_pD3DDevice->SetTransform(D3DTS_WORLD, &matWorld); g_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, 18, 4); g_pD3DDevice->EndScene(); g_pD3DDevice->Present(NULL, NULL, NULL, NULL); } void CleanUp() { SafeRelease(g_pVertexBuffer); SafeRelease(g_pD3DDevice); SafeRelease(g_pD3D); } void GameLoop() { MSG msg; BOOL fMessage; PeekMessage(&msg, NULL, 0U, 0U, PM_NOREMOVE); while(msg.message != WM_QUIT) { fMessage = PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE); if (fMessage) { TranslateMessage(&msg); DispatchMessage(&msg); }else { Render(); } } } LRESULT WINAPI WinProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { switch(msg) { case WM_DESTROY: PostQuitMessage(0); return 0; break; case WM_KEYUP: switch(wParam) { case VK_ESCAPE: DestroyWindow(hWnd); return 0; break; } break; default: break; } return DefWindowProc(hWnd, msg, wParam, lParam); } INT WINAPI WinMain(HINSTANCE hInst, HINSTANCE , LPSTR , int ) { WNDCLASSEX wc = {sizeof(WNDCLASSEX), CS_CLASSDC, WinProc, 0L, 0L, GetModuleHandle(NULL), NULL, NULL, NULL, NULL, "DX Project 1", NULL}; RegisterClassEx(&wc); HWND hWnd = CreateWindow("DX Project 1", "www.andypike.com: Tutorial 1", WS_OVERLAPPEDWINDOW, 50, 50, 500, 500, GetDesktopWindow(), NULL, wc.hInstance, NULL); if(SUCCEEDED(InitializeD3D(hWnd))) { //Show our window ShowWindow(hWnd, SW_SHOWDEFAULT); UpdateWindow(hWnd); //Start game running: Enter the game loop if (SUCCEEDED(InitialiseVertexBuffer())) { GameLoop(); } } CleanUp(); UnregisterClass("DX Project 1", wc.hInstance); return 0; }