版權說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權,請進行舉報或認領
文檔簡介
編號:時間:2021年x月x日書山有路勤為徑,學海無涯苦作舟頁碼:第頁第13章DirectX編程入門DirectX是微軟公司為編寫游戲和其他高性能多媒體應用程序而開發(fā)的一組高級的Windows低層API,它包含了對圖(圖形、視頻和三維動畫)、聲音(聲效與音樂)、輸入設備和網(wǎng)絡游戲等的支持。本章先概述DirectX的基本內(nèi)容,然后介紹DirectX的主要組件Direct3D和DirectSound的基本編程方法,并給出若干具體編程實例。13.1DirectX概述本節(jié)簡單介紹DurectX的發(fā)展歷史、版本和功能的演化、結構和模塊劃分。DurectX是Windows的一種多媒體API,它在保持設備無關性的同時,可以讓應用程序直接控制多媒體設備,從而能充分利用硬件的功能,因此可獲得最高的性能。DurectX自從推出以來,就始終處在快速發(fā)展的過程之中。它已經(jīng)經(jīng)歷了多個版本,其模塊和功能也一直在不斷地增加和完善。DirectX是一種基于COM的系統(tǒng),主要由硬件抽象層HAL和硬件模擬層HEL所構成。DurectX被分成若干個組件模塊,涵蓋了多媒體應用的方方面面。而且這些組件的數(shù)目、名稱和功能,也是隨著其版本的演化而有所增減、改變和加強。13.1.1歷史微軟公司于1990年5月推出的Windows3.0大獲成功,它是一種與設備無關的具有圖形用戶界面(GUI)的操作系統(tǒng)。后來又于1992年3月推出Windows3.1,提供了對多媒體的支持。不過Windows的與設備無關的設計思想,雖然使得Windows向程序員提供了一個獨立于硬件的軟件開發(fā)優(yōu)秀平臺,但它不讓應用程序直接操作顯卡和聲卡等多媒體硬件,這樣就降低了多媒體應用程序(特別是計算機游戲)的運行效率,例如限制了動畫的幀率、不提供混音功能等。所以當時的Windows并不是一個可以開發(fā)和運行高效多媒體程序(如3D游戲)的理想環(huán)境,逼迫PC游戲開發(fā)商只好繞開Windows而仍舊開發(fā)DOS下的游戲。為了改變這種難堪的局面,促使游戲界放棄DOS而使用Windows,微軟需要在設備無關性與高性能之間取得某種平衡,決定為Windows添加一種高性能的動畫機制(以及后來的輸入與音響等),因此于1995年推出了GameSDK,后來改名為DirectX。其中的Direct指可以直接訪問多媒體硬件;X指它的不同組成部分,如Direct3D、DirectSound、DirectInput和DirectPlay等。13.1.2版本與功能因為DirectX必須支持多媒體設備的最新技術和功能,而多媒體硬件(尤其是顯卡[的3D性能])和技術始終處在高速發(fā)展過程中,所以DirectX的技術和版本也同樣在不斷地發(fā)展和演變,其中發(fā)展最快的是3D接口部分。下面列出DirectX的主要版本的發(fā)布時間、引入的新模塊和特性:1.0——1995年9月30日:DirectDraw、DirectSound、DirectInput、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月16日:有許多改進,如受力反饋控制器、多顯示器支持、新的游戲控制面板、用戶界面的全面改進等(次版本有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,更新了DirectInput與DirectPlay,添加了DirectShow、拋棄了其余的DirectXMedia模塊。2001年11月11日推出的8.1版,被集成在WindowsXP中銷售,該版本添加了從DirectShow分離出的DMO(DirectXMediaObjects媒體對象)組件模塊。它還支持許多新的圖形特性,如像素著色引擎的1.2~1.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ù)顯示器自動調整γ值等。也添加若干新特性到DirectInput、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,次版本改為發(fā)布的年月。一般是每兩個月推出一個新版本,因此也叫做DirectX9.0c的雙月更新(bimonthlyupdates)。當前最新版本為2006年10月11日推出的DXOctober2006。它們都包含了(于2002年推出的專為.NET框架設計的)托管(Managed)DirectX,將原來DirectX多個分離的COM模塊集成到了一個容易使用的單一CLR文件之中。10——?:DirectX不會有第10版了,因為微軟公司已將DirectX的功能集成進其新一代操作系統(tǒng)WindowsVista中,而不再將其作為一個額外的模塊了。但是會有Direct3D10,已于2006年12月13日隨Direct3DSDK的December2006版一起發(fā)布,并被嵌入到WindowsVista中。另外,作為學生和業(yè)余愛好者的DirectX替代產(chǎn)品,微軟公司于2004年3月24日宣布了用于托管運行環(huán)境下計算機游戲的設計、開發(fā)和管理的框架和工具集XNA,并于2006年12月11日推出了XNAFrameworkRedistributable和XNAGameStudioExpress的1.0版,可用于Windows和Xbox360游戲的開發(fā)。WindowsAPI應用程序WindowsAPI子系統(tǒng)(GDI、MMAPI、MCI、...)Windows驅動程序接口DirectXWindowsAPI應用程序WindowsAPI子系統(tǒng)(GDI、MMAPI、MCI、...)Windows驅動程序接口DirectXHELHALPC硬件子系統(tǒng)DirectX圖13-1DirectX子系統(tǒng)DirectX是一種基于COM(ComponentObjectModel,組件對象模型)的系統(tǒng),它既不屬于驅動程序層,也不屬于應用層。DirectX的主要設計目標是在提供某種設備獨立性的同時獲取高速度,為此微軟公司為DirectX設計了如圖13-1所示的體系結構。其中:圖13-1DirectX子系統(tǒng)HAL=HardwareAbstractLayer(硬件抽象層)——負責檢測本機的硬件功能,并以一種獨立于設備的方式提供這些功能;HEL=HardwareEmulationLayer(硬件模擬層)——負責提供DirectX功能中本機硬件不支持部分的模擬實現(xiàn)。但是從8.0版起,DirectX就不再提供硬件模擬層HEL了,需要開發(fā)商、第三方或自己來編寫一個PSD(PluggableSoftwareDevice可插式軟件設備)連到DirectX提供的HEL接口上,稱之為參考設備。但是現(xiàn)在很少有這樣的PSD可用,因此新版本的DirectX是嚴重依賴于硬件的。13.1.4組成DirectX由多個(COM組件)模塊組成,而且隨著版本的演化,這些模塊也在不斷地增減、合并和改變。最新的DirectX組件的模塊構成如圖13-2所示,括號中的數(shù)字為該模塊被首次引進(或移出)的版本號。下面是DirectX的主要組成模塊的簡單介紹:DirectXGraphics(圖形)——包括DirectDraw和Direct3D:DirectDraw(繪制)——二維圖形繪制(高速位圖傳送/視頻與2D動畫)。從9.0版起,DirectDraw已被集成到了Direct3D之中。Direct3D(三維)——三維圖形繪制。分成保留(retained)和立即(immediate)兩種模式(mode):保留模式是一種高層API,建立在立即模式之上,使用起來方便容易,但是效率不高,適合于初學者;立即模式則是一種底層API,使用復雜,但是其效率比保留模式高得多。大多數(shù)DirectX應用程序,特別是計算機游戲,都是采用立即模式進行開發(fā)。自從6.0版以來,保留模式API的發(fā)展停滯不前,而立即模式API的發(fā)展卻日新月異。不論是保留模式還是立即模式,Direct3D都是建立在DirectDraw之上的。從9.0版起,Direct3D包含了DirectDraw,它像OpenGL一樣也具有二維圖形繪制的功能。Direct3D的下一個版本為Durect3D10,為WindowsVista的一個有機組成部分。D3DX(Direct3D擴展)——為Direct3D服務的實用工具庫,執(zhí)行公共的數(shù)學計算和一些復雜的任務,包含若干簡化3D模型使用的類,如粒子系統(tǒng)(particlesystem)。D3DX由動態(tài)鏈接庫(DLL)提供。DXUT(編程框架)——建立在Direct3DAPI之上的樣例框架,也叫通用文件框架,可以幫助程序員減少在繁瑣的平凡工作(如創(chuàng)建窗口、創(chuàng)建設備、處理Windows消息和設備事件等)上所花的時間。DirectXDirectXDirectXGraphics(8.0)DirectDraw(1.0)Direct3D(2.0)DirectXAudio(8.0)DirectSound(1.0)DirectMusic(6.1)DirectSound3D(3.0)DirectInput(1.0)DirectPlay(1.0)DirectSetup(1.0)DirectXMedia(5.0)DirectShow(5.0)DirectAnimation(5.0)DirectX視頻加速(5.0)Direct3D保留模式(5.0)DirectXTransform(5.0)并入(9.0)移入平臺SDK(9.0c2005.4)建議用WinSocket和WinFirewallAPI代替(9.0c)并入(8.0)移入WindowsMediaSDK(8.0)XInput(9.0c2005.10)XboxLive(Vista)MediaFoundation(Vista)XACT(9.0c2006.2)XNA(Xbox/Vista)DirectXMediaObjects(8.1)分出(8.1)并入(6.0)Direct3D立即模式(2.0)D3DX(7.0)/DXUT(6.0)圖13-2DirectX的組成模塊DirectXAudio(音頻)——包括DirectSound和DirectMusic:DirectSound(聲音)——主要針對波形音頻,底層接口。可用于開發(fā)播放和捕捉波形音頻的高性能立體與三維(DirectSound3D)音頻應用程序。在下一代DirectX中,DirectSound的功能將由XACT(MicrosoftCross-PlatformAudioCreationTool微軟跨平臺音頻生成工具)來代替。DirectMusic(音樂)——主要針對MIDI音樂,高層接口。為基于波形、MIDI聲音或DirectMusic生成器所創(chuàng)造的動態(tài)內(nèi)容之音樂和非音樂聲道提供一個完整的解決方案。XACT(游戲音頻)——XACT(MicrosoftCross-PlatformAudioCreationTool,微軟跨平臺音頻生成工具),是一種多人合作的音頻設計工具和相關API,用于游戲的動態(tài)音頻開發(fā)。DirectInput(輸入)——提供對各種輸入設備的支持,包括對受力反饋(force-feedback)技術的全面支持。在下一代DirectX中,DirectInput將被XInput代替。DirectPlay(游戲)——提供對多人網(wǎng)絡游戲的支持。在最新的DirectX版本中,微軟公司反對(deprecate)使用DirectPlay,而建議改用WindowsSockets和WindowsFirewallAPI來代替。在下一代DirectX中,DirectPlay可能會被XboxLive代替。DirectSetup(安裝)——提供DirectX組件的一次性調用安裝的一個簡單API(自動安裝DirectX驅動程序)。DirectShow(展示)——提供多媒體(音視頻)流的高質量捕捉和重放。在8.0版之前,DirectShow是DirectXMedia的一個組成模塊。到8.0版時,因為DirectXSDK拋棄了DirectXMedia,所以才將DirectShow集成到了DirectX之中。在DirectX9.0c的2005年4月升級版中,DirectShow又被移出DirectX,放入微軟公司的平臺SDK之中。DirectXMediaObjects(媒體對象DMO)——基于COM的多媒體和數(shù)據(jù)流組件,支持音視頻的編解碼器和特效。是在DirectX的8.1版時,從DirectShow分出的,其功能類似于DirectShow的過濾器。DirectXMedia(媒體)——是一個用于流媒體應用的外部API集合。在DirectX6.0之前,DirectXMediaSDK和DirectXSDK是兩個分離的SDK。在6.0版時DirectXMediaSDK被集成到DirectXSDK之中。DirectXMedia的運行模塊,被集成到Windows和IE之中。到了8.0版時,DirectXMedia又被DirectXSDK拋棄(其核心模塊DirectShow被集成到了DirectX之中),其功能被隨Windows2000Server推出的WindowsMediaSDK所代替。DirectXTransform(變換)——用于產(chǎn)生二、三維圖形的各種效果,如α混色和表面彎曲等。DirectAnimation(動畫)——集成多種媒體類型來創(chuàng)建復雜動畫,并可用作網(wǎng)頁內(nèi)容。DirectXVideoAcceleration(視頻加速DXVA)——利用硬件加速二維視頻的解碼操作。Direct3DRetainedMode(保留模式)——Direct3D的保留模式是一種高層API,建立在Direct3D立即模式之上,使用起來方便容易,但是效率不高,適合于初學者。DirectShow(展示)——支持音視頻流的高質量采集和重放。13.1.5編程準備為了用VC編寫DirectX應用程序,必須先下載并安裝DirectXSDK,并進行必要的頭/庫文件路徑和鏈接庫的設置。下面以WindowsXP中文版環(huán)境下的VisualC++2005中文版和DirectX9.0cAugust2006SDK為例,介紹進行具體的DirectX編程之前,所需做的必要準備工作。下載并安裝DirectXSDK可以從微軟公司的官方網(wǎng)站(/windows/directx/)下載最新的DirectXSDK,如dxsdk_dec2006.exe(448MB)。安裝完成后,會在安裝目錄(缺省為“C:\ProgramFiles\MicrosoftDirectXSDK((December2006)”)中生成DeveloperRuntime、Documentation、Include、Lib、Redist、Samples和Utilities等多個子目錄。安裝時還會為Windows操作系統(tǒng)生成名為“MicrosoftDirectXSDK((December2006)”的程序組,包含多個子程序組和程序。安裝程序會將DirectXSDK的幫助文檔,也安裝到VisualStudio2005的幫助系統(tǒng)內(nèi),位于其“目錄/DirectXSDK((December2006)”目錄之中,包含“DirectXSDK((December2006)C++”和“DirectXSDK((December2006)Managed”兩個幫助子目錄。設置包含和庫路徑在VisualStudio2005中文版的IDE中,選“工具/選項”菜單項,打開“選項”對話框(參見圖13-5)。圖13-5VisualStudio2005的“選項”對話框再選該對話框左邊的“項目和解決方案/VC++目錄”路徑,在右邊的“顯示以下內(nèi)容的目錄”欄的下拉式列表框中,選“包含文件”項。按該欄下面的“新行”鈕,則在其下方的顯示欄中會出現(xiàn)新行,再按新行右端的帶省略號的瀏覽鈕,在彈出的“選擇目錄”對話框中,選擇DirectXSDK的Include目錄所在的路徑“C:\ProgramFiles\MicrosoftDirectXSDK(August2006)\Include”,然后按“打開”關閉“選擇目錄”對話框。結果參見圖13-6。圖13-6設置DirectX的“包含文件”的路徑可類似選擇“庫文件”項,添加庫文件路徑“C:\ProgramFiles\MicrosoftDirectXSDK(August2006)\Lib\x86”,結果參見圖13-7。最后,按“確定”鈕,關閉“選項”對話框。圖13-7設置DirectX的“庫文件”的路徑注意,對DirectX的包含路徑和庫路徑的設置,對所有項目都有效。設置鏈接庫先創(chuàng)建一個DirectX應用程序的MFC單文檔項目(如DxTest),再在VS05的IDE中,選“項目/屬性”,打開“DxTest屬性頁”對話框。在左上角的“配置”欄中,選中“所有配置”項;再選左邊的路徑“配置屬性/鏈接器/輸入”,在右邊的“附加依賴項”欄中,添加d3d9.libd3dx9.libd3dxof.libdsound.libdxguid.libwinmm.lib等鏈接庫(在多個庫文件之間,用空格分隔)。具體添加哪些DirectX庫,與具體應用程序所使用的DirectX模塊有關,你也可以查看DirectX的庫目錄。最后,按“應用”鈕和“確定”鈕,關閉屬性頁對話框。參見圖13-8。圖13-8設置DirectX的鏈接庫注意,對DirectX鏈接庫的設置,只對VC05中當前打開的單個項目有效。在安裝了DirectXSDK,并設置好文件路徑和鏈接庫后,就可以開始編寫具體的DirectX應用程序了。DirectX的組件眾多、功能強大、編程復雜,完整的介紹需要幾本大部頭的專著才行,本書只準備簡單介紹DirectX的最主要模塊——Direct3D和DirectSound編程的最基本內(nèi)容。13.2Direct3D編程簡介Direct3D(直接三維)是DirectX的核心模塊,新版本的Direct3D中還包含原來DirectDraw模塊的2D功能。因此,現(xiàn)在的Direct3D是DirectXGraphics的唯一模塊,具有DirectX(二、三維)圖形的全部功能。13.2.1流水線與設備Direct3D用圖形流水線(graphicspipeline)來處理和渲染場景(renderscene),而Direct3D設備(device)是執(zhí)行變換(transformation)和光照(lighting)等操作的渲染部件。Direct3D圖形流水線可通過Direct3D圖形流水線來充分利用硬件性能,以提供高效處理和繪制Direct3D場景到顯示器的能力。圖13-9為流水線(pipeline,管線/管道/流程)的組成模塊框圖。頂點數(shù)據(jù)頂點數(shù)據(jù)圖元數(shù)據(jù)鑲嵌頂點處理幾何處理像素處理像素繪制紋理采樣器紋理表面圖13-9Direct3D圖形流水線Direct3D設備圖13-10Direct3D設備架構變換模塊光照模塊光柵化器Direct3D設備架構Direct3D設備(device)是Direct3D的渲染部件,它封裝和存儲渲染狀態(tài)。另外,它還執(zhí)行變換和光照等操作,并且光柵化圖像到表面(如屏幕)。在結構上,Direct3D設備包含變換模塊(transformationmodule)、光照模塊(lightingmodule)和光柵化器(rasteriz圖13-10Direct3D設備架構變換模塊光照模塊光柵化器Direct3D設備架構當前,Direct3D有兩種主要的設備類型:HAL設備(haldevice)——具有硬件加速的光柵化(rasterization),可同時使用硬件和軟件的頂點處理進行著色(shading)。參考設備(referencedevice)——由軟件驅動程序提供,現(xiàn)在主要用于性能測試。創(chuàng)建Direct3D對象創(chuàng)建Direct3D設備對象創(chuàng)建Direct3D對象創(chuàng)建Direct3D設備對象設置渲染狀態(tài)定義頂點格式創(chuàng)建頂點緩沖區(qū)鎖定頂點緩沖區(qū)解鎖頂點緩沖區(qū)開始場景結束場景構造幾何對象設置材質和光照或紋理設置設備的流源和頂點格式繪制圖元展現(xiàn)場景進行世界、觀察和投影矩陣變換清除對象清除顯示表面13.2.2基本編程過程Direct3D的基本編程過程如圖13-11所示。下面各小節(jié)依次介紹Direct3D編程的基本步驟和方法。13.2.3創(chuàng)建和初始化對象為了使用Direct3D,你必須首先創(chuàng)建一個應用窗口,然后再創(chuàng)建和初始化Direct3D對象。利用這些對象所實現(xiàn)的COM接口來操作它們,以創(chuàng)建繪制場景所需的其它對象。如果進行MFC編程,則可以省略創(chuàng)建窗口這一步,而直接使用視圖類所代表的客戶區(qū)窗口。圖13-11Direct3D編程的基本過程下面介紹的是初始化Direct3D的內(nèi)容,包括創(chuàng)建Direct3D對象、創(chuàng)建Direct3D圖13-11Direct3D編程的基本過程創(chuàng)建Direct3D對象可使用全局函數(shù)Direct3DCreate9來創(chuàng)建Direct3D接口對象:IDirect3D9*Direct3DCreate9(//成功返回指向IDirect3D9接口的指針,失敗返回NULLUINTSDKVersion//必須為D3D_SDK_VERSION);例如:IDirect3D9*g_pD3D=Direct3DCreate9(D3D_SDK_VERSION);創(chuàng)建Direct3D設備可使用IDirect3D9接口的CreateDevice方法來創(chuàng)建設備(尾參數(shù)的返回值):HRESULTCreateDevice(//成功返回D3D_OK(=0)UINTAdapter,//顯卡(displayadapter)序號,D3DADAPTER_DEFAULT為主顯卡D3DDEVTYPEDeviceType,//設備的枚舉類型,一般取為D3DDEVTYPE_HALHWNDhFocusWindow,//焦點窗口句柄,可取為this->m_hWndDWORDBehaviorFlags,//控制設備的創(chuàng)建行為之選項組合,可以采用硬件或軟件//的頂點處理,如D3DCREATE_SOFTWARE_VERTEXPROCESSINGD3DPRESENT_PARAMETERS*pPresentationParameters,//指向展現(xiàn)參數(shù)結構//D3DPRESENT_PARAMETERS的指針I(yè)Direct3DDevice9**ppReturnedDeviceInterface//代表被創(chuàng)建設備的//IDirect3DDevice9返回接口的指針地址);其中,展現(xiàn)參數(shù)結構D3DPRESENT_PARAMETERS的定義為:typedefstructD3DPRESENT_PARAMETERS{//展現(xiàn)參數(shù)結構UINTBackBufferWidth,BackBufferHeight;//后臺緩沖區(qū)的寬高(以像素為單位),//對窗口模式可取為0,對全屏模式則必須與當前顯卡枚舉模式的一致D3DFORMATBackBufferFormat;//后臺緩沖區(qū)的格式,可取為//D3DFMT_UNKNOWN(=0)UINTBackBufferCount;//后臺緩沖區(qū)計數(shù),可取為0~3,取0時等價于1D3DMULTISAMPLE_TYPEMultiSampleType;//多樣本類型,一般取為 //D3DMULTISAMPLE_NONE(=0)DWORDMultiSampleQuality;//多樣本質量水平,一般取0D3DSWAPEFFECTSwapEffect;//交換效果,可取為 //D3DSWAPEFFECT_DISCARD(=1)、D3DSWAPEFFECT_FLIP(=2) //和D3DSWAPEFFECT_COPY(=3)等枚舉值HWNDhDeviceWindow;//設備窗口的句柄,對窗口模式可取為NULL(=0)BOOLWindowed;//應用程序在窗口/全屏中運行時取TRUE/FALSEBOOLEnableAutoDepthStencil;//允許自動深度模板,為TRUE則由Direct3D//來管理應用程序的深度緩沖區(qū)D3DFORMATAutoDepthStencilFormat;//自動深度模板格式,可取//D3DFMT_D16、D3DFMT_D24S8和D3DFMT_D32等枚舉值DWORDFlags;//表現(xiàn)標志D3DPRESENTFLAG常數(shù)之一,可取為0UINTFullScreen_RefreshRateInHz;//全屏時的屏幕刷新率,對窗口模式必須為0UINTPresentationInterval;//前后臺緩沖區(qū)交換的最大速率,可取為//D3DPRESENT_INTERVAL_DEFAULT(=0)}D3DPRESENT_PARAMETERS;例如://設置創(chuàng)建D3D設備用的表現(xiàn)結構D3DPRESENT_PARAMETERSd3dpp;//定義表現(xiàn)結構變量ZeroMemory(&d3dpp,sizeof(d3dpp));//內(nèi)存清零d3dpp.Windowed=TRUE;//窗口模式d3dpp.SwapEffect=D3DSWAPEFFECT_DISCARD;//放棄交換效果d3dpp.BackBufferFormat=D3DFMT_UNKNOWN;//未知格式d3dpp.EnableAutoDepthStencil=TRUE;//允許自動深度模板d3dpp.AutoDepthStencilFormat=D3DFMT_D16;//16位深度緩沖LPDIRECT3DDEVICE9g_pd3dDevice;//定義D3D設備接口的指針//創(chuàng)建D3D設備對象(獲取D3D設備接口的指針)g_pD3D->CreateDevice(D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL, this->m_hWnd,D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp,&g_pd3dDevice);設置設備的渲染狀態(tài)利用IDirect3D9接口的CreateDevice方法所返回的設備接口IDirect3DDevice9的指針,可以調用該接口的設置渲染(render著色)狀態(tài)方法SetRenderState,來初始化設備:HRESULTSetRenderState(//成功返回D3D_OK(=0)D3DRENDERSTATETYPEState,//設備狀態(tài)DWORDValue//設置值);其中,設備狀態(tài)State,可取D3DRENDERSTATETYPE枚舉的任意值,如D3DRS_ZENABLE(允許Z緩沖)、D3DRS_FILLMODE(填充模式)、D3DRS_SHADEMODE(陰影模式)、D3DRS_ALPHATESTENABLE(允許α測試)、D3DRS_CULLMODE(剔除模式)、D3DRS_FOGENABLE(允許霧化)、D3DRS_LIGHTING(光照)、D3DRS_DITHERENABLE(允許抖動)、……。例如:g_pd3dDevice->SetRenderState(D3DRS_CULLMODE,D3DCULL_NONE);//關閉背面剔除g_pd3dDevice->SetRenderState(D3DRS_ZENABLE,TRUE);//允許Z緩沖g_pd3dDevice->SetRenderState(D3DRS_LIGHTING,FALSE);//關閉光照13.2.4創(chuàng)建場景三維場景是由若干物體(幾何對象)構成的,復雜的幾何對象由多個簡單的圖元(點、線、三角形和多邊形等)所組成,而圖元(primitive)又是頂點(vertex)的集合。圖13-123D圖元表面的三角網(wǎng)格3D圖元一般是一個多面體,通常用其表面的三角網(wǎng)格來表示,參見圖13-12。所以最基本的圖元是三角形和頂點。圖13-123D圖元表面的三角網(wǎng)格創(chuàng)建場景中的幾何對象,等價于建立表示該幾何體的頂點集合。因此,必須先定義自己的頂點結構并創(chuàng)建頂點緩沖區(qū),然后在鎖定頂點緩沖區(qū)后,再通過給頂點緩沖區(qū)中的各頂點結構賦值來構造幾何對象,最后解鎖頂點緩沖區(qū)。定義頂點結構Direct3D使用一種FVF(FlexibleVertexFormat可變頂點格式)結構來定義頂點,以滿足用戶的不同需要。在FVF結構CUSTOMVERTEX中,可以包含描述頂點的位置、RHW(reciprocalhomogeneousw倒數(shù)齊次w,表示已變換頂點位置的齊次坐標w分量)、法向、大小和(漫射、鏡面反射)顏色等字段,具體內(nèi)容由用戶根據(jù)需要自己來確定,但是各字段之間的相對順序不能改變。其中,頂點的位置和法向等字段,一般為三維點向量,可以用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;//顏色 };用戶在定義了自己的頂點結構類型后,還需要定義一個對應的(宏)常量,來描述該結構的字段內(nèi)容。該(宏)常量由若干表示頂點格式的標志位符號常量(參見表13-1)的位或組合而成。表13-1頂點數(shù)據(jù)格式標志符號常量值數(shù)據(jù)類型描述D3DFVF_XYZ0x002float,float,float未轉換的頂點坐標D3DFVF_XYZRHW0x004float,float,float,float已轉換的頂點坐標D3DFVF_XYZB1~50x006/8/a/c/e1-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);創(chuàng)建頂點緩沖區(qū)在定義了頂點結構后,就可以創(chuàng)建頂點緩沖區(qū)了,這可以由IDirect3DDevice9接口的CreateVertexBuffer方法來完成:HRESULTCreateVertexBuffer(//成功返回D3D_OK(=0)UINTLength,//緩沖區(qū)的字節(jié)大小,一般為n*sizeof(CUSTOMVERTEX)DWORDUsage,//緩沖區(qū)用法的附加屬性標志,一般為0DWORDFVF,//頂點結構格式常量D3DPOOLPool,//緩沖區(qū)所在的內(nèi)存池類型(D3DPOOL枚舉值)IDirect3DVertexBuffer9**ppVertexBuffer,//返回被創(chuàng)建的頂點緩沖區(qū)指針HANDLE*pSharedHandle//保留,設為NULL);其中,內(nèi)存池類型D3DPOOL枚舉的定義為:typedefenumD3DPOOL{//內(nèi)存池類型枚舉D3DPOOL_DEFAULT=0,//AGP存儲器或顯存D3DPOOL_MANAGED=1,//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);構造點集創(chuàng)建三維場景中的幾何對象,需要計算和構造描述該幾何對象的點集。具體做法是:先定義一個頂點指針(用于操作頂點數(shù)組);再調用Lock方法來獲取頂點緩沖區(qū)的首地址(賦值給頂點指針),并鎖定該區(qū)域僅供當前操作使用;然后利用該頂點指針,將計算的頂點結構值填入頂點緩沖區(qū),從而構造出幾何對象;最后調用Unlock方法解鎖頂點緩沖區(qū)。IDirect3DVertexBuffer9接口的Lock和Unlock方法的定義為:HRESULTLock(//成功返回D3D_OK(=0)UINTOffsetToLock,//鎖定的偏移地址UINTSizeToLock,//鎖定的字節(jié)數(shù)VOID**ppbData,//返回被鎖定的緩沖區(qū)頭的指針DWORDFlags//鎖定方式標志,可為0或下列符號常量的組合: //D3DLOCK_DISCARD、D3DLOCK_NO_DIRTY_UPDATE、//D3DLOCK_NOSYSLOCK、D3DLOCK_READONLY、//D3DLOCK_NOOVERWRITE);HRESULTUnlock();//成功返回D3D_OK(=0)例如:CUSTOMVERTEX*pVertices;g_pVB->Lock(0,0,(void**)&pVertices,0);……//給頂點緩沖區(qū)中的各頂點結構賦值(構造幾何對象的點集)g_pVB->Unlock();13.2.5矩陣變換描述單個物體(3D幾何對象)一般采用的是本地相對坐標。因此,在渲染之前,需要將它們都轉換為描述場景的統(tǒng)一世界空間(worldspace)坐標,這對應于世界矩陣變換。為了將三維場景顯示在二維屏幕上,還需要選擇一個觀察點(眼睛/攝像機)和觀察角度(方向/坐標)(對應于觀察坐標矩陣變換),并將3D場景投影到一個2D平面(屏幕)上(對應于投影矩陣變換),還要將超出屏幕的部分去掉(裁剪),也可以將場景投射到屏幕的某個矩形區(qū)域中(視口縮放)。參見圖13-13。世界世界變換觀察變換投影變換裁剪與視口縮放頂點光柵器變換引擎圖13-13Direct3D的變換引擎下面依次對這些變換加以介紹,這需要首先介紹Direct3D中的矩陣定義和變換方法。矩陣與變換在Direct3D中,定義了矩陣(matrix)結構D3DXMATRIX:typedefstructD3DXMATRIX{//矩陣結構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;};}D3DXMATRIX;對應于4*4的浮點矩陣:在Direct3D中,還定義了一個對IntelP4CPU運算進行了優(yōu)化的16字節(jié)對齊的矩陣結構(從D3DXMATRIX派生的C++結構對象):typedefstruct_D3DXMATRIXA16:publicD3DXMATRIX{//16字節(jié)對齊矩陣結構_D3DXMATRIXA16();_D3DXMATRIXA16(CONSTFLOAT*f);_D3DXMATRIXA16(CONSTD3DMATRIX&m);_D3DXMATRIXA16(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);void*operatornew(size_ts);void*operatornew[](size_ts);voidoperatordelete(void*p);voidoperatordelete[](void*p);struct_D3DXMATRIXA16&operator=(CONSTD3DXMATRIX&rhs);}_D3DXMATRIXA16;typedefD3DX_ALIGN16_D3DXMATRIXA16D3DXMATRIXA16;Direct3D還提供了若干全局矩陣函數(shù),如:D3DXMATRIX*D3DXMatrixIdentity(D3DXMATRIX*pOut);//創(chuàng)建單位矩陣FLOATD3DXMatrixDeterminant(CONSTD3DXMATRIX*pM);//返回矩陣的行列式值D3DXMATRIX*D3DXMatrixInverse(//計算逆矩陣D3DXMATRIX*pOut,//結果矩陣FLOAT*pDeterminant,//行列式值,可置為NULLCONSTD3DXMATRIX*pM//原矩陣);D3DXMATRIX*D3DXMatrixMultiply(//兩矩陣相乘D3DXMATRIX*pOut,//結果矩陣CONSTD3DXMATRIX*pM1,//矩陣1CONSTD3DXMATRIX*pM2//矩陣2);矩陣變換(transform)的實施,可采用IDirect3DDevice9接口提供的SetTransform方法:HRESULTSetTransform(//成功返回D3D_OK(=0)D3DTRANSFORMSTATETYPEState,//變換類型狀態(tài)值CONSTD3DMATRIX*pMatrix//變換矩陣);其中State的取值可為D3DTRANSFORMSTATETYPE枚舉類型或D3DTS_WORLDMATRIX宏的值。如:D3DTS_VIEW(=2,觀察變換)、D3DTS_PROJECTION(=3,投影變換)、D3DTS_TEXTURE0~7(=16~23,紋理變換)、D3DTS_WORLD(=256,世界變換)等。例如:D3DXMATRIXA16matWorld;//定義矩陣結構對象D3DXMatrixIdentity(&matWorld);//變成單位矩陣……//對matWorld進行其他矩陣變換g_pd3dDevice->SetTransform(D3DTS_WORLD,&matWorld);//實施變換世界變換圖13-14世界變換一般用每個物體各自的本地坐標來描述所對應的3D幾何對象,而用統(tǒng)一的世界坐標來描述整個場景(參見圖13-14),渲染之前需要將頂點從本地坐標系轉換到世界坐標系。稱這種從本地坐標到世界坐標的轉換為世界變換(worldtransform),世界變換包含平移(translation)、旋轉(rotation)和縮放(scaling)等三種具體變換類型,它們都可用對應的矩陣變換來表示。圖13-14世界變換下面是Direct3D提供的若干世界矩陣變換的全局函數(shù):D3DXMATRIX*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方向的比例因子);可以通過這些函數(shù),獲得所需要的各種變換矩陣。最后,還須使用D3DTS_WORLD狀態(tài)值,來調用IDirect3DDevice9接口的SetTransform方法,以實施最終矩陣所對應的世界變換。例如:D3DXMatrixTranslation(&matWorld,m_xPos,m_yPos,m_zPos);//平移D3DXMatrixRotationX(&matWorld,m_fPitch);//繞x軸旋轉g_pd3dDevice->SetTransform(D3DTS_WORLD,&matWorld);//實施世界變換觀察變換觀察變換(viewtransform),可在世界坐標系(xw,yw,zw)中設置和改變觀察者的位置和方向,將世界空間中的頂點轉換到攝影空間(cameraspace)(xe,ye,ze),參見圖13-15。圖13-15觀察變換在Direct3D中,觀察矩陣由全局助手函數(shù)D3DXMatrixLookAtLH(Left-Handed,左手系)和D3DXMatrixLookAtRH(Right-Handed,右手系)來創(chuàng)建:圖13-15觀察變換D3DXMATRIX*D3DXMatrixLookAtLH(//創(chuàng)建左手系觀察矩陣(右手系:LH→RH)D3DXMATRIX*pOut,//結果矩陣CONSTD3DXVECTOR3*pEye,//眼睛位置點CONSTD3DXVECTOR3*pAt,//觀察目標點(方向),通常取為原點(0,0,0)CONSTD3DXVECTOR3*pUp//觀察上方點,通常取為y軸正向(0,1,0));可以通過這兩個函數(shù)之一(一般采用左手系的觀察矩陣函數(shù)),來獲得所需要的觀察變換矩陣。最后,也是需要使用D3DTS_VIEW狀態(tài)值,來調用IDirect3DDevice9接口的SetTransform方法,以實施矩陣所對應的觀察變換。例如:D3DXMATRIXmatView;//定義觀察矩陣結構D3DXVECTOR3eye(2,3,3);//設眼睛位置為(2,3,3)D3DXVECTOR3at(0,0,0);//設目標點為原點D3DXVECTOR3up(0,1,0);//設y軸正向為上方D3DXMatrixLookAtLH(&matView,&eye,&at,&up);//獲取觀察變換矩陣g_pd3dDevice->SetTransform(D3DTS_VIEW,&matView);//實施觀察變換投影變換投影變換(projectiontransform)將觀察平截頭體(frustum,切割物體的兩個平面之間的立體部分)轉換為一個立方體形狀(cuboidshape)??拷^察點的物體,投影后會顯得大一些。參見圖13-16。圖13-16投影變換與觀察平截頭體 圖13-17觀察平截頭體的確定觀察平截頭體由fov(fieldofview,視場/視野)角度和前后剪切面(frontandbackclippingplanes)的(用z坐標指定的)距離來決定,參見圖13-17。圖13-18投影變換將觀察平截頭體轉換為一個立方體投影矩陣是典型的縮放和透視投影(scaleandperspectiveprojection)變換,它將觀察平截頭體轉換為一個立方體,其原點也從右上角移到了中心。參見圖13-18。圖13-18投影變換將觀察平截頭體轉換為一個立方體Direct3D提供了下列6個全局函數(shù)來創(chuàng)建投影矩陣:創(chuàng)建左手系透視投影矩陣——D3DXMatrixPerspectiveLH;創(chuàng)建右手系透視投影矩陣——D3DXMatrixPerspectiveRH;創(chuàng)建基于視野的左手系透視投影矩陣——D3DXMatrixPerspectiveFovLH;創(chuàng)建基于視野的右手系透視投影矩陣——D3DXMatrixPerspectiveFovRH;創(chuàng)建定制的左手系透視投影矩陣——D3DXMatrixPerspectiveOffCenterLH。創(chuàng)建定制的右手系透視投影矩陣——D3DXMatrixPerspectiveOffCenterRH。其中最常用的是創(chuàng)建基于視野的左手系透視投影矩陣函數(shù):D3DXMATRIX*D3DXMatrixPerspectiveFovLH(//返回結果矩陣D3DXMATRIX*pOut,//結果矩陣FLOATfovY,//視角(弧度值)FLOATAspect,//水平視角與垂直視角的比例FLOATzn,//近觀察平面(前剪切面)的Z值(距離)FLOATzf//遠觀察平面(后剪切面)的Z值(距離));其返回矩陣為:其中:yScale=tan(2/fovY)、xScale=yScale/Aspect與世界變換和觀察變換一樣,在獲得了投影變換矩陣后,也需要使用D3DTS_PROJECTION狀態(tài)值,來調用IDirect3DDevice9接口的SetTransform方法,以實施該矩陣所對應的投影變換。例如:D3DXMATRIXA16matProj;//定義矩陣結構//設置基于視野的左手系透視投影矩陣(45度視角、水平與垂直視角的比例為1、//Z值從1~100)D3DXMatrixPerspectiveFovLH(&matProj,D3DX_PI/4,1.0f,1.0f,100.0f);g_pd3dDevice->SetTransform(D3DTS_PROJECTION,&matProj);//實施投影變換剪切和窗口縮放視口(viewport)是一個(三維場景被投影到其中的)二維矩形。當視口小于Direct3D的顯示表面(如屏幕)時,就需要進行裁剪(clipping)。參見圖13-19。在Direct3D中,定義了視口結構:typedefstructD3DVIEWPORT9{//視口結構DWORDX;//視口矩形左上角的x坐標DWORDY;//視口矩形左上角的y坐標DWORDWidth;//視口矩形的寬度DWORDHeight;//視口矩形的高度圖13-19顯示表面與視口(結構)floatMinZ;//最小深度緩沖值圖13-19顯示表面與視口(結構)floatMaxZ;//最大深度緩沖值}D3DVIEWPORT9;可以用IDirect3DDevice9接口的SetViewport和GetViewport方法來設置和獲取視口:HRESULTSetViewport(CONSTD3DVIEWPORT9*pViewport);//設置視口HRESULTGetViewport(D3DVIEWPORT9*pViewport);//獲取視口例如:D3DVIEWPORT9vp(0,0,800,600,0,1);g_pd3dDevice->SetViewport(&vp);13.2.6光照、材質與紋理幾何對象只有形狀和大小,而真實的物體還有材質、紋理、重量、剛度、彈性等等其他物理特性,我們這里只討論影響其外觀的材質和紋理。當然,任何物體,如果沒有光線照射,你是什么也看不見的。所以,場景的最后觀看效果,還取決于燈光的設置。下面簡單介紹Direct3D中的光照安排、材質設置和紋理使用等的基本內(nèi)容。光照光照(light燈光)用于照亮三維場景中的物體。Direct3D提供了兩種燈光模式:環(huán)境光和直接光。環(huán)境光(ambientlight)是一種散射的光,沒有固定的方向,也不會產(chǎn)生陰影,可以照亮場景的任何地方。例如陰天。圖13-20直接光的種類聚光外角φ內(nèi)角θ光照區(qū)方向光點光圖13-20直接光的種類聚光外角φ內(nèi)角θ光照區(qū)方向光點光在Direct3D中定義了光結構D3DLIGHT9:typedefstructD3DLIGHT9{光結構D3DLIGHTTYPEType;//光類型D3DCOLORVALUEDiffuse;//光發(fā)出的漫射色D3DCOLORVALUESpecular;//光發(fā)出的反射色D3DCOLORVALUEAmbient;//光發(fā)出的環(huán)境色D3DVECTORPosition;//光源位置點,方向光時被忽略D3DVECTORDirection;//光的方向(非0矢量),點光時被忽略floatRange;//范圍:光照距離的最大值,必須≤最大浮點值的平方根,方向光時被忽略floatFalloff;//下降:聚光時的內(nèi)角到外角的光線衰減值(0.0~1.0),一般取為1.0floatAttenuation0;//衰減0:光線強度和距離關系的計算權值0,取值0.0~∞floatAttenuation1;//Direct3D中光強衰減倍數(shù)A的計算公式(D為到光源的距離):floatAttenuation2;//floatTheta;//θ:聚光的內(nèi)角大小floatPhi;//φ:聚光的外角大小}D3DLIGHT9;其中:光類型枚舉D3DLIGHTTYPE定義為:typedefenumD3DLIGHTTYPE{//光類型枚舉D3DLIGHT_POINT=1,//點光D3DLIGHT_SPOT=2,//聚光D3DLIGHT_DIRECTIONAL=3,//方向光D3DLIGHT_FORCE_DWORD=0x7fffffff,//強制此枚舉類型的值為雙字}D3DLIGHTTYPE;浮點顏色值結構D3DCOLORVALUE的定義為:(其中各字段的取值范圍為0.0~1.0)typedefstructD3DCOLORVALUE{floatr;floatg;floatb;floata;}D3DCOLORVALUE;其中,a為表示透明度的α值。矢量結構D3DVECTOR的定義為:typedefstructD3DVECTOR{floatx,y,z;}D3DVECTOR;在定義并初始化了光結構后,可以利用IDirect3DDevice9接口的SetLight方法,來設置場景的各個燈光:HRESULTSetLight(//成功返回D3D_OKDWORDIndex,//燈光的索引值(下同)CONSTD3DLight9*pLight//燈光的結構);可以對一個場景設置多個燈光,它們用各自的索引值來標識。對同一索引值的再次燈光設置,將會覆蓋掉原來已有的設置。還可以利用IDirect3DDevice9接口的GetLight方法,來保存場景的燈光設置:HRESULTGetLight(DWORDIndex,D3DLight9*pLight);注意,Direct3D允許打開和關閉所設置的各個燈光,這可由IDirect3DDevice9接口的LightEnable方法來完成:HRESULTLightEnable(//成功返回D3D_OKDWORDLightIndex,//燈光的索引值BOOLbEnable//TRUE:開,F(xiàn)ALSE:關);還可以利用IDirect3DDevice9接口的GetLightEnable方法,來獲取場景中的燈光開關情況:HRESULTGetLightEnable(DWORDIndex,BOOL*pEnable/*返回值*/);例如:D3DLight9d3dLight;//定義燈光結構變量ZeroMemory(&D3dLight,sizeof(d3dLight));//初始化為0//設置白色電光d3dLight.Type=D3DLIGHT_POINT;d3dLight.Diffuse.r=1.0f; d3dLight.Diffuse.g=1.0f; d3dLight.Diffuse.b=1.0f;d3dLight.Ambient.r=1.0f; d3dLight.Ambient.g=1.0f; d3dLight.Ambient.b=1.0f;d3dLight.Specular.r=1.0f; d3dLight.Specular.g=1.0f; d3dLight.Specular.b=1.0f;//設置光源位置d3dLight.Position.x=0.0f; d3dLight.Position.y=1000.0f; d3dLight.Position.z=-100.0f;d3dLight.Attenuation0=1.0f;//無衰減d3dLight.Range=1000.0f;//最大距離if(g_pd3dDevice->SetLight(0,&d3dLight)==D3D_OK)//設置燈光g_pd3dDevice->LightEnable(0,TRUE);//打開燈光材質材質(material)是構成物體的材料和質地(如金屬、木頭、布料、鏡子等),它決定了物體表面隊光線的反應:如何反射光線,包括如何進行鏡面反射和漫反射;在高光部分如何反射光線;是否自己發(fā)出光線沒有設置材質的物體,不能反射任何光線。因此,即使場景中有光源,物體仍然顯示出一片黑暗,你什么也不會看到。所以,只有給場景的物體指定了材質,才會在顯示出正確的光照效果來。在Direct3D中,并沒有給出一個與自然物體(如木材、鋼鐵、布料等)對應的材質表,而是定義了一個可以設置物體反光特性的材質結構D3DMATERIAL9:typedefstructD3DMATERIAL9{//材質結構D3DCOLORVALUEDiffuse;//漫反射光線的顏色D3DCOLORVALUEAmbient;//環(huán)境反射光線的顏色D3DCOLORVALUESpecular;//(高光部分)鏡面反射光線的顏色D3DCOLORVALUEEmissive;//發(fā)射光線的顏色(光源)floatPower;//鏡面反射光線的強度}D3DMATERIAL9;可以利用IDirect3DDevice9接口的SetMaterial方法來為Direct3D設備設置材質:HRESULTSetMaterial(CONSTD3DMATERIAL9*pMaterial);//成功返回D3D_OK該材質設置對后面所渲染的所有物體都有效。如果希望對不同的物體設置不同的材質,就必須在渲染每個物體前,重新設置Direct3D設備為對應的材質。你還可以利用IDirect3DDevice9接口的GetMaterial方法來獲取Direct3D設備的當前材質設置:HRESULTGetMaterial(D3DMATERIAL9*pMaterial/*返回材質設置*/);例如:D3DMATERIAL9mat;//定義材質結構變量//設置漫反射顏色值RGBAmat.Diffuse.r=0.5f; mat.Diffuse.g=0.0f; mat.Diffuse.b=0.5f; mat.Diffuse.a=1.0f;//設置環(huán)境反射顏色值RGBAmat.Ambient.r=0.5f; mat.Ambient.g=0.0f; mat.Ambient.b=0.5f; mat.Ambient.a=1.0f;//設置鏡面反射顏色值和強度mat.Specular.r=1.0f; mat.Specular.g=1.0f; mat.Specular.b=1.0f; mat.Specular.a=1.0f;mat.Power=50.0f;//設置發(fā)射顏色值RGBAmat.Emissive.r=0.0f; mat.Emissive.g=0.0f; mat.Emissive.b=0.0f; mat.Emissive.a=0.0f;g_pd3dDev->SetMaterial(&mat);//設置設備材質紋理紋理(texture)是物體的表面圖形特征(花紋),它比單一的表面顏色更逼近真實。在Direct3D中,紋理實際上被定義為覆蓋在物體表面的矩形平面圖像。為了將紋理覆蓋在物體表面上,需要確定紋理在物體表面上的位置,稱之為紋理坐標。在Direct3D中,定義了一個統(tǒng)一的紋理坐標系,其紋理坐標的取值范圍為規(guī)范為0.0~1.0。紋理中單個的顏色值,稱為紋理元素(texel=textureelement)。參見圖13-21。為了在物體表面上使用紋理,在定義頂點格式時,必須考慮紋理坐標(x,y)。例如:structCUSTOMVERTEX{//頂點結構D3DXVECTOR3position;//位置D3DCOLORcolor;//顏色FLOATtu,tv;//紋理坐標圖13-21紋理坐標與映射}圖13-21紋理坐標與映射對應的宏常量定義也改為:#defineD3DFVF_CUSTOMVERTEX(D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEX1)在Direct3D中,定義了多種紋理接口,其中最主要的是IDirect3DTexture9。在Direct3D中,創(chuàng)建紋理的最簡單的方法是,調用全局函數(shù)D3DXCreateTextureFromFile:HRESULTD3DXCreateTextureFromFile(//成功返回D3D_OKLPDIRECT3DDEVICE9pDevice,//設備指針LPCTSTRpSrcFile,//圖像文件路徑串LPDIRECT3DTEXTURE9*ppTexture//返回的紋理接口指針);來從一個圖像文件來產(chǎn)生紋理,它所支持的圖像文件格式有:BMP、DDS、DIB、HDR、JPG、PFM、PNG、PPM和TGA,但是不支持GIF格式。然后,我們可使用IDirect3DDevice9接口的SetTexture方法,來設置Direct3D設備的當前紋理狀態(tài):(似材質設置,對后面渲染的物體有效)HRESULTSetTexture(//成功返回D3D_OKDWORDSampler,//采樣器編號,用于可編程渲染的參考紋理和紋理層次編號IDirect3DBaseTexture9*pTexture//紋理接口指針(NULL=清除紋理));例如:LPDIRECT3DTEXTURE9g_pTexture=NULL;if(D3DXCreateTextureFromFile(g_pd3dDevice,"picture.bmp
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經(jīng)權益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
- 6. 下載文件中如有侵權或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 專用版全新幼兒園承包協(xié)議模板下載版A版
- 2024鐵礦石銷售合同中的環(huán)境保護附加條款規(guī)范3篇
- 2025年度廠房建設施工后期維護合同范本4篇
- 二手服務器租賃服務詳細合同2024年版一
- 二零二五年度生態(tài)修復工程出渣承包服務協(xié)議3篇
- 2024遺產(chǎn)房產(chǎn)繼承轉讓合同
- 2025年度拆除工程竣工驗收合同樣本下載4篇
- 2024年能源管理服務協(xié)議
- 二零二四年城市綠化帶設施維護勞務分包服務協(xié)議3篇
- 二零二五版地磅租賃與物流配送一體化服務協(xié)議
- 釘釘OA辦公系統(tǒng)操作流程培訓
- 新生兒科年度護理質控總結
- GB/T 15934-2024電器附件電線組件和互連電線組件
- 《工貿(mào)企業(yè)有限空間作業(yè)安全規(guī)定》知識培訓
- 高層次人才座談會發(fā)言稿
- 垃圾清運公司管理制度(人員、車輛、質量監(jiān)督、會計管理制度)
- 《建筑工程設計文件編制深度規(guī)定》(2022年版)
- 營銷人員薪酬考核方案
- 2024至2030年中國it外包服務行業(yè)市場深度分析及發(fā)展趨勢預測報告
- 工程項目計價結算付款情況統(tǒng)計表
- GB/T 20554-2024海帶
評論
0/150
提交評論