多媒體技術(shù)之Direct編程入門_第1頁
多媒體技術(shù)之Direct編程入門_第2頁
多媒體技術(shù)之Direct編程入門_第3頁
多媒體技術(shù)之Direct編程入門_第4頁
多媒體技術(shù)之Direct編程入門_第5頁
已閱讀5頁,還剩50頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

多媒體技術(shù)之DirectX編程入門

第13章DirectX編程入門

DirectX是微軟公司為編寫游戲與其他高性能多媒體應(yīng)用程序而開發(fā)的一組高級的

Windows低層API,它包含了對圖(圖形、視頻與三維動畫)、聲音(聲效與音樂)、輸入

設(shè)備與網(wǎng)絡(luò)游戲等的支持。

本章先概述DirectX的基本內(nèi)容,然后介紹DirectX的要緊組件Direct3D4DirectSound

的基本編程方法,并給出若干具體編程實例。

13.1DirectX概述

本節(jié)簡單介紹DureclX的進展歷史、版本與功能的演化、結(jié)構(gòu)與模塊劃分。

DurectX是Windows的一種多媒體APL它在保持設(shè)備無關(guān)性的同時,能夠讓應(yīng)用程序

直接操縱多媒體設(shè)備,從而能充分利用硬件的功能,因此可獲得最高的性能。

DurectX自從推出以來,就始終處在快速進展的過程之中。它已經(jīng)經(jīng)歷了多個版本,其

模塊與功能也一直在不斷地增加與完善。

DirectX是一種基于COM的系統(tǒng),要緊由硬件抽象層HAL與硬件模擬層HEL所構(gòu)成。

DurectX被分成若干個組件模塊,涵蓋了多媒體應(yīng)用的方方面面。而且這些組件的數(shù)目、名

稱與功能,也是隨著其版本的演化而有所增減、改變與加強。

13.1.1歷史

微軟公司于1990年5月推出的Windows3.0大獲成功,它是一種與設(shè)備無關(guān)的具有圖形

用戶界面(GUI)的操作系統(tǒng)。后來又于1992年3月推出Windows3.1,提供了對多媒體的

支持。只是Windows的與設(shè)備無關(guān)的設(shè)計思想,盡管使得Windows向程序員提供了一個獨

立于硬件的軟件開發(fā)優(yōu)秀平臺,但它不讓應(yīng)用程序直接操作顯卡與聲卡等多媒體硬件,這樣

就降低了多媒體應(yīng)用程序(特別是計算機游戲)的運行效率,比如限制了動畫的幀率、不提

供混音功能等。因此當時的Windows并不是一個能夠開發(fā)與運行高效多媒體程序(如3D游

戲)的理想環(huán)境,逼迫PC游戲開發(fā)商只好繞開Windows而仍舊開發(fā)DOS下的游戲。

為了改變這種難堪的局面,促使游戲界放棄DOS而使用Windows,微軟需要在設(shè)備無

關(guān)性與高性能之間取得某種平衡,決定為Windows添加一種高性能的動畫機制(與后來的輸

入與音響等),因此于1995年推出了GameSDK,后來改名為DirectX。其中的Direct指能

夠直接訪問多媒體硬件;X指它的不一致構(gòu)成部分,如Direct3D、DireclSound、Directlnput

與DirectPlay等。

13.1.2版本與功能

由于DirectX務(wù)必支持多媒體設(shè)備的最新技術(shù)與功能,而多媒體硬件(特別是顯卡[的3D

性能])與技術(shù)始終處在高速進展過程中,因此DirectX的技術(shù)與版本也同樣在不斷地進展與

演變,其中進展最快的是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!技術(shù)、性能較5.0有提高。在1999年2月3日推出的6.1版中,添加了

DirectMusic模塊;

■7.0——1999年9月22日:改進3D圖形與聲音、性能更快,為Direct3DAPI引入硬件

傳送、光照與紋理壓縮、與硬件加速,引入D3DX工具庫。使用Creative公司的EAX

技術(shù)改進3D聲音的算法(次版本有7.0a與7.1);

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

的性能有了本質(zhì)上的飛躍(引入頂點/像素shader[著色引擎/光照模型]、支持硬件點精靈

與三維體紋理),將DirectMusic與DirectSound更緊密地集成在一起構(gòu)成DirectXAudio,

更新了Directlnput與DirectPlay,添加了DirectShow、拋棄了其余的DirectXMedia模塊。

2001年11月II日推出的8.1版,被集成在WindowsXP中銷售,該版本添加了從

DirectShow分離出的DMO(DirectXMediaObjects媒體對象)組件模塊。它還支持許

多新的圖形特性,如像素著色引擎的1.27.4版、動態(tài)/高分辨率紋理、新3D擴展方法

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

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

