用MFC构造DirectX应用框架

MFC类库DirectX SDK

Microsoft DirectX SD是开发基于 Windows 平台游戏的一个软件开发工具,其功能主要包括在五个组件中 :DirectDraw DirectSound DirectPlay Direct3D和DirectInput,每个组件都具不中的功能:

DirectDraw使用直接写存技术加快游戏的动画速度;

DirectSound控制游戏声音的合成和播放;

DirectPlay使游戏具有网络多人游戏功能;

Direct3D让程序员更方便地开发三维游戏;

DirectInput使游戏支持更多的办入设备(现在只支持游戏杆,鼠标和键盘)。

可以说DirectX SDK提供了编写一个游戏 所必须的功能及基层函数,所以大多Windows游戏都使用了DirectX SDK.

MFC(Microsoft Foundation Class)类库是Microsoft Visual C++中提供的一个功能强大的 Windows 应用程序开发类, 使用这些类我们可以避免和繁琐的Windows API打交道,而且在 Visual C++中我们还可以利用ClassWizard 对MFC 类进行Windows 消息映射,所以如果能用MFC 类库来开发DirectX SDK的应用程序,至少有以下几个好处:

可以用VC++的ClassWizard方便地对Windows消息进行映射;

增加了程序的可读性,并且可以用VC++的 ClassView方便的管理所用的类;

增加程序代码的可重用性, 可以在原有的基础上开发出功能更强大的应用程序;

更进一步,如果我们能开发出一个能生成DirectX SDK应用程序基本框架的VC++的工程向导,则为以后开发DirectX SDK应用于程序提供及大的方便。下面,我们将用Visual C++先编写一个DirectX SDK应用程序的基本框架。

二 编写 DirectX SDK 应用程序基本框架

我们按下列步骤建立一个DirectX SDK 程序的基本框架:

1 用Visual C ++的MFC App Wizard (EXE) 生成一个基本对话框的工程文件,取名为DirectX,在向导第二步时取消About Box 的复选框,然后按Finish按钮。

2 删除在DirectX 工程目录中生成的DirectXDlg.H两个文件,并在Visual C++的File View中删除以上两个文件,按CTRL+W启动ClassWizard删除CdirectXDlg类,然后在ResourseView中删除 IDD_DIRECTX_DIALOG.

