导言:一个黑屏程序,要调用这么多的函数,可见游戏编程的艰辛。
上次我们学了函数InitializeD3D()函数,现在我们的任务就是学习真正的渲染屏幕了。我们不妨用RenderScece()这个函数来承载这个功能。详细的过程我们可以参考《DirectX游戏开发终极指南》这本书。我只是想说说自己对于这个函数的理解。
RenderScene()这个函数的功能大概是这样的:
最后一定不要忘记四方自己所创建的所有对象。书上使用的是Shutdown()函数。这个函数将所有已创建的类都释放出来。我注意到,这些类首先被释放资源,然后将指针设置为NULL,至此,所有的任务就已经完成了。
以下是程序的主干框架。
下面是完整的代码。
- #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”程序终于完成了,是不是有些困难呢?以后我相信大家熟悉了后就不会觉得困难了。