www.pudn.com > Direct3D_ZBuffer.zip > Direct3D.cpp
// // // #include#include #include LPDIRECT3D9 g_pD3D = NULL; LPDIRECT3DDEVICE9 g_pD3DDevice = NULL; LPDIRECT3DVERTEXBUFFER9 g_pVertexBuffer = NULL; // Buffer to hold vertices struct CUSTOMVERTEX { float x, y, z; // The transformed position for the vertex DWORD color; // The vertex colour }; #define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ | D3DFVF_DIFFUSE) #define SafeRelease(pObject) if(pObject != NULL){pObject->Release(); pObject = NULL;} const TCHAR g_szClassName[] = _T("Direct3D"); const TCHAR g_szWindowName[] = _T("Direct3D"); LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); HRESULT InitD3D(HWND hWnd); HRESULT InitVertexBuffer(void); void Render(void); void Cleanup(void); void GameLoop(void); void SetupRotation(void); void SetupCamera(void); void SetupPerspective(void); //Application entry point int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd) { WNDCLASSEX wc; wc.cbClsExtra = 0; wc.cbSize = sizeof(WNDCLASSEX); wc.cbWndExtra = 0; wc.hbrBackground= NULL; wc.hCursor = NULL; wc.hIcon = NULL; wc.hIconSm = NULL; wc.hInstance = hInstance; wc.lpfnWndProc = WndProc; wc.lpszClassName= g_szClassName; wc.lpszMenuName = NULL; wc.style = CS_CLASSDC; // Register the window class if(!RegisterClassEx(&wc)) { MessageBox(NULL, _T("RegisterClass failed !"), _T("Warning"), MB_OK); } // Create the application's window HWND hWnd = CreateWindow(g_szClassName, g_szWindowName, WS_OVERLAPPEDWINDOW, 50, 50, 500, 500, GetDesktopWindow(), NULL, hInstance, NULL); //Initialize Direct3D if(SUCCEEDED(InitD3D(hWnd))) { // Show our window ShowWindow(hWnd, nShowCmd); UpdateWindow(hWnd); // Initialize Vertex Buffer if(SUCCEEDED(InitVertexBuffer())) { // Start game running: Enter the game loop GameLoop(); } } Cleanup(); UnregisterClass(g_szClassName, hInstance); return 0; } //The windows message handler LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { switch(message) { case WM_DESTROY: { PostQuitMessage(0); return 0; } break; case WM_KEYDOWN: { switch(wParam) { case VK_ESCAPE: { //User has pressed the escape key, so quit DestroyWindow(hWnd); return 0; } break; } } break; } return DefWindowProc(hWnd, message, wParam, lParam); } HRESULT InitD3D(HWND hWnd) { // First of all, create the main D3D object. If it is created successfully we // should get a pointer to an IDirect3D8 interface. g_pD3D = Direct3DCreate9(D3D_SDK_VERSION); if(g_pD3D == NULL) { return E_FAIL; } // Get the current display mode D3DDISPLAYMODE d3ddm; if(FAILED(g_pD3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &d3ddm))) { return E_FAIL; } // Create a structure to hold the settings for our device D3DPRESENT_PARAMETERS d3dpp; memset(&d3dpp, 0, sizeof(D3DPRESENT_PARAMETERS)); // Fill the structure. // We want our program to be windowed, and set the back buffer to a format // that matches our current display mode d3dpp.Windowed = TRUE; d3dpp.SwapEffect = D3DSWAPEFFECT_COPY; d3dpp.BackBufferFormat = d3ddm.Format; // Create a Direct3D device if(FAILED(g_pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &g_pD3DDevice))) { return E_FAIL; } // Turn on back face culling. // This is because we want to hide the back of our polygons g_pD3DDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW); // Turn off lighting because we are specifying that our vertices have colour g_pD3DDevice->SetRenderState(D3DRS_LIGHTING, FALSE); return S_OK; } HRESULT InitVertexBuffer() { // Store each point of the triangle together with it's colour CUSTOMVERTEX cvVertices[] = { // Top face {-5.0f, 5.0f, -5.0f, D3DCOLOR_XRGB(0,0,255)}, // Blue {-5.0f, 5.0f, 5.0f, D3DCOLOR_XRGB(255,0,0)}, // Red {5.0f, 5.0f, -5.0f, D3DCOLOR_XRGB(255,0,0)}, // Red {5.0f, 5.0f, 5.0f, D3DCOLOR_XRGB(0,0,255)}, // Green // Face 1 {-5.0f, -5.0f, -5.0f, D3DCOLOR_XRGB(255,0,0)}, // Red {-5.0f, 5.0f, -5.0f, D3DCOLOR_XRGB(0,0,255)}, // Blue {5.0f, -5.0f, -5.0f, D3DCOLOR_XRGB(0,255,0)}, // Green {5.0f, 5.0f, -5.0f, D3DCOLOR_XRGB(255,0,0)}, // Red // Face 2 {5.0f, -5.0f, 5.0f, D3DCOLOR_XRGB(0,0,255)}, // Blue {5.0f, 5.0f, 5.0f, D3DCOLOR_XRGB(0,0,255)}, // Green // Face 3 {-5.0f, -5.0f, 5.0f, D3DCOLOR_XRGB(0,0,255)}, // Green {-5.0f, 5.0f, 5.0f, D3DCOLOR_XRGB(255,0,0)}, // Red // Face 4 {-5.0f, -5.0f, -5.0f, D3DCOLOR_XRGB(255,0,0)}, // Red {-5.0f, 5.0f, -5.0f, D3DCOLOR_XRGB(0,0,255)}, // Blue // Bottom face {5.0f, -5.0f, -5.0f, D3DCOLOR_XRGB(0,255,0)}, // Green {5.0f, -5.0f, 5.0f, D3DCOLOR_XRGB(0,0,255)}, // Blue {-5.0f, -5.0f, -5.0f, D3DCOLOR_XRGB(255,0,0)}, // Red {-5.0f, -5.0f, 5.0f, D3DCOLOR_XRGB(0,0,255)}, // Green }; // Create the vertex buffer from our device if(FAILED(g_pD3DDevice->CreateVertexBuffer(18 * sizeof(CUSTOMVERTEX), 0, D3DFVF_CUSTOMVERTEX, D3DPOOL_DEFAULT, &g_pVertexBuffer, NULL))) { return E_FAIL; } // Get a pointer to the vertex buffer vertices and lock the vertex buffer void *pVertices; if(FAILED(g_pVertexBuffer->Lock(0, sizeof(cvVertices), (void **)&pVertices, 0))) { return E_FAIL; } // Copy our stored vertices values into the vertex buffer memcpy(pVertices, cvVertices, sizeof(cvVertices)); // Unlock the vertex buffer 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; D3DXVECTOR3 eye(0.0f, 0.0f, -30.0f); D3DXVECTOR3 lookat(0.0f, 0.0f, 0.0f); D3DXVECTOR3 up(0.0f, 1.0f, 0.0f); D3DXMatrixLookAtLH(&matView, &eye, &lookat, &up); 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; } // Clear the back buffer to a specified color g_pD3DDevice->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0); // Begin the scene g_pD3DDevice->BeginScene(); // Setup the rotation, camera, and perspective matrices SetupRotation(); SetupCamera(); SetupPerspective(); // Rendering our object g_pD3DDevice->SetStreamSource(0, g_pVertexBuffer, 0, sizeof(CUSTOMVERTEX)); //g_pD3DDevice->SetVertexShader(D3DFVF_CUSTOMVERTEX); g_pD3DDevice->SetFVF(D3DFVF_CUSTOMVERTEX); g_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2); g_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, 4, 8); g_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, 14, 2); // End the scene g_pD3DDevice->EndScene(); // Filp the back and front buffers so that whatever has been rendered on the // back buffer will now be visible on screen (front buffer) g_pD3DDevice->Present(NULL, NULL, NULL, NULL); } void Cleanup() { if(g_pVertexBuffer != NULL) { g_pVertexBuffer->Release(); g_pVertexBuffer = NULL; } if(g_pD3DDevice != NULL) { g_pD3DDevice->Release(); g_pD3DDevice = NULL; } if(g_pD3D != NULL) { g_pD3D->Release(); g_pD3D = NULL; } } void GameLoop() { // Enter the game loop MSG msg; BOOL fMessage; PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE); while(msg.message != WM_QUIT) { fMessage = PeekMessage(&msg, NULL, 0, 0, PM_REMOVE); if(fMessage) { // Process message TranslateMessage(&msg); DispatchMessage(&msg); } else { // No message to process, so render the current scene Render(); } } }