3 建立两个文件DirectXWnd.H(这两个文件在本文的附录中,请注意不要删除有“//{”和“//}”之间的内容,否则将不能使用 ClassWizard对窗口信息进行映射),并把它们加入到工程中。这时工程中将加入一个基于CWnd的CdirectXWnd类,这是我们的 DirectX应用程序的基类。CdirectXWnd类创建一个窗口并生成一个与该窗口相关联的DirectDraw对象lpDD,同时还生成一个显示 平面(lpFrontBuffer)和一个显示缓冲平面(lpBackBuffer),该类使用了几个虚函数,必要时其派生类可以覆盖这些函数。

4 打开DirectX.CPP,把 # include”DirectXDLG.h”改为 #include “DirectXWnd.H”然后把CdirectXApp::InitInstance()函数修改如下,其中黑体字为要增加的内容:

BOOL CdirectXApp::initlnstance()

{

#ifdef_AFXDLL

Enable3dControls();//Call this when using MFC in a shared DLL

#else

Enable3dConteolsStatic();//Call this when linking to MFC

Statically

#endif

CdirectXWnd *pWnd =new CdirectXWnd();

PWnd->Create(“DirectXWnd Test”);

m-pMainWnd =pWnd;

pWnd->UpdateWindow();

pWnd->SetFocus();

if (pWnd->initializeGame(640,480,8)= =FALSE){

pWnd->DestroyWindow();

return FALSE;

}

MSG msg;

White(1)

{

if(PeekMessage(&msg,NULL,0,0,PM-NOREMOVE)) {

if( !GetMessage(&msg,NULL,0,0))

return msg.wParam;

TranslateMessage(&msg);

DispatchMessage(&msg);

}

else{

if (pWnd->blsActive) {

pWnd-> UpdateFrame();

}

}

}

return TURE;

}

编译该程序并运行,可以看到出现一个黑色的屏幕窗口,按ESC或F12则可退出程序。至此我们的基本框架已经建立好了,虽然这个框架还比较简单,但我们可 以在此基础上开发出更强大的应用框架。为了方便使用该框架,我们可以为该框架写一个Custom App Wizard,当然也可以不写,只要把该工程目录下的文件拷贝到另一个工程目录中即可。

三 测试框架

现在,我们按下列步骤写一个程序来测试这个框架:

1 把刚才创建的工程框架拷贝到一个新目录下,并打开。用Class View 创建一个基于CWnd的类CtestWnd,然后把CtestWnd.h和CtestWnd.CPP文件中的所有“CWnd”字符串替换为 “CdirectXWnd”,并在CtestWnd.h文件头加入下列字符串:#include “DirectXWnd.h”.

2 打开DirectX.CPP文件,在文件头加入# include “TestWnd.h”,并把该文件中的所有”CdirectXWnd”字符串替换成”CtestWnd”并保存。

3 为CtestWnd类增加一个虚函数UpdateFrame(),这个函数覆盖了其基类CdirectXWnd的UpdateFrame():

void CtestWnd :: UpdateFrame()

{

staic int x= 0, dx =5;

staic int y =0, dy =5;

HDC hdc;

DDBL TFX ddbltfx;

HRESULT ddrval;

UpdateWindow();

Ddbltfx.swSize = sizedof(ddbltfx);

Ddbltfx.dwFillColor = 0;

Ddrval = lpBackBuffer ->Blt(

NULL ,//dest rect

NULL,//src surface

NULL,// src rect

DDBLT_COLORFILL |DDBLT_WA99v,

&ddbltfx);

if (ddrval ! = DD_OK)

{

msg(“ Fill failed ddrval =0x%081x”,ddrval);

return;

}

if (lpBackBuffer ->GetDC(&hdc) = =DD- OK)

{

if(x<0) dx=5;

if(x>590) dx= -5;

if (y<0) dy =5;

if ( y>430) dy = -5;

x += dx ; y + =dy;

Ellipse( hdc ,x,y,x+50,y+50);

LpBackBuffer ->ReleaseDC(hdc);

}

while(1)

{

HRESULT ddrval;

ddrva =lp FrontBuffer->Flip(NULL,0);

if( ddrval = =DD_ OK)

{break;}

if (ddravl= =DDERR_SURFACELOST)

{

if(!CdirectXWnd::RestoreSurfaces())

{

break;

}

}

if (ddravl !=DDERR_WASSTILLDRAWING)

{

break;

}

}

}
4:编译并运行程序,屏幕上会出现一个白色球在移动

附录:

文件DirectXWnd.h

#if !defined(DIRECTXWND-H)

#define DIRECTXWND_H

//DirectXWnd.h:header file

#include<ddraw.h>

#pragma comment (lib,“ddraw。Lib”)//链接时加入ddraw.lib库

class CdirectXWnd: public CWnd

{

//Construction

public:

CDirectXWnd();

//Attributes

public:

BOOL blsActive; //应用程序是否激活

protected:

LPDERECTDRAW lpDD; //DirectDraw对象指针

LPDERECTDRAWSURFACE lpFrontBuffer;//DirectDraw主缓冲区

LPDERECTDRAWSURFACE lpBacdBuffer;//DirectDraw后备缓冲区

int nBufferCount; //后备缓冲区个数

//Operations

protected:

void Msg(LPSTR fmt,...);

public:

BOOL Create(LPCSTR lpszAppName); //创建窗体

//Overrides

virtual BOOL InitializeGame(UINT Gmodex,UINT GmodeY,UINT GBPP);

virtual BOOL CleanSurface();

virtual void UpdateFrame();

virtual BOOL RestoreSurfaces(void);

//{{AFX-VIRTUAL(CdirectXWnd)

//}}AFX_VIRTUAL

//Implementation

public:

virtual~CdirectXWnd();

//Generated message map functions

protected:

//{{AFX-MSG(CderectXWnd)

afx-msg

posted @ 2013-03-21 22:39  顶顶顶顶  阅读(436)  评论(0)    收藏  举报