如將DirectDraw的功能并入到Direct3D之中,支持頂點與像素著色引擎的新版本2.0

與3.0,引入裁剪測試、位移貼圖與多元紋理,支持128位浮點著色精度與根據(jù)顯示器

自動調(diào)整Y值等。也添加若干新特性到Directlnput、DirectPlay>DirectSound與

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

DirectX的最后一個以數(shù)字與字母命名的版本是2004年8月9日推出的9.0c,后來又于

2004年10月、2005年的2/4/6/8/10月分別推出了它的多個升級版。從2005年12月推

出的DirectX開始,其版本的命名發(fā)生了變化:主版本號改為DX,次版本改為公布的

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

應(yīng)用程序

updates)o當前最新版本為

2006年10月11日推出的DX

October20060它們都包含了

(于2002年推出的專

為.NET框架設(shè)計的)托管

(Managed)DirectX,將原

先DirectX多個分離的COM

模塊集成到了一個容易使用PC硬件子系統(tǒng)

的單一CLR文件之中。

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

一代操作系統(tǒng)WindowsVista中,而不再將其作為一個額外的模塊了。但是會有Direcl3D

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

到WindowsVista中。另外,作為學(xué)生與業(yè)余愛好者的DirectX替代產(chǎn)品,微軟公司于

2004年3月24日宣布了用于托管運行環(huán)境下計算機游戲的設(shè)計、開發(fā)與管理的框架與

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

GameStudioExpress的1.0版,可用于Windows與Xbox360游戲的開發(fā)。

13.1.3結(jié)構(gòu)

DirectX是一種基于COM(ComponentObjectModel,組件對象模型)的系統(tǒng),它既不

屬于驅(qū)動程序?qū)?,也不屬于?yīng)用層。DirectX的要緊設(shè)計目標是在提供某種設(shè)備獨立性的同時

獲取高速度,為此微軟公司為DirectX設(shè)計了如圖13-1所示的體系結(jié)構(gòu)。其中:

■HAL=HardwareAbstractLayer(硬件抽象層)----負責檢測本機的硬件功能,并

以一種獨立于設(shè)備的方

式提供這些功能;圖13"DirectX子系統(tǒng)

■HEL=HardwareEmulationLayer(硬件模擬層)---負責提供DirectX功能中本機

硬件不支持部分的模擬實現(xiàn)。

但是從&0版起,DirectX就不再提供硬件模擬層HEL了,需要開發(fā)商、第三方或者

自己來編寫一個PSD(PluggableSoftwareDevice可插式軟件設(shè)備)連到DirectX提供的HEL

接口上,稱之為參考設(shè)備。但是現(xiàn)在很少有這樣的PSD可用,因此新版本的DirectX是嚴

重依靠于硬件的。

13.1.4構(gòu)成

DirectX由多個(COM組件)模塊構(gòu)成,而且隨著版本的演化,這些模塊也在不斷地增

減、合并與改變。最新的DirectX組件的模塊構(gòu)成如圖13-2所示,括號中的數(shù)字為該模塊被

首次引進(或者移出)的版本號。

下面是DirectX的要緊構(gòu)成模塊的簡單介紹:

■DirectXGraphics(圖形)----包含DirectDraw與Direct3D:

?DirectDraw(繪制)——二維圖形繪制(高速位圖傳送/視頻與2D動畫)。

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

?Direct3D(三維)----三維圖形繪制。分成保留(retained)與立即(immediate)

兩種模式(mode):保留模式是一種高層API,建立在立即模式之上,使用

起來方便容易,但是效率不高,適合于初學(xué)者;立即模式則是一種底層API,

使用復(fù)雜,但是其效率比保留模式高得多。大多數(shù)DirectX應(yīng)用程序,特別

是計算機游戲,都是使用立即模式進行開發(fā)。自從6.0版以來,保留模式API

的進展停滯不前,而立即模式API的進展卻日新月異。不論是保留模式還是

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

包含了DirectDraw,它像OpenGL一樣也具有二維圖形繪制的功能。Direct3D

的下一個版本為Durect3D10,為WindowsVista的一個有機構(gòu)成部分。

?D3DX(Direct3D擴展)——為Direct3D服務(wù)的有用工具庫,執(zhí)行公

共的數(shù)學(xué)計算與一些復(fù)雜的任務(wù),包含若干簡化3D模型使用的類,如

粒子系統(tǒng)(particlesystem)。D3DX由動態(tài)鏈接庫(DLL)提供。

?DXUT(編程框架)——建立在Direct3DAPI之上的樣例框架,也叫

通用文件框架,能夠幫助程序員減少在繁瑣的平凡工作(如創(chuàng)建窗口、

創(chuàng)建設(shè)備、處理Windows消息與設(shè)備事件等)上所花的時間。

