多媒体技术之Direct编程入门_第1页
多媒体技术之Direct编程入门_第2页
多媒体技术之Direct编程入门_第3页
多媒体技术之Direct编程入门_第4页
多媒体技术之Direct编程入门_第5页
已阅读5页,还剩50页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

多媒体技术之DirectX编程入门

第13章DirectX编程入门

DirectX是微软公司为编写游戏与其他高性能多媒体应用程序而开发的一组高级的

Windows低层API,它包含了对图(图形、视频与三维动画)、声音(声效与音乐)、输入

设备与网络游戏等的支持。

本章先概述DirectX的基本内容,然后介绍DirectX的要紧组件Direct3D4DirectSound

的基本编程方法,并给出若干具体编程实例。

13.1DirectX概述

本节简单介绍DureclX的进展历史、版本与功能的演化、结构与模块划分。

DurectX是Windows的一种多媒体APL它在保持设备无关性的同时,能够让应用程序

直接操纵多媒体设备,从而能充分利用硬件的功能,因此可获得最高的性能。

DurectX自从推出以来,就始终处在快速进展的过程之中。它已经经历了多个版本,其

模块与功能也一直在不断地增加与完善。

DirectX是一种基于COM的系统,要紧由硬件抽象层HAL与硬件模拟层HEL所构成。

DurectX被分成若干个组件模块,涵盖了多媒体应用的方方面面。而且这些组件的数目、名

称与功能,也是随着其版本的演化而有所增减、改变与加强。

13.1.1历史

微软公司于1990年5月推出的Windows3.0大获成功,它是一种与设备无关的具有图形

用户界面(GUI)的操作系统。后来又于1992年3月推出Windows3.1,提供了对多媒体的

支持。只是Windows的与设备无关的设计思想,尽管使得Windows向程序员提供了一个独

立于硬件的软件开发优秀平台,但它不让应用程序直接操作显卡与声卡等多媒体硬件,这样

就降低了多媒体应用程序(特别是计算机游戏)的运行效率,比如限制了动画的帧率、不提

供混音功能等。因此当时的Windows并不是一个能够开发与运行高效多媒体程序(如3D游

戏)的理想环境,逼迫PC游戏开发商只好绕开Windows而仍旧开发DOS下的游戏。

为了改变这种难堪的局面,促使游戏界放弃DOS而使用Windows,微软需要在设备无

关性与高性能之间取得某种平衡,决定为Windows添加一种高性能的动画机制(与后来的输

入与音响等),因此于1995年推出了GameSDK,后来改名为DirectX。其中的Direct指能

够直接访问多媒体硬件;X指它的不一致构成部分,如Direct3D、DireclSound、Directlnput

与DirectPlay等。

13.1.2版本与功能

由于DirectX务必支持多媒体设备的最新技术与功能,而多媒体硬件(特别是显卡[的3D

性能])与技术始终处在高速进展过程中,因此DirectX的技术与版本也同样在不断地进展与

演变,其中进展最快的是3D接口部分。

下面列出DirectX的要紧版本的公布时间、引入的新模块与特性:

■1.0------1995年9月30日:DirectDraw、DirectSound、Directlnput、DirectPlay、DirectSetup;

■2.0——1996年6月5日:引入Direct3D(次版本有2.0a);

■3.0——1996年9月15日:支持MMX、为DirectSound补充DirectSound3DAPI(次版

本有3.0a);

■4.0——无此版本号;

■5.0——1997年7月16H:有许多改进,如受力反馈操纵器、多显示器支持、新的游戏

操纵面板、用户界面的全面改进等(次版本有5.1与5.2);

■6.0——1998年8月7日:添加新的3D特性(如添加DXUT框架)、支持AMD公司

的3DNow!技术、性能较5.0有提高。在1999年2月3日推出的6.1版中,添加了

DirectMusic模块;

■7.0——1999年9月22日:改进3D图形与声音、性能更快,为Direct3DAPI引入硬件

传送、光照与纹理压缩、与硬件加速,引入D3DX工具库。使用Creative公司的EAX

技术改进3D声音的算法(次版本有7.0a与7.1);

■8.0——2000年9月30日:将DirectDraw与Direct3D完全集成在一起、其中Direct3D

的性能有了本质上的飞跃(引入顶点/像素shader[着色引擎/光照模型]、支持硬件点精灵

与三维体纹理),将DirectMusic与DirectSound更紧密地集成在一起构成DirectXAudio,

更新了Directlnput与DirectPlay,添加了DirectShow、抛弃了其余的DirectXMedia模块。

2001年11月II日推出的8.1版,被集成在WindowsXP中销售,该版本添加了从

DirectShow分离出的DMO(DirectXMediaObjects媒体对象)组件模块。它还支持许

多新的图形特性,如像素着色引擎的1.27.4版、动态/高分辨率纹理、新3D扩展方法

等(次版本有8.0a、8.1、8.1a与8.1b);

■9.0——2002年12月24日:添加许多新特性到DirectXGraphics与DirectShow中,比

如将DirectDraw的功能并入到Direct3D之中,支持顶点与像素着色引擎的新版本2.0

与3.0,引入裁剪测试、位移贴图与多元纹理,支持128位浮点着色精度与根据显示器

自动调整Y值等。也添加若干新特性到Directlnput、DirectPlay>DirectSound与

DirectMusic中。(次版本有9.0a、9.0b与9.0c)。

DirectX的最后一个以数字与字母命名的版本是2004年8月9日推出的9.0c,后来又于

2004年10月、2005年的2/4/6/8/10月分别推出了它的多个升级版。从2005年12月推

出的DirectX开始,其版本的命名发生了变化:主版本号改为DX,次版本改为公布的

年月。通常是每两个月推出一个新版本,因此也叫做DirectX9.0c的双月更新(bimonthly

应用程序

updates)o当前最新版本为

2006年10月11日推出的DX

October20060它们都包含了

(于2002年推出的专

为.NET框架设计的)托管

(Managed)DirectX,将原

先DirectX多个分离的COM

模块集成到了一个容易使用PC硬件子系统

的单一CLR文件之中。

■10—?:DirectX不可能有第10版了,由于微软公司已将DirectX的功能集成进其新

一代操作系统WindowsVista中,而不再将其作为一个额外的模块了。但是会有Direcl3D

10,已于2006年12月13日随Direct3DSDK的December2006版一起公布,并被嵌入

到WindowsVista中。另外,作为学生与业余爱好者的DirectX替代产品,微软公司于

2004年3月24日宣布了用于托管运行环境下计算机游戏的设计、开发与管理的框架与

工具集XNA,并于2006年12月11日推出了XNAFrameworkRedistributable与XNA

GameStudioExpress的1.0版,可用于Windows与Xbox360游戏的开发。

13.1.3结构

DirectX是一种基于COM(ComponentObjectModel,组件对象模型)的系统,它既不

属于驱动程序层,也不属于应用层。DirectX的要紧设计目标是在提供某种设备独立性的同时

获取高速度,为此微软公司为DirectX设计了如图13-1所示的体系结构。其中:

■HAL=HardwareAbstractLayer(硬件抽象层)----负责检测本机的硬件功能,并

以一种独立于设备的方

式提供这些功能;图13"DirectX子系统

■HEL=HardwareEmulationLayer(硬件模拟层)---负责提供DirectX功能中本机

硬件不支持部分的模拟实现。

但是从&0版起,DirectX就不再提供硬件模拟层HEL了,需要开发商、第三方或者

自己来编写一个PSD(PluggableSoftwareDevice可插式软件设备)连到DirectX提供的HEL

接口上,称之为参考设备。但是现在很少有这样的PSD可用,因此新版本的DirectX是严

重依靠于硬件的。

13.1.4构成

DirectX由多个(COM组件)模块构成,而且随着版本的演化,这些模块也在不断地增

减、合并与改变。最新的DirectX组件的模块构成如图13-2所示,括号中的数字为该模块被

首次引进(或者移出)的版本号。

下面是DirectX的要紧构成模块的简单介绍:

■DirectXGraphics(图形)----包含DirectDraw与Direct3D:

♦DirectDraw(绘制)——二维图形绘制(高速位图传送/视频与2D动画)。

从9.0版起,DirectDraw已被集成到了Direct3D之中。

♦Direct3D(三维)----三维图形绘制。分成保留(retained)与立即(immediate)

两种模式(mode):保留模式是一种高层API,建立在立即模式之上,使用

起来方便容易,但是效率不高,适合于初学者;立即模式则是一种底层API,

使用复杂,但是其效率比保留模式高得多。大多数DirectX应用程序,特别

是计算机游戏,都是使用立即模式进行开发。自从6.0版以来,保留模式API

的进展停滞不前,而立即模式API的进展却日新月异。不论是保留模式还是

立即模式,Direct3D都是建立在DirectDraw之上的。从9.0版起,Direct3D

包含了DirectDraw,它像OpenGL一样也具有二维图形绘制的功能。Direct3D

的下一个版本为Durect3D10,为WindowsVista的一个有机构成部分。

•D3DX(Direct3D扩展)——为Direct3D服务的有用工具库,执行公

共的数学计算与一些复杂的任务,包含若干简化3D模型使用的类,如

粒子系统(particlesystem)。D3DX由动态链接库(DLL)提供。

•DXUT(编程框架)——建立在Direct3DAPI之上的样例框架,也叫

通用文件框架,能够帮助程序员减少在繁琐的平凡工作(如创建窗口、

创建设备、处理Windows消息与设备事件等)上所花的时间。

图13-2DirectX的构成模块

