第一章 MFC框架
(DX8MFC)
這裡的MFC框架指的是一個符合游戲開發應用的框架,當然你也可以寫一個符合你要求的MFC框架。如果你對MFC比較熟悉的話可以直接從第二章開始閱讀。本框架是以後幾個例子的基礎,如果你對MFC不是很了解的話,就要認真閱讀本章,以求對這個MFC框架有一個深入的了解。
框架中包括兩個類:
CDX8MFCApp類和CFrameWin類,CDX8MFCApp類是應用程序類,CFrameWin類是框架的主類,以後我們的大部分代碼都是從這裡擴展的。首先來看一看CDX8MFCApp類,它包括CDX8MFCApp()、ExitInstance()、InitInstance()、OnIdle(LONG lCount)等成員函數和一個Game對象。
InitInstance()成員函數在程序初始化時就被調用,在這裡我建立了一個窗口:
BOOL CDX8MFCApp::InitInstance() { // The one and only window has been initialized, so show and update it. m_pMainWnd = new CFrameWin(); m_pMainWnd->ShowWindow(m_nCmdShow); m_pMainWnd->UpdateWindow(); Game = (CFrameWin*) m_pMainWnd; Game->Init(); return TRUE; }
ExitInstance()成員函數在程序終止時被調用,在這裡我們釋放一些對象和指針:
int CDX8MFCApp::ExitInstance() { // TODO: Add your specialized code here and/or call the base class Game->End(); delete Game; return CWinApp::ExitInstance(); }
OnIdle(LONG lCount)成員函數會在沒有Windows消息要處理的時候被調用,也就是說OnIdle()成員函數會不斷的被調用,這正好被我們用作游戲循環。
BOOL CDX8MFCApp::OnIdle(LONG lCount) { // TODO: Add your specialized code here and/or call the base class if(Game->window_active==TRUE) { Game->Active(); Game->window_active=FALSE; } Game->Go(); return TRUE; }
Game對象是一個CFrameWin類指針,我們在InitInstance()成員函數中創建了一個CFrameWin對象並把CFrameWin對象的指針值賦給Game。
下面我們來看一看CFrameWin類,它包括Active()、End()、Go()、Init()、Update()等成員函數。
Init()成員函數,你可以在這裡做一些自己的初始化。回顧CDX8MFCApp類的InitInstance()成員函數可知,在完成窗口初始化後InitInstance()成員函數裡就調用了Game->Init(),也就是說Init()在窗口初始化後被調用。
void CFrameWin::Init() { AfxMessageBox("Init"); }
Go()成員函數會不斷的被循環調用,它又調用了Update()和DestroyWindow()。Update()用於更新窗口,調用DestroyWindow()則會結束應用程序。如果你把DestroyWindow()語句刪除掉,程序會不斷的循環。
void CFrameWin::Go() //Game循環 { AfxMessageBox("Go"); Update(); DestroyWindow(); } Active()成員函數會在應用程序被擊活的時候被調用。 void CFrameWin::Active() //窗口被激活 { TRACE("Active\n"); AfxMessageBox("Active"); }
這個程序並不做任何事,只是一個MFC框架。你可以從http://gamedev.363.net 下載例子的源程序,或通過E-mail: [email protected] 向本文作者索取。
第二章 初始化DirectX8
(DX8MFC1)
本例將以第一章的MFC框架為基礎對CFrameWin類進行擴展。主要加入了DrawScene()、InitDirect3D(HWND hwnd)和ShutdownDirect3D()三個函數。
InitDirect3D(HWND hwnd)函數對Direct3D進行初始化: HRESULT CFrameWin::InitDirect3D(HWND hwnd) { pID3D = Direct3DCreate8(D3D_SDK_VERSION); HRESULT hr; do { // we need the display mode so we can get // the properties of our back buffer D3DDISPLAYMODE d3ddm; hr = pID3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &d3ddm); if(FAILED(hr)) break; D3DPRESENT_PARAMETERS present; ZeroMemory(&present, sizeof(present)); present.SwapEffect = D3DSWAPEFFECT_COPY; present.Windowed = TRUE; present.BackBufferFormat = d3ddm.Format; hr = pID3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hwnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present, &pID3DDevice); if(FAILED(hr)) break; // we do our own coloring, so disable lighting hr = pID3DDevice->SetRenderState(D3DRS_LIGHTING, FALSE); } while(0); return hr; }