圖13-2DirectX的構(gòu)成模塊

■DirectXAudio(音頻)----包含DirectSound與DirectMusic:

?DirectSound(聲音)——要緊針對波形音頻,底層接口。可用于開發(fā)播放

與捕捉波形音頻的高性能立體與三維(DirectSound3D)音頻應(yīng)用程序。在下一

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

CreationTool微軟跨平臺音頻生成工具)來代替。

?DirectMusic(音樂)----要緊針對MIDI音樂,高層接口。為基于波形、

MIDI聲音或者DirectMusic生成器所制造的動態(tài)內(nèi)容之音樂與非音樂聲道提

供一個完整的解決方案。

?XACT(游戲音頻)----XACT(MicrosoftCross-PlatformAudioCreation

Tool,微軟跨平臺音頻生成工具),是一種多人合作的音頻設(shè)計工具與有關(guān)

API,用于游戲的動態(tài)音頻開發(fā)。

■Directlnput(輸入)——提供對各類輸入設(shè)備的支持,包含對受力反饋

(force-feedback)技術(shù)的全面支持。在下一代DirectX中,Directlnput將被XInput代

替。

■DirectPlay(游戲)——提供對多人網(wǎng)絡(luò)游戲的支持。在最新的DirectX版本中,

微軟公司反對(deprecate)使用DirectPlay,而建議改用WindowsSockets與Windows

FirewallAPI來代替。在下一代DirectX中,DirectPlay可能會被XboxLive代替。

■DirectSetup(安裝)——提供DirectX組件的一次性調(diào)用安裝的一個簡單API(自

動安裝DirectX驅(qū)動程序)。

■DirectShow(展示)——提供多媒體(音視頻)流的高質(zhì)量捕捉與重放。在8.0

版之前,DirectShow是DirectXMedia的一個構(gòu)成模塊。到8.0版時,由于DirectX

SDK拋棄了DirectXMedia,因此才將DirectShow集成到了DirectX之中。在DirectX

9.0c的2005年4月升級版中,DirectShow又被移出DirectX,放入微軟公司的平臺

SDK之中。

■DirectXMediaObjects(媒體對象DM0)——基于COM的多媒體與數(shù)據(jù)流組件,

支持音視頻的編解碼器與特效。是在DirectX的8.1版時,從DirectShow分出的,

其功能類似于DirectShow的過濾器。

■DirectXMedia(媒體)——是一個用于流媒體應(yīng)用的外部API集合。在DirectX6.0

之前,DirectXMediaSDK與DirectXSDK是兩個分離的SDK?在6.0版時DirectX

MediaSDK被集成到DirectXSDK之中。DirectXMedia的運行模塊,被集成到