■DirectXAudio(音频)----包含DirectSound与DirectMusic:

♦DirectSound(声音)——要紧针对波形音频,底层接口。可用于开发播放

与捕捉波形音频的高性能立体与三维(DirectSound3D)音频应用程序。在下一

代DirectX中,DirectSound的功能将由XACT(MicrosoftCross-PlatformAudio

CreationTool微软跨平台音频生成工具)来代替。

♦DirectMusic(音乐)----要紧针对MIDI音乐,高层接口。为基于波形、

MIDI声音或者DirectMusic生成器所制造的动态内容之音乐与非音乐声道提

供一个完整的解决方案。

♦XACT(游戏音频)----XACT(MicrosoftCross-PlatformAudioCreation

Tool,微软跨平台音频生成工具),是一种多人合作的音频设计工具与有关

API,用于游戏的动态音频开发。

■Directlnput(输入)——提供对各类输入设备的支持,包含对受力反馈

(force-feedback)技术的全面支持。在下一代DirectX中,Directlnput将被XInput代

替。

■DirectPlay(游戏)——提供对多人网络游戏的支持。在最新的DirectX版本中,

微软公司反对(deprecate)使用DirectPlay,而建议改用WindowsSockets与Windows

FirewallAPI来代替。在下一代DirectX中,DirectPlay可能会被XboxLive代替。

■DirectSetup(安装)——提供DirectX组件的一次性调用安装的一个简单API(自

动安装DirectX驱动程序)。

■DirectShow(展示)——提供多媒体(音视频)流的高质量捕捉与重放。在8.0

版之前,DirectShow是DirectXMedia的一个构成模块。到8.0版时,由于DirectX

SDK抛弃了DirectXMedia,因此才将DirectShow集成到了DirectX之中。在DirectX

9.0c的2005年4月升级版中,DirectShow又被移出DirectX,放入微软公司的平台

SDK之中。

■DirectXMediaObjects(媒体对象DM0)——基于COM的多媒体与数据流组件,

支持音视频的编解码器与特效。是在DirectX的8.1版时,从DirectShow分出的,

其功能类似于DirectShow的过滤器。

■DirectXMedia(媒体)——是一个用于流媒体应用的外部API集合。在DirectX6.0

之前,DirectXMediaSDK与DirectXSDK是两个分离的SDK»在6.0版时DirectX

MediaSDK被集成到DirectXSDK之中。DirectXMedia的运行模块,被集成到

Windows与IE之中。到了8.0版时,DirectXMedia又被DirectXSDK抛弃(其核

心模块DirectShow被集成到了DirectX之中),其功能被随Windows2000Server

推出的WindowsMediaSDK所代替。

♦DirectXTransform(变换)——用于产生二、三维图形的各类效果,如a混

色与表面弯曲等。

♦DirectAnimation(动画)---集成多种媒体类型来创建复杂动画,并可用

作网页内容。

♦DirectXVideoAcceleration(视频加速DXVA)——利用硬件加速二维视频

的解码操作。

♦Direct3DRetainedMode(保留模式)----Direct3D的保留模式是一种高层

API,建立在Direct3D立即模式之上,使用起来方便容易,但是效率不高,

适合于初学者。

♦DirectShow(展示)----支持音视频流的高质量采集与重放。

13.1.5编程准备

为了用VC编写DirectX应用程序,务必先下载并安装DirectXSDK,并进行必要的头

/库文件路径与链接库的设置。

下面以WindowsXP中文版环境下的VisualC++2005中文版与DirectX9.0cAugust

2006SDK为例,介绍进行具体的DirectX编程之前,所需做的必要准备工作。

•下载并安装DirectXSDK

能够从微软公司的官方网站()下载最新的DirectXSDK,如dxsdk_dec2006.exe

