设定Direct X应用程序中的Direct 3D.docx
- 文档编号:29146326
- 上传时间:2023-07-20
- 格式:DOCX
- 页数:34
- 大小:35.23KB
设定Direct X应用程序中的Direct 3D.docx
《设定Direct X应用程序中的Direct 3D.docx》由会员分享,可在线阅读,更多相关《设定Direct X应用程序中的Direct 3D.docx(34页珍藏版)》请在冰豆网上搜索。
设定DirectX应用程序中的Direct3D
4.设定DirectX应用程序中的Direct3D
现在进入有趣的部分!
从现在起,我们将开始建立我们程序中的MicrosoftDirect3D立即模式。
在本章中,我们会先检查在立即模式中有哪些可用的对象和接口。
然后我们会带您走过要建立一个立即模式程序框架的相关步骤。
在读过 第三章 后,您应该对DirectDraw定义程序代码已经适应了。
要记住,Direct3D是一个指向DirectDraw对象的COM接口。
因此Microsoft把硬件抽像层(HAL)叫作DirectDraw/Direct3DHAL。
此外,Direct3D利用DirectDraw绘图页作为前后缓冲区来显示3D场景和计算3D场景时的z缓冲区。
另外,Direct3D贴图是由DirectDraw绘图页所构成的,并且可以引用DirectDraw型态。
Direct3D立即模式对象和接口
Direct3D立即模式是由一些COM对象和连到这些对象的接口所构成的,您可以用这种模式来建构和控制您程序中的3D世界。
在本段落中,我们会看到这些对象和他们的接口(以及一些DirectDraw对象和接口)。
DirectDraw物件
和在 第三章 中您看到的一样,您可以用DirectDrawCreateEx函式来建立DirectDraw对象。
DirectDrawCreateEx函式开启了DirectX7最新的DirectDraw和Direct3D接口。
您在任何Direct3D应用程序中所建立的第一个对象一定是DirectDraw对象,因为它负责并提供显示装置的存取功能,如此才能实作许多Direct3D的功能。
IDirectDraw7是DirectX7中连到DirectDraw对象的最新版接口,而且它和之前版本有很大的不同。
我们也会在本书中使用到它。
DirectDrawSurface物件
在一个Direct3D程序中,可以用DirectDrawSurface(IDirectDrawSurface7接口)对象来建立前缓冲区、后缓冲区、贴图对映和深度缓冲区。
绘图页则表示某块可能存在在您的视讯卡上或您的计算机标准系统内存中的内存。
如果您用DDSCAPS_3DDEVICE特性位建立了一个DirectDrawSurface对象,您可以用IDirect3D7:
:
CreateDevice,并配合绘图页来建立一个Direct3D装置对象,这个对象会用此绘图页作为它的绘制目标,这也是在建立后缓冲区时的一般作法。
您也可以利用IDirectDraw7:
:
CreateSurface方法和DDSCAPS_TEXTURE旗标来建立一个拥有贴图功能的DirectDrawSurface对象。
这个对象可以填入您想用在场景中的对象贴图所用到的位图。
Direct3DDevice物件
所谓Direct3Device对象是Direct3D的成像组件。
它可以概括和储存立即模式应用程序的「成像状态」和一个可以运用该状态来计算基本形状的方法。
所谓成像状态(renderingstate)定义了绘制上用到的参数,包括了贴图、上色、色彩和烟雾。
DirectX7中包含了IDirect3DDevice7的接口所提供的装置对象模型。
您可以用IDirect3D7:
:
CreateDevice方法来建立Direct3D装置对象。
这个呼叫动作也同时让您取得一个IDirect3DDevice7接口。
而这个接口并不会对材质、光源和检视埠使用不同的COM对象,这是和早期版本的DirectX不同之处。
在DirectX7中,这个新的接口包含了可提供这些新特性作为Direct3D装置内部数据结构的一些方法。
在目标系统上可以建立以下几种Direct3D装置:
∙HAL装置。
∙TnLHAL装置。
∙RGB装置。
∙参照扫描成像装置(referencerasterizerdevice)。
还有其它二种装置在DirectX的之前版本有提供-MMX装置和连冲装置(rampdevice),但在DirectX7中不存在。
HAL装置是一个支持Direct3D的3D绘图器,提供了硬件的扫描成像,但不提供转换和打光功能,(转换、打光和扫描成像会在后面两章有详细说明)。
如果列举时有找到HAL装置,应该在您的程序中运用。
但是如果您在开发程序时采纳了硬件转换和打光的优点时,TnLHAL会是更好的选择。
TnLHAL(Transform'n'LightingHAL)装置用硬盘来处理所有转换和打光以及扫描成像模块,而且显然也是最快速的装置类型。
它和HAL的差异是在它执行硬件加速的转换和打光动作。
因此,它可以减轻CPU的负载,明显加快应用程序的速度。
您可以检查D3DEVCAPS_HWTRANSFORMANDLIGHT装置特性来辨认某个装置有无提供硬件加速的转换和打光。
RGB装置主要是用在不含任何硬件3D加速功能的系统上。
RGB装置可用软件仿真3D指令。
这意谓着它会比用HAL装置执行速度慢得多,但是它可以利用系统CPU提供的特殊指令。
这种扫描成像器会用到支持MMX指令集(某些Intel处理器适用),或者是AMD3DNow!
(某些AMD处理器适用)来加速绘制。
MMX指令集是用来加速扫描成像而3DNow!
指令集则可加速转换和打光动作。
但实时有了这些特殊指令集,RGB装置还是比HAL和TnLHAL慢。
最后一种是参照扫描成像装置,这种绘制器支持所有的Direct3D功能,但是实作上是针对正确性作最佳化而非针对速度。
因此,参照扫描成像器相当地慢,您应该只用它来测试您的卡无法支持的Direct3D功能上。
Direct3D的默认值并不会列举扫描成像器。
要列举它时,您首先必须使用RegEdit,将HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Direct3D\Drivers下的记录值EnumReference值设为一个非零的DWORD值。
Direct3DVertexBuffer物件
这种对象是一个内存缓冲区,里面包含要用IDirect3DDevice7接口提供的顶点缓冲区绘制方法计算的顶点。
使用IDirect3D7:
:
CreateVertexBuffer方法可以建立顶点缓冲区以及相关的存取接口。
下一章会详细说明顶点和顶点缓冲区。
建立一个立即模式应用程序
要让您的程序用到Direct3D时,会包含以下的步骤,其中有一些在第三章就提过了。
我会针对前五个步骤深入探讨一些额外的内容,并且描述建立Direct3D装置和深度缓冲区的最终过程。
1.初始化应用程序。
2.辨认可用的DirectX版本(如果省略这个动作,本书的程序代码中假设DirectX7可用)。
3.列举存在可用的Direct3D装置。
4.选择Direct3D装置。
5.利用DirectDrawCreateEx取得一个IDirectDraw7接口。
6.利用IDirectDraw7接口的QueryInterface方法来取得IDirect3D7接口,再建立一个Direct3D装置。
7.列举深度缓冲区格式,建立一个深度缓冲区用来绘制您的3D世界。
在本章中,您可以看到如何做到以上步骤和建立一个有效的Direct3D装置所需要的相关程序,让您可以绘制您的3D世界。
我们先修改 第三章 提到的CD3DFramework7:
:
CreateEnvironment程序来建立Direct3D、Direct3DDevice和深度缓冲区对象。
以下是这个程序修改过的版本:
//-------------------------------------------------------------------
//名称:
CreateEnvironment
//说明:
建立程序框架的内部对象
//-------------------------------------------------------------------
HRESULTCD3DFramework7:
:
CreateEnvironment(GUID*pDriverGUID,
GUID*pDeviceGUID,
DDSURFACEDESC2*pMode,
DWORDdwFlags)
{
HRESULThr;
//依据装置为硬件装置或
//软件装置而定,选择预设的内存型态。
if(IsEqualIID(*pDeviceGUID,IID_IDirect3DHALDevice))
m_dwDeviceMemType=DDSCAPS_VIDEOMEMORY;
elseif(IsEqualIID(*pDeviceGUID,IID_IDirect3DTnLHalDevice))
m_dwDeviceMemType=DDSCAPS_VIDEOMEMORY;
else
m_dwDeviceMemType=DDSCAPS_SYSTEMMEMORY;
//建立DirectDraw对象
hr=CreateDirectDraw(pDriverGUID,dwFlags);
if(FAILED(hr))
returnhr;
//建立前后缓冲区,并加上裁切。
if(dwFlags&D3DFW_FULLSCREEN)
hr=CreateFullscreenBuffers(pMode,dwFlags);
else
hr=CreateWindowedBuffers(pMode,dwFlags);
if(FAILED(hr))
returnhr;
//建立Direct3D对象和Direct3DDevice对象
hr=CreateDirect3D(pDeviceGUID,dwFlags);
if(FAILED(hr))
returnhr;
//建立并附加上z-缓冲区
if(dwFlags&D3DFW_ZBUFFER)
hr=CreateZBuffer(pDeviceGUID,dwFlags);
if(FAILED(hr))
returnhr;
returnS_OK;
}
我们会在本章稍后对这个程序增加其它的呼叫内容。
依照您所建立的不同装置类型(HAL、RGB等),您应该让软件选择您的主绘图页、贴图和顶点缓冲区所需要的内存型态,让您的程序发挥最好的效率。
除了标准的视讯内存外,DirectDraw支持加速图型端口(AcceleratedGraphicsPort,AGP)架构,允许在非本机视讯内存中建立绘图页。
AGP架构的作法有二种:
执行模型(executemodel)和DMA模型。
在执行模型下,显示装置同时支持非本机(AGP)和本机(标准)视讯内存绘图页的同样功能。
在DMA模型下,如果没有可用的本机视讯内存时,(除非您要求使用本机视讯内存),DirectDraw会针对您建立的任何贴图绘图页使用非本机视讯内存。
对其他的绘图页型态而言,绘图页只会建立在本机视讯内存中,除非您的程序需要使用非本机视讯内存。
要辨别某种装置驱动程序是否支持非本机视讯内存绘图页的贴图,您可以看看D3DDEVCAPS_TEXTURENONLOCALVIDMEM旗标值是否有被设定。
您可以利用IDirect3DDevice7:
:
GetCaps方法取得3D装置特性清单,再从清单中取得该旗标值。
步骤1:
初始化应用程序
要在程序中建立Direct3D内容的第一个步骤是初始化所有相关的变量。
这个步骤的主要目的是要清除所有的对象和结构,让您可以在您的3D世界中建立必要的对象和在结构中填入需要的设定值,例如上色参数和裁切。
以下的CD3DFramework7建构元会初始化所有的成员变量,并定义某些项目(如z轴、后缓冲区和装置)。
//-------------------------------------------------------------------
//名称:
CD3DFramework7
//说明:
用来清除静态变量的建构元
//-------------------------------------------------------------------
CD3DFramework7:
:
CD3DFramework7()
{
m_hWnd=NULL;
m_bIsFullscreen=FALSE;
m_bIsStereo=FALSE;
m_dwRenderWidth=0L;
m_dwRenderHeight=0L;
m_pddsFrontBuffer=NULL;
m_pddsBackBuffer=NULL;
m_pddsBackBufferLeft=NULL;
m_pddsZBuffer=NULL;
m_pd3dDevice=NULL;
m_pDD=NULL;
m_pD3D=NULL;
m_dwDeviceMemType=NULL;
}
步骤2:
决定DirectX版本
辨别系统上已安装的DirectX版本的整个过程称为版本检查。
您需要做到的版本检查程度依照您使用Direct3D的方式而有不同。
如果您有兴趣开发自己的系统,那么您大概已经安装了最新且最完整的DirectX,因此不需再作检查。
如果您正在撰写一个全新的DirectX7应用程序,您应该会在产品中附上最新的DirectX执行时期函式库,您的安装程序也会顺便安装(如果系统环境是Windows95或Windows98)。
如果环境是MicrosoftWindowsNT4或更早版本,您可以控制程序不要安装或执行。
Windows2000出厂时已附有完整的DirectX支持,所以如果系统环境是Windows2000时,您的软件可以使用最新的DirectX特性。
大多数公司出厂的3D游戏和其它软件会希望您已安装最新版DirectX-否则会在游戏安装过程中,再从同一片游戏光盘安装DirectX。
然而,如果您打算支持之前版本的DirectX(为了某种理由),您必须作更精准的版本检查。
您可能想避免在连结ddraw.lib而不是用LoadLibrary和GetProcAddress时,看到突然出现的标准错误讯息。
如果您不想让使用者收到标准的系统错误讯息,请使用QueryInterface作为需求接口,以一个错误讯息表示失败,并且结束程序。
您的最佳作法是建立一个Windows95或Windows98的安装程序,能够在安装过程中自动更新系统为最新版的DirectX。
然而,请记住,在WindowsNT和Windows2000中,只有系统管理者有权更新操作系统的重要部分(如DirectX),因此您的安装程序无法更新DirectX版本。
如果您希望使用版本检查的作法,好让您的软件能在多个平台上执行,您可以检查不同的DirectX接口的可用性。
试着检查从DirectX2支持的接口到只有DirectX7才支持的接口,您可以找出目前可用的DirectX版本。
一旦找出确实可用的DirectX版本,您可以让程序完全享受到系统平台支持的所有功能的优点。
如果系统平台的DirectX版本不及您需求的来得新,您可以让软件本身适当的减少支持效果。
比方说,如果您想要DirectX7,但只有DirectX3可用,您0可以停用多贴图,因为在DirectX3中并不支持。
依此作法可以让您的应用程序正常执行,只会牺牲一点视觉效果。
然而上面也提过,您最好还是在系统平台上安装最新版的DirectX,这样您的软件才能发挥它的实力。
步骤3:
列举现存可用的Direct3D装置
要建立一个稍后可用来绘制的装置,首先您要列举出Direct3D装置。
第三章 提到,这样做意谓着先列举出DirectDraw装置,再列举出附属在每个DirectDraw装置上的所有Direct3D装置。
您可以用第三章描述的 D3DEnum_EnumerateDevices 程序来做到这件事。
步骤4:
选择Direct3D装置
要让您的程序能使用Direct3D的下一步骤包含了挑选最适用于程序需求的Direct3D装置,并且去建立该装置。
处理这个选择动作和建立装置的原始程序的同时也要能判别是在全屏幕或窗口模式下执行。
在第三章的 DeviceEnumCallback 程序中说明了整个动作。
步骤5:
取得一个IDirectDraw7界面
在初始化您的变量及判别DirectX版本后,下一步就是要建立一个DirectDraw对象。
第三章 已详述了如何用CD3DFramework7:
:
CreateDirectDraw成员函式来取得新的IDirectDraw7界面。
步骤6:
从IDirectDraw7接口取得IDirect3D7接口并建立一个Direct3D装置
要建立一个Direct3D对象,您要用DirectDraw对象的QueryInterface方法来判定它是否支持DirectX7所提供的IID_IDirect3D7接口,如果DirectDraw对象支持该接口,QueryInterface会取得一个指到该接口的指针并且呼叫AddRef来累加此参照。
以下的d3dframe.cpp程序说明了如何建立Direct3D对象和Direct3DDevice对象。
(我们会在 第五章 中讨论这个程序的最后一段:
建立一个检视埠)
//-------------------------------------------------------------------
//名称:
CreateDirect3D
//说明:
建立Direct3D接口
//-------------------------------------------------------------------
HRESULTCD3DFramework7:
:
CreateDirect3D(GUID*pDeviceGUID)
{
//查询DirectDraw以存取Direct3D。
if(FAILED(m_pDD->QueryInterface(IID_IDirect3D7,
(VOID**)&m_pD3D)))
{
DEBUG_MSG(_T("Couldn'tgettheDirect3Dinterface"));
returnD3DFWERR_NODIRECT3D;
}
//建立装置。
if(FAILED(m_pD3D->CreateDevice(*pDeviceGUID,m_pddsBackBuffer,
&m_pd3dDevice)))
{
DEBUG_MSG(_T("Couldn'tcreatetheD3DDevice"));
returnD3DFWERR_NO3DDEVICE;
}
//设定新建立的装置的检视端口。
D3DVIEWPORT7vp={0,0,m_dwRenderWidth,m_dwRenderHeight,
0.0f,1.0f};
if(FAILED(m_pd3dDevice->SetViewport(&vp)))
{
DEBUG_MSG(
_T("Error:
couldn'tsetcurrentviewporttodevice"))_T("Error:
Couldn'tsetcurrentviewporttodevice"));
returnD3DFWERR_NOVIEWPORT;
}
returnS_OK;
}
一旦这个程序成功地回传,您就拥有了一个有效的Direct3D物件和一个有效的Direct3D装置对象,可以用在应用程序中。
建立Direct3D装置
在本章的前面,您曾经看过可用的Direct3D装置类型。
在DirectX7中,只要呼叫IDirect3D7:
:
CreateDevice方法即可取得IDirect3DDevice7接口,其中即包含了支持材质、光源和视埠的方法,而不是像之前版本的DirectX需要取得不同的Direct3DLight、Direct3DMaterial和Direct3DViewport物件。
我们曾讨论过,您建立的装置必须对应系统平台上的可用功能。
Direct3D利用计算机的3D硬件或软件仿真3D特性的方式提供了绘制功能,也就是同时提供硬件存取和软件仿真。
您应该在设计软件时尽可能地使用硬件功能而非软件仿真,因为硬件执行速度较快。
记住,软件装置未必支持硬件装置所有支持的特性。
因此,您应该查询装置的特性来找出硬件支持的部分,而在缺少硬件加速卡的系统上再使用软件仿真。
HAL和TnLHAL装置皆属于硬件加速,您应该多加利用。
Direct3D应用程序利用Direct3D方法和HAL来存取3D硬件。
如果系统里有一片Direct3D功能的3D硬件加速卡,您应该将它用在硬件实作的Direct3D功能上。
如果没有可用的硬件加速时,RGB装置(它会试着利用MMX)则是次佳的选择。
RGB装置是一种软件扫描成像器,所以它会比硬件加速装置来得慢。
然而,RGB装置可以运用现有的CPU延伸功能,例如MMX、3DNOW!
和Katmai,来尽可能地加快执行速度。
取得各种装置类型的呼叫指令如下:
CreateDevice(IID_IDirect3DTnLHalDevice,
lpDirectDrawSurface,
lplpDirect3DDevice);
CreateDevice(IID_IDirect3DHALDevice,
lpDirectDrawSurface,
lplpDirect3DDevice);
CreateDevice(IID_IDirect3DRGBDevice,
lpDirectDrawSurface,
lplpDirect3DDevice);
CreateDevice(IID_IDirect3DRefDevice,
lpDirectDrawSurface,
lplpDirect3DDevice);
IDirect3DDevice7界面的成员函式IDirect3DDevice7:
:
GetCaps,会取得所有Direct3D装置的特性。
这个方法会将描述这些特性的数据存入D3DDEVICEDESC7结构中。
D3DDEVICEDESC7结构的定义如下:
typedefstruct_D3DDeviceDesc7{
DWORDdwDevCaps;//装置特性
D3DPRIMCAPSdpcLineCaps;
D3DPRIMCAPSdpcTriCaps;
DWORDdwDeviceRenderBitDepth;//DDBB_8,16,等中的任一种
DWORDdwDeviceZBufferBitDepth;//DDBD_16,32,等中的任一种
DWORDdwMinTextureWidth,dwMinTextureHeight;
DWORDdwMaxTextureWidth,dwMaxTextureHeight;
DWORDdwMaxTextureRepeat;
DW
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 设定Direct X应用程序中的Direct 3D 设定 Direct 应用程序 中的