Windows與IE之中。到了8.0版時,DirectXMedia又被DirectXSDK拋棄(其核

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

推出的WindowsMediaSDK所代替。

?DirectXTransform(變換)——用于產(chǎn)生二、三維圖形的各類效果,如a混

色與表面彎曲等。

?DirectAnimation(動畫)---集成多種媒體類型來創(chuàng)建復(fù)雜動畫,并可用

作網(wǎng)頁內(nèi)容。

?DirectXVideoAcceleration(視頻加速DXVA)——利用硬件加速二維視頻

的解碼操作。

?Direct3DRetainedMode(保留模式)----Direct3D的保留模式是一種高層

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

適合于初學(xué)者。

?DirectShow(展示)----支持音視頻流的高質(zhì)量采集與重放。

13.1.5編程準備

為了用VC編寫DirectX應(yīng)用程序,務(wù)必先下載并安裝DirectXSDK,并進行必要的頭

/庫文件路徑與鏈接庫的設(shè)置。

下面以WindowsXP中文版環(huán)境下的VisualC++2005中文版與DirectX9.0cAugust

2006SDK為例,介紹進行具體的DirectX編程之前,所需做的必要準備工作。

?下載并安裝DirectXSDK

能夠從微軟公司的官方網(wǎng)站()下載最新的DirectXSDK,如dxsdk_dec2006.exe

(448MB)。安裝完成后,會在安裝目錄(缺省為“C:\ProgramFiles\MicrosoftDirectXSDK

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

與Utilities等多個子目錄。安裝時還會為Windows操作系統(tǒng)生成名為“MicrosoftDirectXSDK

((December2006)"的程序組,包含多個子程序組與程序。

安裝程序會將DirectXSDK的幫助文檔,也安裝到VisualStudio2005的幫助系統(tǒng)內(nèi),位

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

C++"與"DirectXSDK((December2006)Managed”兩個幫助子目錄。

?設(shè)置包含與庫路徑

在VisualStudio2005中文版的IDE中,選“工具/選項”菜單項,打開“選項”對話框

(參見圖13-5)1,

圖13-5VisualStudio2005的“選項”對話框

再選該對話框左邊的“項目與解決方案/VC++目錄”路徑,在右邊的“顯示下列內(nèi)容的

目錄”欄的下拉式列表框中,選“包含文件”項。按該欄下面的“新行”鈕凈L則在其下

方的顯示欄中會出現(xiàn)新行,再按新行右端的帶省略號的瀏覽鈕匚~1在彈出的“選擇目錄”

對話框中,選擇DirectXSDK的Include目錄所在的路徑"C:\ProgramFiles\MicrosoftDirectX

SDK(August2006)\Includew,然后按“打開”關(guān)閉“選擇目錄”對話框。結(jié)果參見圖13-6。

圖13-6設(shè)置DirectX的“包含文件”的路徑

可類似選擇“庫文件”項,添加庫文件路徑uC:\ProgramFiles\MicrosoftDirectXSDK

(August2006)\Lib\X86^^,結(jié)果參見圖13-7。最后,按“確定”鈕,關(guān)閉“選項”對話框。

圖13-7設(shè)置DirectX的“庫文件”的路徑

注意,對DirectX的包含路徑與庫路徑的設(shè)置,對所有項目都有效。

?設(shè)置鏈接庫

先創(chuàng)建一個DirectX應(yīng)用程序的MFC單文檔項目(如DxTest),再在VS05的IDE中,

選“項目/屬性”,打開“DxTest屬性頁”對話框。在左上角的“配置”欄中,選中“所有配

置”項;再選左邊的路徑“配置屬性/鏈接器/輸入”,在右邊的“附加依靠項”欄中,添加

d3d9.libd3dx9.1ibd3dxof.libdsound.libdxguid.libwinmm.lib等鏈接庫(在多個庫文件之間,用

空格分隔)。具體添加什么DirectX庫,與具體應(yīng)用程序所使用的DirectX模塊有關(guān),你也能

夠查看DirectX的庫目錄。最后,按“應(yīng)用”鈕與“確定”鈕,關(guān)閉屬性頁對話框。參見圖

13-8。

圖13-8設(shè)置DirectX的鏈接庫

注意,對DirectX鏈接庫的設(shè)置,只對VC05中當前打開的單個項目有效。

在安裝了DirectXSDK,并設(shè)置好文件路徑與鏈接庫后,就能夠開始編寫具體的DirectX

應(yīng)用程序了。

DirectX的組件眾多、功能強大、編程復(fù)雜,完整的介紹需要幾本大部頭的專著才行,

本書只準備簡單介紹DirectX的最要緊模塊---Direct3D與DirectSound編程的最基本內(nèi)容。

13.2Direct3D編程簡介

Direct3D(直接三維)是DirectX的核心模塊,新版本的Direct3D中還包含原先

DirectDraw模塊的2D功能。因此,現(xiàn)在的Direct3D是DirectXGraphics的唯一模塊,具有

DirectX(二、三維)圖形的全部功能。

13.2.1流水線與設(shè)備

Direct3D用圖形流水線(graphicspipeline)來處理與渲染場景(renderscene),而Direcl3D

設(shè)備(device)是執(zhí)行變換(transformation)與光照(lighting)等操作的渲染部件。

?Direct3D圖形流水線

可通過Direct3D圖形流水線來充分利用硬件性能,以提供高效處理與繪制Direct3D場

景到顯示器的能力。圖13-9為流水線(pipeline,管線/管道/流程)的構(gòu)成模塊框圖。

圖13-9Direct3D圖形流水線

?Direct3D設(shè)備

Direct3D設(shè)備(device)是Direct3D的渲染部件,它封裝與存儲渲染狀態(tài)。另外,它還

執(zhí)行變換與光照等操作,同時光柵化圖像到表面(如屏幕)。在結(jié)構(gòu)上,Direcl3D設(shè)備包含

變換模塊(transformationmodule)、光照模塊Direct3D設(shè)備架構(gòu)

(lightingmodule)與光柵化器(rasterizer)。圖13-10變換模塊||光照模塊||光柵化器

為Direct3D的設(shè)備架構(gòu)(architecture)。

圖13-10Di〃ct3D設(shè)備架構(gòu)

當前,Direct3D有兩種要緊的設(shè)備類型:

■HAL設(shè)備(haldevice)------具有硬件加速的光柵化(rasterization),可同時使用硬件

與軟件的頂點處理進行著色(shading)。

■參考設(shè)備(referencedevice)——由軟件驅(qū)動程序提供,現(xiàn)在要緊用于性能測試。

具有軟件特性的參考設(shè)備不一定能提供與硬件等同的性能,因此應(yīng)用程序務(wù)必總是查

詢設(shè)備的能力以確定其支持什么特性。創(chuàng)建Direct3D對象定義頂點格式

創(chuàng)建Direct3D設(shè)備對象—?創(chuàng)建頂點緩沖區(qū)

13.2.2基本編程過程q

設(shè)置渲染狀態(tài)鎖定頂點緩沖區(qū)

Direct3D的基本編程過程如圖13-11所1

清除顯示表面構(gòu)造幾何對象

示。下面各小節(jié)依次介紹Direct3D編程的基Q

本步驟與方法。開始場景解鎖頂點緩沖區(qū)

13.2.3創(chuàng)建與初始化對象設(shè)置材質(zhì)與光照或者紋

1

進行世界、觀察與投影矩陣變換

為了使用Direct3D,你務(wù)必首先創(chuàng)建一0

個應(yīng)用窗口,然后再創(chuàng)建與初始化Direct3D設(shè)置設(shè)備的流源與頂點格式V—

*

對象。利用這些對象所實現(xiàn)的COM接口來操繪制圖元

作它們,以創(chuàng)建繪制場景所需的其它對象。

假如進行MFC編程,則能夠省略創(chuàng)建窗結(jié)束場景

*

口這一步,而直接使用視圖類所代表的客戶

展現(xiàn)場景

區(qū)窗口。+

下面介紹的是初始化Direct3D的內(nèi)容,清除對象

包含創(chuàng)建Direct3D對象、創(chuàng)建Direct3D設(shè)備圖13-11Dircct3D編程的基本過程

與設(shè)置Direct3D設(shè)備的渲染(render著色)

狀態(tài)等。

?創(chuàng)建Direct3D對象

可使用全局函數(shù)Direct3DCreate9來創(chuàng)建Direcl3D接口對象:

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

UINTSDKVersionH務(wù)必為D3D_SDK_VERSION

);

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

?創(chuàng)建Direct3D設(shè)備

可使用IDirect3D9接口的CreateDevice方法來創(chuàng)建設(shè)備(尾參數(shù)的返回值):

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

UINTAdapter,//顯卡(displayadapter)序號,D3DADAPTER_DEFAULT為主顯卡

D3DDEVTYPEDeviceType,//設(shè)備的枚舉類型,通常取為D3DDEVTYPE_HAL

HWNDhFocusWindow,//焦點窗口句柄,可取為this->m_hWnd

DWORDBehaviorFlags,//操縱設(shè)備的創(chuàng)建行為之選項組合,能夠使用硬件或者軟

//的頂點處理,如D3DCREATE_SOFTWARE_VERTEXPROCESSING

D3DPRESENT_PARAMETERS*pPresentationParameters,//指向展現(xiàn)參數(shù)結(jié)構(gòu)

//D3DPRESENT_PARAMETERS的指針

IDirect3DDevice9**ppRetumedDevicelnterface//代表被創(chuàng)建設(shè)備的

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

);

其中,展現(xiàn)參數(shù)結(jié)構(gòu)D3DPRESENT_PARAMETERS的定義為:

typedefstructD3DPRESENT_PARAMETERS{//展現(xiàn)參數(shù)結(jié)構(gòu)

UINTBackBufferWidth,BackBufferHeight;//后臺緩沖區(qū)的寬高(以像素為單位),

//對窗口模式可取為0,對全屏模式則務(wù)必與當前顯卡枚舉模式的一致

D3DFORMATBackBufferFormat;//后臺緩沖區(qū)的格式,可取為

//D3DFMT_UNKNOWN(=0)

UINTBackBufferCount;〃后臺緩沖區(qū)計數(shù),可取為0~3,取0時等價于1

D3DMULTISAMPLE_TYPEMultiSampleType;//多樣本類型,通常取為

//D3DMULTISAMPLE_NONE(=0)

DWORDMultiSampleQuality;//多樣本質(zhì)量水平,通常取0

D3DSS;〃交換效果,可取為

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

//與D3DS(=3)等枚舉值

HWNDhDeviceWindow;//設(shè)備窗口的句柄,對窗口模式可取為NULL(=0)

BOOLWindowed;//應(yīng)用程序在窗口/全屏中運行時取TRUE/FALSE

BOOLEnableAutoDepthStencil;//同意自動深度模板,為TRUE貝|由Direct3D

//來管理應(yīng)用程序的深度緩沖區(qū)

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

//D3DFMT_D16、D3DFMT_D24s8與D3DFMT_D32等枚舉值

DWORDFlags;//表現(xiàn)標志D3DPRESENTFLAG常數(shù)之一,可取為0

UINTFullScreen_RefreshRateInHz;//全屏?xí)r的屏幕刷新率,對窗口模式務(wù)必為0

UINTPresentationinterval;//前后臺緩沖區(qū)交換的最大速率,可取為

//D3DPRESENT_INTERVAL_DEFAULT(=0)

}D3DPRESENT_PARAMETERS;

比如:

//設(shè)置創(chuàng)建D3D設(shè)備用的表現(xiàn)結(jié)構(gòu)

D3DPRESENT_PARAMETERSd3dpp;//定義表現(xiàn)結(jié)構(gòu)變量

ZeroMemory(&d3dpp,sizeof(d3dpp));//內(nèi)存清零

d3dpp.Windowed=TRUE;〃窗口模式

d3dpp.S=D3DS;//放棄交換效果

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

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

d3dpp.AutoDepthStencilFormat=D3DFMT_D16;〃16位深度緩沖

LPDIRECT3DDEVICE9g_pd3dDevice;//定義D3D設(shè)備接口的指針

//創(chuàng)建D3D設(shè)備對象(獲取D3D設(shè)備接口的指針)

g_pD3D->CreateDevice(D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL,

this->m_hWnd,D3DCREATE_SOFTWARE_VERTEXPROCESSING,

&d3dpp,&g_pd3dDevice);

?設(shè)置設(shè)備的渲染狀態(tài)

利用IDirect3D9接口的CreateDevice方法所返回的設(shè)備接口IDirect3DDevice9的指針,

能夠調(diào)用該接口的設(shè)置渲染(render著色)狀態(tài)方法SetRenderStale,來初始化設(shè)備:

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

D3DRENDERSTATETYPEState,//設(shè)備狀態(tài)

DWORDValue//設(shè)置值

);

其中,設(shè)備狀態(tài)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);//關(guān)閉背面易U除

