📄 csdn_文档中心_mfc架构下的directx8.htm
字号:
<TABLE bgColor=#eeeeee border=0 cellPadding=0 cellSpacing=0 width=600>
<TBODY>
<TR bgColor=#ffffff>
<TD align=middle height=10 width=50></TD>
<TD align=right><A href="http://www.csdn.net/">CSDN</A> - <A
href="http://www.csdn.net/develop/">文档中心</A> - <FONT
color=#003399>Visual C++</FONT> </TD></TR>
<TR>
<TD align=middle height=5></TD>
<TD align=middle width=500></TD></TR>
<TR>
<TD align=middle bgColor=#003399 height=10><FONT
color=#ffffff>标题</FONT></TD>
<TD><B> MFC架构下的DirectX8</B> ghj1976(转贴)
</TD></TR>
<TR>
<TD align=middle height=5></TD>
<TD align=middle width=500></TD></TR>
<TR>
<TD align=middle bgColor=#003399><FONT color=#ffffff>关键字</FONT></TD>
<TD width=500> MFC架构下的DirectX8</TD></TR>
<TR>
<TD align=middle height=5></TD>
<TD align=middle width=500></TD></TR>
<TR>
<TD align=middle bgColor=#003399 height=10><FONT
color=#ffffff>出处</FONT></TD>
<TD height=10> <A
href="http://vg1.homeip.net/bbsgame/messages/396.shtml">http://vg1.homeip.net/bbsgame/messages/396.shtml</A></TD></TR>
<TR>
<TD align=middle height=10></TD>
<TD height=10></TD></TR></TBODY></TABLE><!--文章说明信息结束//-->
<TABLE border=0 width=600>
<TBODY>
<TR>
<TD align=left><BR>MFC架构下的DirectX8<BR>第一章
MFC框架<BR>(DX8MFC)<BR>这里的MFC框架指的是一个符合游戏开发应用的框架,当然你也可以写一个符合你要求的MFC框架。如果你对MFC比较熟悉的话可以直接从第二章开始阅读。本框架是以后几个例子的基础,如果你对MFC不是很了解的话,就要认真阅读本章,以求对这个MFC框架有一个深入的了解。<BR>框架中包括两个类:<BR>CDX8MFCApp类和CFrameWin类,CDX8MFCApp类是应用程序类,CFrameWin类是框架的主类,以后我们的大部分代码都是从这里扩展的。首先来看一看CDX8MFCApp类,它包括CDX8MFCApp()、ExitInstance()、InitInstance()、OnIdle(LONG
lCount)等成员函数和一个Game对象。<BR>InitInstance()成员函数在程序初始化时就被调用,在这里我建立了一个窗口:<BR>BOOL
CDX8MFCApp::InitInstance()<BR>{<BR>// The one and only window has
been initialized, so show and update it.<BR>m_pMainWnd = new
CFrameWin();<BR>
m_pMainWnd->ShowWindow(m_nCmdShow);<BR>
m_pMainWnd->UpdateWindow();<BR>Game = (CFrameWin*)
m_pMainWnd;<BR>Game->Init();
<P>return TRUE;<BR>}
<P>ExitInstance()成员函数在程序终止时被调用,在这里我们释放一些对象和指针:<BR>int
CDX8MFCApp::ExitInstance() <BR>{<BR>// TODO: Add your specialized
code here and/or call the base class<BR>Game->End();<BR>delete
Game;
<P>return CWinApp::ExitInstance();<BR>}
<P>OnIdle(LONG
lCount)成员函数会在没有Windows消息要处理的时候被调用,也就是说OnIdle()成员函数会不断的被调用,这正好被我们用作游戏循环。<BR>BOOL
CDX8MFCApp::OnIdle(LONG lCount) <BR>{<BR>// TODO: Add your
specialized code here and/or call the base
class<BR>if(Game->window_active==TRUE)<BR>{<BR>Game->Active();<BR>Game->window_active=FALSE;<BR>}
<P>Game->Go();
<P>return TRUE;<BR>}
<P>Game对象是一个CFrameWin类指针,我们在InitInstance()成员函数中创建了一个CFrameWin对象并把CFrameWin对象的指针值赋给Game。<BR>下面我们来看一看CFrameWin类,它包括Active()、End()、Go()、Init()、Update()等成员函数。<BR>Init()成员函数,你可以在这里做一些自己的初始化。回顾CDX8MFCApp类的InitInstance()成员函数可知,在完成窗口初始化后InitInstance()成员函数里就调用了Game->Init(),也就是说Init()在窗口初始化后被调用。<BR>void
CFrameWin::Init()<BR>{<BR>AfxMessageBox("Init");<BR>}
<P>Go()成员函数会不断的被循环调用,它又调用了Update()和DestroyWindow()。Update()用于更新窗口,调用DestroyWindow()则会结束应用程序。如果你把DestroyWindow()语句删除掉,程序会不断的循环。<BR>void
CFrameWin::Go()
//Game循环<BR>{<BR>AfxMessageBox("Go");<BR>Update();<BR>DestroyWindow();<BR>}
<P>Active()成员函数会在应用程序被击活的时候被调用。<BR>void CFrameWin::Active()
//窗口被激活<BR>{<BR>TRACE("Active\n");<BR>AfxMessageBox("Active");<BR>}
<P>这个程序并不做任何事,只是一个MFC框架。你可以从http://gamedev.363.net
下载例子的源程序,或通过E-mail: laical@21cn.com 向本文作者索取。
<P>第二章
初始化DirectX8<BR>(DX8MFC1)<BR>本例将以第一章的MFC框架为基础对CFrameWin类进行扩展。主要加入了DrawScene()、InitDirect3D(HWND
hwnd)和ShutdownDirect3D()三个函数。<BR>InitDirect3D(HWND
hwnd)函数对Direct3D进行初始化:<BR>HRESULT CFrameWin::InitDirect3D(HWND
hwnd)<BR>{<BR> pID3D =
Direct3DCreate8(D3D_SDK_VERSION);
<P> HRESULT hr;<BR>
do<BR>
{<BR> // we need the
display mode so we can
get<BR> // the properties
of our back buffer<BR>
D3DDISPLAYMODE d3ddm;<BR>
hr = pID3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT,
&d3ddm);<BR>
if(FAILED(hr))<BR>
break;
<P> D3DPRESENT_PARAMETERS
present;<BR>
ZeroMemory(&present,
sizeof(present));<BR>
present.SwapEffect =
D3DSWAPEFFECT_COPY;<BR>
present.Windowed =
TRUE;<BR>
present.BackBufferFormat = d3ddm.Format;
<P> hr =
pID3D->CreateDevice(D3DADAPTER_DEFAULT,<BR>
D3DDEVTYPE_HAL,<BR>
hwnd,<BR>
D3DCREATE_SOFTWARE_VERTEXPROCESSING,<BR>
&present,<BR>
&pID3DDevice);
<P>
if(FAILED(hr))<BR>
break;
<P> // we do our own
coloring, so disable
lighting<BR> hr =
pID3DDevice->SetRenderState(D3DRS_LIGHTING,<BR>
FALSE);
<P> } while(0);
<P> return hr;<BR>}
<P>IDirect3D是我们首先要用到的接口,你可以这样写:<BR>IDirect3D8 * pID3D =
Direct3Dcreate8(D3D_SDK_VERSION);<BR>在你使用pID3D以前,请检查pID3D是否为非空。<BR>你下一步通常是创建D3D设备,但在创建D3D设备之前你要调用GetAdapterDisplayMode方法取得必须的信息:<BR>D3DDISPLAYMODE
d3ddm;<BR>pID3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT,
&d3ddm);<BR>接下来是取得当前显示模式参数。下面的参数是Surface格式。你可以用这些参数来创建一个D3DPRESENT_PARAMETERS结构:<BR>D3DPRESENT_PARAMETERS
present;<BR>ZeroMemory(&present,
sizeof(present));<BR>present.SwapEffect
=
D3DSWAPEFFECT_COPY;<BR>present.Windowed
=
TRUE;<BR>present.BackBufferFormat
=
d3ddm.Format;<BR>D3DPRESENT_PARAMETERS描述了显示器Surface的信息,交换机制的类型,应用程序是窗口的还是全屏模式等信息。<BR>在本例中,Surface是以拷贝方法代替页面翻转的,因为它是一个窗口模式的应用程序。把后台表面设置成与当前显示模式相匹配的格式,一个准备显示的Surface可以Draw在后台表面上。
<P>现在你可以创建一个IDirect3DDevice8接口了:<BR>pID3D->CreateDevice(D3DADAPTER_DEFAULT,<BR>
D3DDEVTYPE_HAL,<BR>
hwnd,<BR>
D3DCREATE_SOFTWARE_VERTEXPROCESSING,<BR>
&present,<BR>
&pID3DDevice);<BR>这个函数有六个参数,幸运的是没有一个是很复杂的。D3DADAPTER_DEFAULT告诉Direct3D使用主显示器,只有当你使用多显示器时才是必须的。你可以使用一个数值来指定另外一个显示器。调用IDirect3D的GetAdapterCount将返回系统的适配器数目。<BR>第二个参数,D3DDEVTYPE_HAL,告诉Direct3D使用硬件加速。其它选项包括D3DDEVTYPE_REF
和
D3DDEVTYPE_SW,通常你都会希望使用硬件加速的,但有时侯你可能会使用软件加速进行测试。<BR>指定窗口取得焦点。如果是全屏应用程序,你需要一个最顶层窗口。<BR>D3DCREATE_SOFTWARE_VERTEXPROCESSING指定顶点处理类型。你也可以使用硬件加速或是联合类型,我不使用硬件加速为的是广泛的兼容性。如果你想支持T&L,则你必须使用硬件加速。<BR>最后两个参数很简单,一个是你以前建立的,而pID3Ddevice是你现在要创建的IDirect3DDevice8接口。如果方法返回D3DERR_NOTAVAILABLE,则你写的参数是正确的,但你的设备不支持你指定的参数。<BR>最完美的是这个方法自动为你创建后台缓冲(back
buffers)和深度缓冲(depth buffers)。剪裁(Clipping)作为后台表面(backface
culling)被自动激活。灯光也被自动激活了,直到你定义顶点颜色之前,你可以禁止使用灯光:<BR>pID3DDevice->SetRenderState(D3DRS_LIGHTING,
FALSE);
<P>DrawScene()函数:<BR>HRESULT
CFrameWin::DrawScene()<BR>{<BR> HRESULT
hr;<BR> do<BR>
{<BR> // clear back
buffer<BR> hr =
pID3DDevice->Clear(0,<BR>
NULL,<BR>
D3DCLEAR_TARGET,<BR>
D3DCOLOR_RGBA(0,63,0,0),<BR>
0,<BR>
0);<BR>
if(FAILED(hr))<BR>
break;
<P> // start
drawing<BR> hr =
pID3DDevice->BeginScene();<BR>
if(FAILED(hr))<BR>
break;
<P> // Put all drawing
code here
<P> hr =
pID3DDevice->EndScene();<BR>
if(FAILED(hr))<BR>
break;
<P> // flip back buffer to
front<BR> hr =
pID3DDevice->Present(NULL, NULL, NULL,
NULL);<BR> } while(0);
<P> return hr;<BR>}
<P>Clear会填充你指定的缓冲区。你可以填充Z缓冲区、后台缓冲区或摸板缓冲区(stencil
buffer)。在这个例子中你将用绿色填充后台缓冲区。所以,我们设定D3DCLEAR_TARGET标志和绿色。<BR>在本例中BeginScene和EndScene并没有做什么,但在以后的例子中我们会用到它的。这两个函数是画图元时的例行公事代码,<BR>这个函数不断的翻转后台表面。我们可以不断的在后台表面画一些东西,然后把后台表面翻转到前台表面。
<P>ShutdownDirect3D()函数<BR>void
CFrameWin::ShutdownDirect3D()<BR>{<BR>
HELPER_RELEASE(pTexture);<BR>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -