導言:一個黑屏程式,要調用這麼多的函數,可見遊戲編程的艱辛。
上次我們學了函數InitializeD3D()函數,現在我們的任務就是學習真正的渲染螢幕了。我們不妨用RenderScece()這個函數來承載這個功能。詳細的過程我們可以參考《DirectX遊戲開發終極指南》這本書。我只是想說說自己對於這個函數的理解。
RenderScene()這個函數的功能大概是這樣的:
最後一定不要忘記四方自己所建立的所有對象。書上使用的是Shutdown()函數。這個函數將所有已建立的類都釋放出來。我注意到,這些類首先被釋放資源,然後將指標設定為NULL,至此,所有的任務就已經完成了。
以下是程式的主幹架構。
下面是完整的代碼。
Code:
- #include<d3d9.h>
-
- #pragma comment(lib, "d3d9.lib")//串連庫函數的
- #pragma comment(lib, "d3dx9.lib")//串連庫函數的
-
- #define WINDOW_CLASS "UGPDX"
- #define WINDOW_NAME "Blank D3D Window"
-
-
- // Function Prototypes...
- bool InitializeD3D(HWND hWnd, bool fullscreen);
- void RenderScene();
- void Shutdown();
-
-
- // Direct3D object and device.
- LPDIRECT3D9 g_D3D = NULL;
- LPDIRECT3DDEVICE9 g_D3DDevice = NULL;
-
-
- LRESULT WINAPI MsgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
- {
- switch(msg)
- {
- case WM_DESTROY:
- PostQuitMessage(0);
- return 0;
- break;
-
- case WM_KEYUP:
- if(wParam == VK_ESCAPE) PostQuitMessage(0);
- break;
- }
-
- return DefWindowProc(hWnd, msg, wParam, lParam);
- }
-
-
- int WINAPI WinMain(HINSTANCE hInst, HINSTANCE prevhInst, LPSTR cmdLine, int show)
- {
- // Register the window class
- WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_CLASSDC, MsgProc, 0L, 0L,
- GetModuleHandle(NULL), NULL, NULL, NULL, NULL,
- WINDOW_CLASS, NULL };
- RegisterClassEx(&wc);
-
- // Create the application's window
- HWND hWnd = CreateWindow(WINDOW_CLASS, WINDOW_NAME, WS_OVERLAPPEDWINDOW,
- 100, 100, 640, 480, GetDesktopWindow(), NULL,
- wc.hInstance, NULL);
-
- // Initialize Direct3D
- if(InitializeD3D(hWnd, false))
- {
- // Show the window
- ShowWindow(hWnd, SW_SHOWDEFAULT);
- UpdateWindow(hWnd);
-
- // Enter the message loop
- MSG msg;
- ZeroMemory(&msg, sizeof(msg));
-
- while(msg.message != WM_QUIT)
- {
- if(PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE))
- {
- TranslateMessage(&msg);
- DispatchMessage(&msg);
- }
- else
- RenderScene();
- }
- }
-
- // Release any and all resources.
- Shutdown();
-
- // Unregister our window.
- UnregisterClass(WINDOW_CLASS, wc.hInstance);
- return 0;
- }
-
-
- bool InitializeD3D(HWND hWnd, bool fullscreen)
- {
- D3DDISPLAYMODE displayMode;
-
- // Create the D3D object.
- g_D3D = Direct3DCreate9(D3D_SDK_VERSION);
- if(g_D3D == NULL) return false;
-
- // Get the desktop display mode.
- if(FAILED(g_D3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &displayMode)))
- return false;
-
- // Set up the structure used to create the D3DDevice
- D3DPRESENT_PARAMETERS d3dpp;
- ZeroMemory(&d3dpp, sizeof(d3dpp));
-
- if(fullscreen)
- {
- d3dpp.Windowed = FALSE;
- d3dpp.BackBufferWidth = 640;
- d3dpp.BackBufferHeight = 480;
- }
- else
- d3dpp.Windowed = TRUE;
- d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
- d3dpp.BackBufferFormat = displayMode.Format;
-
- // Create the D3DDevice
- if(FAILED(g_D3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd,
- D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &g_D3DDevice)))
- {
- return false;
- }
-
- return true;
- }
-
-
- void RenderScene()
- {
- // Clear the backbuffer.
- g_D3DDevice->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0,0,0), 1.0f, 0);
-
- // Begin the scene. Start rendering.
- g_D3DDevice->BeginScene();
-
- // End the scene. Stop rendering.
- g_D3DDevice->EndScene();
-
- // Display the scene.
- g_D3DDevice->Present(NULL, NULL, NULL, NULL);
- }
-
-
- void Shutdown()
- {
- if(g_D3DDevice != NULL) g_D3DDevice->Release();
- if(g_D3D != NULL) g_D3D->Release();
- }
要順利地運行程式,必須使用這些語句:
#pragma comment(lib, "d3d9.lib")
#pragma comment(lib, "d3dx9.lib")
當然,這些也可在VS2005中可以設定,即不用加語句,在VS2005,點“項目->屬性”開啟對話方塊,在左邊樹狀圖:配置屬性->連接器->輸入,在右邊附加依賴項中寫上要串連的庫檔案就行了。
至此這個“Black Window”程式終於完成了,是不是有些困難呢?以後我相信大家熟悉了後就不會覺得困難了。