g_pd3dDevice->SetRenderState(D3DRS_ZENABLE,TRUE);//同意Z緩沖

g_pd3dDevice->SetRenderState(D3DRS_LIGHTING,FALSE);//關(guān)閉光照

13.2.4創(chuàng)建場景

三維場景是由若干物體(幾何對象)構(gòu)成的,

復(fù)雜的幾何對象由多個簡單的圖元(點、線、三

角形與多邊形等)所構(gòu)成,而圖元(primitive)

又是頂點(vertex)的集合。

3D圖元通常是一個多面體,通常用其表面的圖13-123D圖元表面的三角網(wǎng)格

三角網(wǎng)格來表示,參見圖13-12。因此最基本的圖元是三角形與頂點。

創(chuàng)建場景中的幾何對象,等價于建立表示該幾何體的頂點集合。因此,務(wù)必先定義自己

的頂點結(jié)構(gòu)并創(chuàng)建頂點緩沖區(qū),然后在鎖定頂點緩沖區(qū)后,再通過給頂點緩沖區(qū)中的各頂點

結(jié)構(gòu)賦值來構(gòu)造幾何對象,最后解鎖頂點緩沖區(qū)。

?定義頂點結(jié)構(gòu)

Direct3D使用一種FVF(FlexibleVertexFormat可變頂點格式)結(jié)構(gòu)來定義頂點,以滿