(448MB)。安装完成后,会在安装目录(缺省为“C:\ProgramFiles\MicrosoftDirectXSDK

((December2006)")中生成DeveloperRuntime、DocumentationAInclude,Lib、Redist、Samples

与Utilities等多个子目录。安装时还会为Windows操作系统生成名为“MicrosoftDirectXSDK

((December2006)"的程序组,包含多个子程序组与程序。

安装程序会将DirectXSDK的帮助文档,也安装到VisualStudio2005的帮助系统内,位

于其“目录/DirectXSDK((December2006)M目录之中,包含“DirectXSDK((December2006)

C++"与"DirectXSDK((December2006)Managed”两个帮助子目录。

•设置包含与库路径

在VisualStudio2005中文版的IDE中,选“工具/选项”菜单项,打开“选项”对话框

(参见图13-5)1,

图13-5VisualStudio2005的“选项”对话框

再选该对话框左边的“项目与解决方案/VC++目录”路径,在右边的“显示下列内容的

目录”栏的下拉式列表框中,选“包含文件”项。按该栏下面的“新行”钮净L则在其下

方的显示栏中会出现新行,再按新行右端的带省略号的浏览钮匚~1在弹出的“选择目录”

对话框中,选择DirectXSDK的Include目录所在的路径"C:\ProgramFiles\MicrosoftDirectX

SDK(August2006)\Includew,然后按“打开”关闭“选择目录”对话框。结果参见图13-6。

图13-6设置DirectX的“包含文件”的路径

可类似选择“库文件”项,添加库文件路径uC:\ProgramFiles\MicrosoftDirectXSDK

(August2006)\Lib\X86^^,结果参见图13-7。最后,按“确定”钮,关闭“选项”对话框。

图13-7设置DirectX的“库文件”的路径

注意,对DirectX的包含路径与库路径的设置,对所有项目都有效。

•设置链接库

先创建一个DirectX应用程序的MFC单文档项目(如DxTest),再在VS05的IDE中,

选“项目/属性”,打开“DxTest属性页”对话框。在左上角的“配置”栏中,选中“所有配

置”项;再选左边的路径“配置属性/链接器/输入”,在右边的“附加依靠项”栏中,添加

d3d9.libd3dx9.1ibd3dxof.libdsound.libdxguid.libwinmm.lib等链接库(在多个库文件之间,用

空格分隔)。具体添加什么DirectX库,与具体应用程序所使用的DirectX模块有关,你也能

够查看DirectX的库目录。最后,按“应用”钮与“确定”钮,关闭属性页对话框。参见图

13-8。

图13-8设置DirectX的链接库

注意,对DirectX链接库的设置,只对VC05中当前打开的单个项目有效。

在安装了DirectXSDK,并设置好文件路径与链接库后,就能够开始编写具体的DirectX

应用程序了。

DirectX的组件众多、功能强大、编程复杂,完整的介绍需要几本大部头的专著才行,

本书只准备简单介绍DirectX的最要紧模块---Direct3D与DirectSound编程的最基本内容。

13.2Direct3D编程简介

Direct3D(直接三维)是DirectX的核心模块,新版本的Direct3D中还包含原先

DirectDraw模块的2D功能。因此,现在的Direct3D是DirectXGraphics的唯一模块,具有

DirectX(二、三维)图形的全部功能。

13.2.1流水线与设备

Direct3D用图形流水线(graphicspipeline)来处理与渲染场景(renderscene),而Direcl3D

设备(device)是执行变换(transformation)与光照(lighting)等操作的渲染部件。

•Direct3D图形流水线

可通过Direct3D图形流水线来充分利用硬件性能,以提供高效处理与绘制Direct3D场

景到显示器的能力。图13-9为流水线(pipeline,管线/管道/流程)的构成模块框图。

图13-9Direct3D图形流水线

•Direct3D设备

Direct3D设备(device)是Direct3D的渲染部件,它封装与存储渲染状态。另外,它还

执行变换与光照等操作,同时光栅化图像到表面(如屏幕)。在结构上,Direcl3D设备包含

变换模块(transformationmodule)、光照模块Direct3D设备架构

(lightingmodule)与光栅化器(rasterizer)。图13-10变换模块||光照模块||光栅化器

为Direct3D的设备架构(architecture)。

图13-10Di〃ct3D设备架构

当前,Direct3D有两种要紧的设备类型:

■HAL设备(haldevice)------具有硬件加速的光栅化(rasterization),可同时使用硬件

与软件的顶点处理进行着色(shading)。

■参考设备(referencedevice)——由软件驱动程序提供,现在要紧用于性能测试。

具有软件特性的参考设备不一定能提供与硬件等同的性能,因此应用程序务必总是查

询设备的能力以确定其支持什么特性。创建Direct3D对象定义顶点格式

创建Direct3D设备对象—►创建顶点缓冲区

13.2.2基本编程过程q

设置渲染状态锁定顶点缓冲区

Direct3D的基本编程过程如图13-11所1

清除显示表面构造几何对象

示。下面各小节依次介绍Direct3D编程的基Q

本步骤与方法。开始场景解锁顶点缓冲区

13.2.3创建与初始化对象设置材质与光照或者纹

1

进行世界、观察与投影矩阵变换

为了使用Direct3D,你务必首先创建一0

个应用窗口,然后再创建与初始化Direct3D设置设备的流源与顶点格式V—

*

对象。利用这些对象所实现的COM接口来操绘制图元

作它们,以创建绘制场景所需的其它对象。

假如进行MFC编程,则能够省略创建窗结束场景

*

口这一步,而直接使用视图类所代表的客户

展现场景

区窗口。+

下面介绍的是初始化Direct3D的内容,清除对象

包含创建Direct3D对象、创建Direct3D设备图13-11Dircct3D编程的基本过程

与设置Direct3D设备的渲染(render着色)

状态等。

•创建Direct3D对象

可使用全局函数Direct3DCreate9来创建Direcl3D接口对象:

IDirect3D9*Direct3DCreate9(//成功返回指向!Direct3D9接口的指针,失败返回NULL

UINTSDKVersionH务必为D3D_SDK_VERSION

);

比如:EDirect3D9*g_pD3D=Direct3DCreate9(D3D_SDK_VERSION);

•创建Direct3D设备

可使用IDirect3D9接口的CreateDevice方法来创建设备(尾参数的返回值):

HRESULTCreateDevice(//成功返回D3D_OK(=0)

UINTAdapter,//显卡(displayadapter)序号,D3DADAPTER_DEFAULT为主显卡

D3DDEVTYPEDeviceType,//设备的枚举类型,通常取为D3DDEVTYPE_HAL

HWNDhFocusWindow,//焦点窗口句柄,可取为this->m_hWnd

DWORDBehaviorFlags,//操纵设备的创建行为之选项组合,能够使用硬件或者软

//的顶点处理,如D3DCREATE_SOFTWARE_VERTEXPROCESSING

D3DPRESENT_PARAMETERS*pPresentationParameters,//指向展现参数结构

//D3DPRESENT_PARAMETERS的指针

IDirect3DDevice9**ppRetumedDevicelnterface//代表被创建设备的

//IDirect3DDevice9返回接口的指针地址

);

其中,展现参数结构D3DPRESENT_PARAMETERS的定义为:

typedefstructD3DPRESENT_PARAMETERS{//展现参数结构

UINTBackBufferWidth,BackBufferHeight;//后台缓冲区的宽高(以像素为单位),

//对窗口模式可取为0,对全屏模式则务必与当前显卡枚举模式的一致

D3DFORMATBackBufferFormat;//后台缓冲区的格式,可取为

//D3DFMT_UNKNOWN(=0)

UINTBackBufferCount;〃后台缓冲区计数,可取为0~3,取0时等价于1

D3DMULTISAMPLE_TYPEMultiSampleType;//多样本类型,通常取为

//D3DMULTISAMPLE_NONE(=0)

DWORDMultiSampleQuality;//多样本质量水平,通常取0

D3DSS;〃交换效果,可取为

//D3DS(=1)、D3DS(=2)

//与D3DS(=3)等枚举值

HWNDhDeviceWindow;//设备窗口的句柄,对窗口模式可取为NULL(=0)

BOOLWindowed;//应用程序在窗口/全屏中运行时取TRUE/FALSE

BOOLEnableAutoDepthStencil;//同意自动深度模板,为TRUE贝|由Direct3D

//来管理应用程序的深度缓冲区

D3DFORMATAutoDepthStencilFormat;//自动深度模板格式,可取

//D3DFMT_D16、D3DFMT_D24s8与D3DFMT_D32等枚举值

DWORDFlags;//表现标志D3DPRESENTFLAG常数之一,可取为0

UINTFullScreen_RefreshRateInHz;//全屏时的屏幕刷新率,对窗口模式务必为0

UINTPresentationinterval;//前后台缓冲区交换的最大速率,可取为

//D3DPRESENT_INTERVAL_DEFAULT(=0)

}D3DPRESENT_PARAMETERS;

比如:

//设置创建D3D设备用的表现结构

D3DPRESENT_PARAMETERSd3dpp;//定义表现结构变量

ZeroMemory(&d3dpp,sizeof(d3dpp));//内存清零

d3dpp.Windowed=TRUE;〃窗口模式

d3dpp.S=D3DS;//放弃交换效果

d3dpp.BackBufferFormat=D3DFMTJJNKNOWN;//未知格式

d3dpp.EnableAutoDepthStencil=TRUE;//同意自动深度模板

d3dpp.AutoDepthStencilFormat=D3DFMT_D16;〃16位深度缓冲

LPDIRECT3DDEVICE9g_pd3dDevice;//定义D3D设备接口的指针

//创建D3D设备对象(获取D3D设备接口的指针)

g_pD3D->CreateDevice(D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL,

this->m_hWnd,D3DCREATE_SOFTWARE_VERTEXPROCESSING,

&d3dpp,&g_pd3dDevice);

•设置设备的渲染状态

利用IDirect3D9接口的CreateDevice方法所返回的设备接口IDirect3DDevice9的指针,

能够调用该接口的设置渲染(render着色)状态方法SetRenderStale,来初始化设备:

HRESULTSetRenderState(//成功返回D3DJDK(=0)

D3DRENDERSTATETYPEState,//设备状态

DWORDValue//设置值

);

其中,设备状态State,可取D3DRENDERSTATETYPE枚举的任意值,如D3DRS_ZENABLE

(同意Z缓冲)、D3DRS_FILLMODE(填充模式)、D3DRS_SHADEMODE(阴影模式)、

D3DRS_ALPHATESTENABLE(同意a测试)、D3DRS_CULLMODE(剔除模式)、

D3DRS_FOGENABLE(同意雾化)、D3DRS_LIGHTING(光照)、D3DRS_DITHERENABLE

(同意抖动)、。

比如:

g_p<13dDevice->SetRenderState(D3DRS_CULLMODE,D3DCULL_NONE);//关闭背面易U除

g_pd3dDevice->SetRenderState(D3DRS_ZENABLE,TRUE);//同意Z缓冲

g_pd3dDevice->SetRenderState(D3DRS_LIGHTING,FALSE);//关闭光照

13.2.4创建场景

三维场景是由若干物体(几何对象)构成的,

复杂的几何对象由多个简单的图元(点、线、三

角形与多边形等)所构成,而图元(primitive)

又是顶点(vertex)的集合。

3D图元通常是一个多面体,通常用其表面的图13-123D图元表面的三角网格

三角网格来表示,参见图13-12。因此最基本的图元是三角形与顶点。

创建场景中的几何对象,等价于建立表示该几何体的顶点集合。因此,务必先定义自己

的顶点结构并创建顶点缓冲区,然后在锁定顶点缓冲区后,再通过给顶点缓冲区中的各顶点

结构赋值来构造几何对象,最后解锁顶点缓冲区。

•定义顶点结构

Direct3D使用一种FVF(FlexibleVertexFormat可变顶点格式)结构来定义顶点,以满

足用户的不一致需要。在FVF结构CUSTOMVERTEX中,能够包含描述顶点的位置、RHW

(reciprocalhomogeneousw倒数齐次w,表示已变换顶点位置的齐次坐标w分量)、法向、

大小与(漫射、镜面反射)颜色等字段,具体内容由用户根据需要自己来确定,但是各字段

之间的相对顺序不能改变。

其中,顶点的位置与法向等字段,通常为三维点向量,能够用Direct3D的扩展三维向量

结构D3DXVECTOR3来表示:

typedefstructD3DXVECTOR3{FLOATx;FLOATy;FLOATz;}D3DXVECTOR3;

其中的FLOAT为float的typedef类型,定义在windef.h头文件中。而颜色通常使用DWORD

的typedef定义类型D3DCOLOR。

比如:

structCUSTOMVERTEX{//含位置、法向量与颜色的自定义顶点结构

D3DXVECTOR3position;//未变换顶点的3D位置

D3DXVECTOR3normal;//顶点的表面法向量

D3DCOLORcolor;//颜色

);或者:

structCUSTOMVERTEX{//含位置、颜色与纹理坐标的自定义顶点结构

D3DXVECTOR3position;//未变换顶点的3D位置

D3DCOLORcolor;//颜色

FLOATtu,tv;//纹理坐标

);或者:

structCUSTOMVERTEX{//含位置齐次坐标与颜色的自定义顶点结构

FLOATx,y,z,rhw;//已变换顶点的3D位置

DWORDcolor;//颜色

);

用户在定义了自己的顶点结构类型后,还需要定义一个对应的(宏)常量,来描述该结

构的字段内容。该(宏)常量由若干表示顶点格式的标志位符号常量(参见表13-1)的位或

者组合而成。

表13-1顶点数据格式标志

符号常量值数据类型描述

D3DFVF_XYZ0x002float,float,float未转换的顶点坐标

D3DFVF_XYZRHW0x004float,float,float,float已转换的顶点坐标

D3DFVF_XYZB1~5OxOO6/8/a/c/e】-3个float含权重i的顶点坐标

D3DFVF.XYZW0x4002float,float,float,float已转换与裁剪的顶点坐标

D3DFVF_NORMAL0x010float,float,float顶点的法线

D3DFVF_PSIZE0x020float点大小

D3DFVF_DIFFUSE0x040DWORD(ARGB)漫射颜色

D3DFVF_SPECULAR0x080DWORD(ARGB)镜面反射颜色

D3DFVF_TEX0~80x0-8001-4个floati重纹理映射

比如:

#defineD3DFVF_CUSTOMVERTEX(D3DFVF_XYZ|D3DFVF_NORMAL|D3DFVF_DIFFUSE)

或者:#defineD3DFVF_CUSTOMVERTEX(D3DFVF_XYZ|D3DFVF_DIFFUSE

D3DFVF_TEX1)

或者:constDWORDFVF=(D3DFVF_XYZRHW|D3DFVF_DIFFUSE);

•创建顶点缓冲区

在定义了顶点结构后,就能够创建顶点缓冲区了,这能够由IDirect3DDevice9接口的

CreateVertexBuffer方法来完成:

HRESULTCreateVertexBuffer(//成功返回D3D_OK(=0)

UINTLength,//缓冲区的字节大小,通常为n*sizeof(CUSTOMVERTEX)

DWORDUsage,//缓冲区用法的附加属性标志,通常为0

DWORDFVF,//顶点结构格式常量

D3DPOOLPool,//缓冲区所在的内存池类型(D3DPOOL枚举值)

IDirect3DVertexBuffer9**ppVertexBuffer,//返回被创建的顶点缓冲区指针

HANDLE*pSharedHandle//保留,设为NULL

);

其中,内存池类型D3DPOOL枚举的定义为:

typedefenumD3DPOOL{//内存池类型枚举

D3DPOOL_DEFAULT=0,//AGP存储器或者显存

D3DPOOL_MANAGED=1J/AGP存储器或者显存,且在系统内存中还有一份拷贝

D3DPOOL_SYSTEMMEM=2,//系统内存

D3DPOOL_SCRATCH=3,//系统内存中的临时池

D3DPOOL_FORCE_DWORD=0x7fffffff//未使用(强制该枚举被编译成32位)

)D3DPOOL;

比如:g_pd3dDevice->CreateVertexBuffer(100*sizeof(CUSTOMVERTEX),0,

D3DFVF_CUSTOMVERTEX,D3DPOOL_DEFAULT,&g_pVB,NULL);

或者:g_pd3dDevice->CreateVertexBuffer(3*sizeof(CUSTOMVERTEX),0,FVF,

D3DPOOL_MANAGED,&g_pVB,NULL);

•构造点集

创建三维场景中的几何对象,需要计算与构造描述该几何对象的点集。具体做法是:先

定义一个顶点指针•(用于操作顶点数组);再调用Lock方法来获取顶点缓冲区的首地址(赋

值给顶点指针),并锁定该区域仅供当前操作使用;然后利用该顶点指针,将计算的顶点结

构值填入顶点缓冲区,从而构造出几何对象;最后调用Unlock方法解锁顶点缓冲区。

IDirect3DVertexBuffer9接口的Lock与Unlock方法的定义为:

HRESULTLock(//成功返回D3D_OK(=0)

UINTOffsetToLock,//锁定的偏移地址

UINTSizeToLock,//锁定的字节数

VOID**ppbData,//返回被锁定的缓冲区头的指针

DWORDFlags//锁定方式标志,可为0或者下列符号常量的组合:

//D3DLOCKDISCARD、D3DLOCKNODIRTYUPDATE,

//D3DL0CK_N0SYSL0CK.D3DL0CK_READ0NLY>

//D3DLOCK_NOOVERWRITE

);

HRESULTUnlock();//成功返回D3D_OK(=0)

比如:

CUSTOMVERTEX*pVertices;

g_pVB->Lock(0,0,(void**)&pVertices,0);

……〃给顶点缓冲区中的各顶点结构赋值(构造几何对象的点集)

g_pVB->Unlock();

13.2.5矩阵变换

描述单个物体(3D几何对象)通常使用的是本地相对坐标。因此,在渲染之前,需要

将它们都转换为描述场景的统一世界空间(worldspace)坐标,这对应于世界矩阵变换。

为了将三维场景显示在二维屏幕上,还需要选择一个观察点(眼睛/摄像机)与观察角度

(方向/坐标)(对应于观察坐标矩阵变换),并将3D场景投影到一个2D平面(屏幕)上

(对应于投影矩阵变换),还要将超出屏幕的部分去掉(裁剪),也能够将场景投射到屏幕

的某个矩形区域中(视口缩放)。参见图13-13。

下面依次对这些变换加以介绍,这需要首先介绍Direct3D中的矩阵定义与变换方法。

•矩阵与变换

在Direct3D中,定义了矩阵(matrix)结构D3DXMATRIX:

typedefstructD3DXMATRIX{//矩阵结构

struct{//注意,C/C++的变量名可下列划线开头(但不能以数字开头)

FLOAT_11;FLOAT_12;FLOAT_13;FLOAT_14;

FLOAT_21;FLOAT_22;FLOAT_23;FLOAT_24;

FLOAT_31;FLOAT_32;FLOAT_33;FLOAT_34;

FLOAT_41;FLOAT_42;FLOAT_43;FLOAT_44;

);‘_口_12_13_14、

)D3DXMATRIX;_21_22_23_24

对应于4*4的浮点矩阵:_31_32_33_34

\—41—42—43―44/,

在Direct3D中,还定义了一个对IntelP4CPU运算进行了优化的16字节对齐的矩阵结

构(从D3DXMATRIX派生的C++结构对象):

typedefstruct_D3DXMATRIXA16:publicD3DXMATRIX{//16字节对齐矩阵结构

_D3DXMATRIXA16();

_D3DXMATRIXA16(CONSTFLOAT*f);

_D3DXMATRIXA16(CONSTD3DMATRIX&m);

_D3DXMATRIXA16(FLOAT」1,FLOAT_12,FLOAT_I3,FLOAT_14,

FLOAT_21,FLOAT_22,FLOAT_23,FLOAT_24,

FLOAT_31,FLOAT_32,FLOAT_33,FLOAT_34,

FLOAT_41,FLOAT_42,FLOAT_43,FLOAT_44);

void*operatornew(size_ts);

void*operatornew[](size_ts);

voidoperatordelete(void*p);

voidoperatordelete[l(void*p);

struct_D3DXMATRIXA16&operator=(CONSTD3DXMATRIX&rhs);

}_D3DXMATRIXA16;

typedefD3DX_ALIGN16_D3DXMATRIXA16D3DXMATRIXA16;

Direct3D还提供了若干全局矩阵函数,如:

D3DXMATRIX*D3DXMatrixIdentity(D3DXMATRIX*pOut);//仓I建单位矩阵

FLOATD3DXMatrixDeterminant(CONSTD3DXMATRIX*pM);//返回矩阵的行歹U式值

D3DXMATRIX*D3DXMatrixInverse(//计算逆矩阵

D3DXMATRIX*pOut,//结果矩阵

FLOAT*pDeterminant,//行歹!J式值,可置为NULL

CONSTD3DXMATRIX*pM//原矩阵

);

D3DXMATRIX*D3DXMatrixMultiply(//两矩阵相乘

D3DXMATRIX*pOut,//结果矩阵

CONSTD3DXMATRIX*pMl,〃矩阵1

CONSTD3DXMATRIX*pM2//矩阵2

);

矩阵变换(transform)的实施,可使用IDirect3DDevice9接口提供的SetTransform方法:

HRESULTSetTransform(//成功返回D3D_0K(=0)

D3DTRANSFORMSTATETYPEState,//变换类型状态值

CONSTD3DMATRIX*pMatrix//变换矩阵

);

其中State的取值可为D3DTRANSFORMSTATETYPE枚举类型或者

D3DTS_WORLDMATRIX宏的值。如:D3DTS_VIEW(=2,观察变换)>D3DTS_PROJECTION

(=3,投影变换)、D3DTSTEXTURE0-7(=16-23,纹理变换)、D3DTSWORLD(=256,

世界变换)等。

比如:

D3DXMATRIXA16matWorld;//定义矩阵结构对象

D3DXMatrixIdentity(&matWorld);//变成单位矩阵

……〃对matWorld进行其他矩阵变换

g_pd3dDevice->SetTransfonn(D3DTS_WORLD.&matWorld);//实施变换

•世界变换

通常用每个物体各自的本地坐标来描述所对应的3D几何对象,而用统一的世界坐标来

描述整个场景(参见图13-14),渲染之前需要将顶点从本地坐标系转换到世界坐标系。称

这种从本地坐标到世界坐标的转换为世界变换(worldtransform),世界变换包含平移

(translation)、旋转(rotation)与缩放(scaling)等三种具体变换类型,它们都可用对应的

矩阵变换来表示。

下面是Direct3D提供的若干世界矩阵变换的全局函数:

D3DXMATR1X*D3DXMatrixTranslation(//平移变换

D3DXMATRIX*pOut,//原/结果矩阵

FLOATx,//x偏移量

FLOATy,//y偏移量

FLOATz//z偏移量

D3DXMATRIX*D3DXMatrixRotationX[Y/Z](//(绕x[y/z]轴的)旋转变换

D3DXMATRIX*pOut,//原/结果矩阵

FLOATAngle//旋转角度(弧度单位)

);

D3DXMATRIX*D3DXMatrixScaling(//缩放变换

D3DXMATRIX*pOut,//原/结果矩阵

FLOATsx,//x方向的比例因子

FLOATsy,〃y方向的比例因子

FLOATsz//z方向的比例因子

);

能够通过这些函数,获得所需要的各类变换矩阵。最后,还须使用D3DTS_W0RLD状

态值,来调用IDirect3DDevice9接口的SetTransform方法,以实施最终矩阵所对应的世界变

换。比如:

D3DXMatrixTranslation(&matWorld,m_xPos,m_yPos,m_zPos);//平移

D3DXMatrixRotationX(&matWorld,m_fPitch);〃绕x轴旋转

g_pd3dDevice->SetTransfomi(D3DTS_W0RLD,&matWorld);//

实施世界变换

•观察变换

观察变换(viewtransform),可在世界坐标系(x、,,y、*Zw)中设置与改变观察者的位置与

方向,将世界空间中的顶点转换到摄影空间(cameraspace)(xe,ye,Ze),参见图13-15。

在Direct3D中,观察矩阵由全局助手函数D3DXMatrixLookAtLH(Left-Handed,左手

系)与D3DXMatrixLookAtRH(Right-Handed,右手系)来创建:

图13-15通1察变横

D3DXMATRIX*D3DXMatrixLookAtLH(//创建左手系观察-

矩阵(右手系:LH-RH)

D3DXMATRIX*pOut,//结果

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论