足用戶的不一致需要。在FVF結(jié)構(gòu)CUSTOMVERTEX中,能夠包含描述頂點的位置、RHW

(reciprocalhomogeneousw倒數(shù)齊次w,表示已變換頂點位置的齊次坐標w分量)、法向、

大小與(漫射、鏡面反射)顏色等字段,具體內(nèi)容由用戶根據(jù)需要自己來確定,但是各字段

之間的相對順序不能改變。

其中,頂點的位置與法向等字段,通常為三維點向量,能夠用Direct3D的擴展三維向量

結(jié)構(gòu)D3DXVECTOR3來表示:

typedefstructD3DXVECTOR3{FLOATx;FLOATy;FLOATz;}D3DXVECTOR3;

其中的FLOAT為float的typedef類型,定義在windef.h頭文件中。而顏色通常使用DWORD

的typedef定義類型D3DCOLOR。

比如:

structCUSTOMVERTEX{//含位置、法向量與顏色的自定義頂點結(jié)構(gòu)

D3DXVECTOR3position;//未變換頂點的3D位置

D3DXVECTOR3normal;//頂點的表面法向量

D3DCOLORcolor;//顏色

);或者:

structCUSTOMVERTEX{//含位置、顏色與紋理坐標的自定義頂點結(jié)構(gòu)

D3DXVECTOR3position;//未變換頂點的3D位置

D3DCOLORcolor;//顏色

FLOATtu,tv;//紋理坐標

);或者:

structCUSTOMVERTEX{//含位置齊次坐標與顏色的自定義頂點結(jié)構(gòu)

FLOATx,y,z,rhw;//已變換頂點的3D位置

DWORDcolor;//顏色

);

用戶在定義了自己的頂點結(jié)構(gòu)類型后,還需要定義一個對應(yīng)的(宏)常量,來描述該結(jié)

構(gòu)的字段內(nèi)容。該(宏)常量由若干表示頂點格式的標志位符號常量(參見表13-1)的位或

者組合而成。

表13-1頂點數(shù)據(jù)格式標志

符號常量值數(shù)據(jù)類型描述

D3DFVF_XYZ0x002float,float,float未轉(zhuǎn)換的頂點坐標

D3DFVF_XYZRHW0x004float,float,float,float已轉(zhuǎn)換的頂點坐標

D3DFVF_XYZB1~5OxOO6/8/a/c/e】-3個float含權(quán)重i的頂點坐標

D3DFVF.XYZW0x4002float,float,float,float已轉(zhuǎn)換與裁剪的頂點坐標

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);

?創(chuàng)建頂點緩沖區(qū)

在定義了頂點結(jié)構(gòu)后,就能夠創(chuàng)建頂點緩沖區(qū)了,這能夠由IDirect3DDevice9接口的

CreateVertexBuffer方法來完成:

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

UINTLength,//緩沖區(qū)的字節(jié)大小,通常為n*sizeof(CUSTOMVERTEX)

DWORDUsage,//緩沖區(qū)用法的附加屬性標志,通常為0

DWORDFVF,//頂點結(jié)構(gòu)格式常量

D3DPOOLPool,//緩沖區(qū)所在的內(nèi)存池類型(D3DPOOL枚舉值)

IDirect3DVertexBuffer9**ppVertexBuffer,//返回被創(chuàng)建的頂點緩沖區(qū)指針

HANDLE*pSharedHandle//保留,設(shè)為NULL

);

其中,內(nèi)存池類型D3DPOOL枚舉的定義為:

typedefenumD3DPOOL{//內(nèi)存池類型枚舉

D3DPOOL_DEFAULT=0,//AGP存儲器或者顯存

D3DPOOL_MANAGED=1J/AGP存儲器或者顯存,且在系統(tǒng)內(nèi)存中還有一份拷貝

D3DPOOL_SYSTEMMEM=2,//系統(tǒng)內(nèi)存

D3DPOOL_SCRATCH=3,//系統(tǒng)內(nèi)存中的臨時池

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);

?構(gòu)造點集

創(chuàng)建三維場景中的幾何對象,需要計算與構(gòu)造描述該幾何對象的點集。具體做法是:先

定義一個頂點指針?(用于操作頂點數(shù)組);再調(diào)用Lock方法來獲取頂點緩沖區(qū)的首地址(賦

值給頂點指針),并鎖定該區(qū)域僅供當前操作使用;然后利用該頂點指針,將計算的頂點結(jié)

構(gòu)值填入頂點緩沖區(qū),從而構(gòu)造出幾何對象;最后調(diào)用Unlock方法解鎖頂點緩沖區(qū)。

IDirect3DVertexBuffer9接口的Lock與Unlock方法的定義為:

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

UINTOffsetToLock,//鎖定的偏移地址

UINTSizeToLock,//鎖定的字節(jié)數(shù)

VOID**ppbData,//返回被鎖定的緩沖區(qū)頭的指針

DWORDFlags//鎖定方式標志,可為0或者下列符號常量的組合:

//D3DLOCKDISCARD、D3DLOCKNODIRTYUPDATE,

//D3DL0CK_N0SYSL0CK.D3DL0CK_READ0NLY>

//D3DLOCK_NOOVERWRITE

);

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

比如:

CUSTOMVERTEX*pVertices;

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

……〃給頂點緩沖區(qū)中的各頂點結(jié)構(gòu)賦值(構(gòu)造幾何對象的點集)

g_pVB->Unlock();

13.2.5矩陣變換

描述單個物體(3D幾何對象)通常使用的是本地相對坐標。因此,在渲染之前,需要

將它們都轉(zhuǎn)換為描述場景的統(tǒng)一世界空間(worldspace)坐標,這對應(yīng)于世界矩陣變換。

為了將三維場景顯示在二維屏幕上,還需要選擇一個觀察點(眼睛/攝像機)與觀察角度

(方向/坐標)(對應(yīng)于觀察坐標矩陣變換),并將3D場景投影到一個2D平面(屏幕)上

(對應(yīng)于投影矩陣變換),還要將超出屏幕的部分去掉(裁剪),也能夠?qū)鼍巴渡涞狡聊?/p>

的某個矩形區(qū)域中(視口縮放)。參見圖13-13。

下面依次對這些變換加以介紹,這需要首先介紹Direct3D中的矩陣定義與變換方法。

?矩陣與變換

在Direct3D中,定義了矩陣(matrix)結(jié)構(gòu)D3DXMATRIX:

typedefstructD3DXMATRIX{//矩陣結(jié)構(gòu)

struct{//注意,C/C++的變量名可下列劃線開頭(但不能以數(shù)字開頭)

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

對應(yīng)于4*4的浮點矩陣:_31_32_33_34

\—41—42—43―44/,

在Direct3D中,還定義了一個對IntelP4CPU運算進行了優(yōu)化的16字節(jié)對齊的矩陣結(jié)

構(gòu)(從D3DXMATRIX派生的C++結(jié)構(gòu)對象):

typedefstruct_D3DXMATRIXA16:publicD3DXMATRIX{//16字節(jié)對齊矩陣結(jié)構(gòu)

_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還提供了若干全局矩陣函數(shù),如:

D3DXMATRIX*D3DXMatrixIdentity(D3DXMATRIX*pOut);//倉I建單位矩陣

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

D3DXMATRIX*D3DXMatrixInverse(//計算逆矩陣

D3DXMATRIX*pOut,//結(jié)果矩陣

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

CONSTD3DXMATRIX*pM//原矩陣

);

D3DXMATRIX*D3DXMatrixMultiply(//兩矩陣相乘

D3DXMATRIX*pOut,//結(jié)果矩陣

CONSTD3DXMATRIX*pMl,〃矩陣1

CONSTD3DXMATRIX*pM2//矩陣2

);

矩陣變換(transform)的實施,可使用IDirect3DDevice9接口提供的SetTransform方法:

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

D3DTRANSFORMSTATETYPEState,//變換類型狀態(tài)值

CONSTD3DMATRIX*pMatrix//變換矩陣

);

其中State的取值可為D3DTRANSFORMSTATETYPE枚舉類型或者

D3DTS_WORLDMATRIX宏的值。如:D3DTS_VIEW(=2,觀察變換)>D3DTS_PROJECTION

(=3,投影變換)、D3DTSTEXTURE0-7(=16-23,紋理變換)、D3DTSWORLD(=256,

世界變換)等。

比如:

D3DXMATRIXA16matWorld;//定義矩陣結(jié)構(gòu)對象

D3DXMatrixIdentity(&matWorld);//變成單位矩陣

……〃對matWorld進行其他矩陣變換

g_pd3dDevice->SetTransfonn(D3DTS_WORLD.&matWorld);//實施變換

?世界變換

通常用每個物體各自的本地坐標來描述所對應(yīng)的3D幾何對象,而用統(tǒng)一的世界坐標來

描述整個場景(參見圖13-14),渲染之前需要將頂點從本地坐標系轉(zhuǎn)換到世界坐標系。稱

這種從本地坐標到世界坐標的轉(zhuǎn)換為世界變換(worldtransform),世界變換包含平移

(translation)、旋轉(zhuǎn)(rotation)與縮放(scaling)等三種具體變換類型,它們都可用對應(yīng)的

矩陣變換來表示。

下面是Direct3D提供的若干世界矩陣變換的全局函數(shù):

D3DXMATR1X*D3DXMatrixTranslation(//平移變換

D3DXMATRIX*pOut,//原/結(jié)果矩陣

FLOATx,//x偏移量

FLOATy,//y偏移量

FLOATz//z偏移量

D3DXMATRIX*D3DXMatrixRotationX[Y/Z](//(繞x[y/z]軸的)旋轉(zhuǎn)變換

D3DXMATRIX*pOut,//原/結(jié)果矩陣

FLOATAngle//旋轉(zhuǎn)角度(弧度單位)

);

D3DXMATRIX*D3DXMatrixScaling(//縮放變換

D3DXMATRIX*pOut,//原/結(jié)果矩陣

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

FLOATsy,〃y方向的比例因子

FLOATsz//z方向的比例因子

);

能夠通過這些函數(shù),獲得所需要的各類變換矩陣。最后,還須使用D3DTS_W0RLD狀

態(tài)值,來調(diào)用IDirect3DDevice9接口的SetTransform方法,以實施最終矩陣所對應(yīng)的世界變

換。比如:

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

D3DXMatrixRotationX(&matWorld,m_fPitch);〃繞x軸旋轉(zhuǎn)

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

實施世界變換

?觀察變換

觀察變換(viewtransform),可在世界坐標系(x、,,y、*Zw)中設(shè)置與改變觀察者的位置與

方向,將世界空間中的頂點轉(zhuǎn)換到攝影空間(cameraspace)(xe,ye,Ze),參見圖13-15。

在Direct3D中,觀察矩陣由全局助手函數(shù)D3DXMatrixLookAtLH(Left-Handed,左手

系)與D3DXMatrixLookAtRH(Right-Handed,右手系)來創(chuàng)建:

圖13-15通1察變橫

D3DXMATRIX*D3DXMatrixLookAtLH(//創(chuàng)建左手系觀察-

矩陣(右手系:LH-RH)

D3DXMATRIX*pOut,//結(jié)果

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
  • 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論