原文出處:點擊打開鏈接
初始化Direct3D(步驟)
下面幾點說明怎樣初始化Direct3D。根據下邊的步驟你能初始化Direct3D:
1.獲得一個IDirect3D9接口指針。這個接口用於獲得物理設備的信息和創建一個IDirect3DDevice9接口,它是一個代表我們顯示3D圖形的物理設備的C++對象。
2.檢查設備的技術特性(D3DCAPS9),搞清楚主顯卡是否支持硬件頂點處理。我們需要知道假如它能支持,我們就能創建IDirect3DDevice9接口。
3.初始化一個D3DPRESENT_PARAMETERS結構實例,這個結構包含了許多數據成員允許我們指定將要創建的IDirect3DDevice9接口的特性。
4.創建一個基於已經初始化好的D3DPRESENT_PARAMETERS結構的IDirect3DDevice9對象。它是一個代表我們顯示3D圖形的物理設備的C++對象。
請注意,本書使用主顯示設備繪製3D圖形,如果你的機子只有一塊顯卡,那它就是主顯示設備。如果你有多個顯卡,那麼你當前使用的顯卡將會成爲主顯示設備(如:用來顯示Windows桌面的顯卡)。
//
一)獲得IDirect3D9接口
先預習一下下面COM的內容
----------------------------------------------------------------------------------------------------------------------------------------------------------
組件對象模型(COM, Component Object Model)是一種能使DirectX獨立於編程語言和具有向下兼容性的技術。我們通常把COM對象作爲一個接口,你可以把它當作達到某種目的的C++類來使用它。當使用C++寫DirectX程序的時候,COM的大部分細節對我們來說是透明。但是有一件事,我們必須知道,那就是我們通過某個特殊的COM接口的函數或指針獲得了另一個COM接口指針,而不是通過C++的新關鍵字來創建它。
當我們使用完某個接口後,調用它的Release方法比直接Delete它更好。COM對象具有它們自己的內存管理。
對COM來說還有很多細節可以瞭解,但是掌握這些細節對於我們有效的使用DirectX不是必須的。
注意:COM接口都具有前綴大寫字母“I”,例如表示一個表面的COM接口叫做IDirect3DSurface9。
-----------------------------------------------------------------------------------------------------------------------------------------------------------
Direct3D的初始化是從獲得一個IDirect3D9接口指針開始的。使用一個專門的Direct3D函數來完成這個工作是非常容易的,代碼如下:
IDirect3D9* _d3d9; _d3d9 = Direct3DCreate9(D3D_SDK_VERSION); |
Direct3DCreate9的唯一一個參數總是D3D_SDK_VERSION,這可以保證應用程序通過正確的頭文件被生成。如果函數調用失敗,那麼它將返回一個空指針。
IDirect3D9對象通常有兩個用途:
1)設備列舉:設備列舉即爲查明系統中顯示設備的技術特性,顯示模式、格式,以及其它每一種顯卡各自支持的特性。
2)創建IDirect3DDevice9對象:創建代表物理設備的IDirect3DDevice9對象,我們需要利用這個物理設備的顯示模式結構和格式來創建它。爲了找到一個工作配置,我們必須使用IDirect3D9的列舉方法。
二)檢查設備的技術特性(D3DCAPS9)
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
頂點是3D圖形學的基礎,它能夠通過兩種不同的方法被處理,一種是軟件方式(software vertex processing),一種是硬件方式(hardware vertex processing),前者總是被支持且永遠可用,後者必須要顯卡硬件支持頂點處理纔可用。
使用硬件頂點處理總是首選,因爲它比軟件方式更快,而且不佔用CPU資源,這意味CPU至少可以有更多的空閒時間進行別的計算。
注意:如果一塊顯卡支持硬件頂點處理的話,也就是說它也支持硬件幾何轉換和光源計算。
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
(1) 檢測硬件頂點處理
IDirect3D9::GetDeviceCaps Method
Retrieves device-specific information about a device. //返回關於設備的信息
Syntax
HRESULT GetDeviceCaps(
UINT Adapter,
D3DDEVTYPE DeviceType,
D3DCAPS9 *pCaps
);
Parameters
Adapter
[in] Ordinal number that denotes the display adapter.D3DADAPTER_DEFAULT is always the primary display adapter. //一般使用D3DADAPTER_DEFAULT 指定要獲得哪個顯示適配器的特性
DeviceType
[in] Member of theD3DDEVTYPE enumerated type. Denotes the device type. //設備類型 :指定設備類型(硬件設備(D3DDEVTYPE_HAL),軟件設備(D3DDEVTYPE_REF))
pCaps
[out] Pointer to aD3DCAPS9 structure to be filled with information describing the capabilities of the device. //返回一個已初始化的D3DCAPS9結構
Return Value
If the method succeeds, the return value isD3D_OK.
//如果成功D3D_OK返回
If the method fails, the return value can be one of the following values.
D3DERR_INVALIDCALL |
The method call is invalid. For example, a method's parameter may have an invalid value. |
D3DERR_INVALIDDEVICE |
The requested device type is not valid. |
D3DERR_OUTOFVIDEOMEMORY |
Direct3D does not have enough display memory to perform the operation. |
Remarks
The application should not assume the persistence of vertex processing capabilities across Microsoft Direct3D device objects. The particular capabilities that a physical device exposes may depend on parameters supplied to IDirect3D9::CreateDevice. For example, the capabilities may yield different vertex processing capabilities before and after creating a Direct3D Device Object with hardware vertex processing enabled. For more information see the description ofD3DCAPS9.
// Fill D3DCAPS9 structure with the capabilities of the // primary display adapter. //填充 D3DCAPS9結構用檢測到的顯示適配器的特性
D3DCAPS9 caps; d3d9->GetDeviceCaps( D3DADAPTER_DEFAULT, // Denotes primary display adapter.指定主顯卡 deviceType, // Specifies the device type, usually D3DDEVTYPE_HAL. //指定設備內容 一般使用D3DDEVTYPE_HAL. &caps); // Return filled D3DCAPS9 structure that contains // the capabilities of the primary display adapter. //返回一個已初始化的D3DCAPS9結構 // Can we use hardware vertex processing? int vp = 0; if( caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT ) { //檢測硬件是否支持變換和燈光的 // yes, save in ‘vp’ the fact that hardware vertex // processing is supported. vp = D3DCREATE_HARDWARE_VERTEXPROCESSING; } else { // no, save in ‘vp’ the fact that we must use software // vertex processing. vp = D3DCREATE_SOFTWARE_VERTEXPROCESSING; //沒有意見支持那麼就選軟件支持 } |
觀察代碼,我們使用變量vp來存儲頂點處理類型。這是因爲在稍後創建IDirect3DDevice9對象時要求指定其頂點處理的類型。
注意:標識符D3DCREATE_HARDWARE_VERTEXPROCESSING和D3DCREATE_SOFTWARE_VERTEXPROCESSING是預定義的值,它們分別代表硬件頂點處理和軟件頂點處理。
技巧:若我們開發有一些新的,高級的特性的程序,在使用前我們總是先檢查硬件是否支持這些特性。
注意:如果一個應用程序在你的機子上不能運行,說明它用到的一些特性可能你的顯卡並不支持,可以試試把設備類型換成REF。
三)初始化一個D3DPRESENT_PARAMETERS結構實例
初始化過程的下一步是填充一個D3DPRESENT_PARAMETERS結構的實例。這個結構用於設定我們將要創建的IDirect3DDevice9對象的一些特性,它的定義如下:
typedef struct _D3DPRESENT_PARAMETERS_ { UINT BackBufferWidth; UINT BackBufferHeight; D3DFORMAT BackBufferFormat; UINT BackBufferCount; D3DMULTISAMPLE_TYPE MultiSampleType; DWORD MultiSampleQuality; D3DSWAPEFFECT SwapEffect; HWND hDeviceWindow; BOOL Windowed; BOOL EnableAutoDepthStencil; D3DFORMAT AutoDepthStencilFormat; DWORD Flags; UINT FullScreen_RefreshRateInHz; UINT PresentationInterval; } D3DPRESENT_PARAMETERS; |
下面介紹其比較重要的數據成員,至於更詳細的信息,請查閱SDK:
BackBufferWidth——後備緩衝表面的寬度(以像素爲單位)
BackBufferHeight——後備緩衝表面的高度(以像素爲單位)
BackBufferFormat——後備緩衝表面的像素格式(如:32位像素格式爲D3DFMT——A8R8G8B8)
BackBufferCount——後備緩衝表面的數量,通常設爲“1”,即只有一個後備表面
MultiSampleType——全屏抗鋸齒的類型,詳情請看SDK
MultiSampleQuality——全屏抗鋸齒的質量等級,詳情看SDK
SwapEffect——指定表面在交換鏈中是如何被交換的,取D3DSWAPEFFECT枚舉類型中的一個成員。其中D3DSWAPEFFECT_DISCARD是最有效的
hDeviceWindow——與設備相關的窗口句柄,你想在哪個窗口繪製就寫那個窗口的句柄
Windowed——BOOL型,設爲true則爲窗口模式,false則爲全屏模式
EnableAutoDepthStencil——設爲true,D3D將自動創建深度/模版緩衝
AutoDepthStencilFormat——深度/模版緩衝的格式
Flags——一些附加特性,設爲0或D3DPRESENTFLAG類型的一個成員。下列兩個最常用的標誌
全部的標誌請查閱SDK:
D3DPRESENTFLAG_LOCKABLE_BACKBUFFER——設定後備表面能夠被鎖定,這會降低應用程序的性能
D3DPRESENTFLAG_DISCARD_DEPTHSTENCIL——深度/模版緩衝在調用IDirect3DDevice9::present方法後將被刪除,這有利於提升程序性能
FullScreen_RefreshRateInHz——刷新率,設定D3DPRESENT_RATE_DEFAULT使用默認刷新率
PresentationInterval——屬於D3DPRESENT成員,又有兩個常用標誌,其餘請查SDK:
D3DPRESENT_INTERVAL_IMMEDIATE——立即交換
D3DPRESENT_INTERVAL_DEFAULT——D3D選擇交換速度,通常等於刷新率
填充示例如下:
D3DPRESENT_PARAMETERS d3dpp; d3dpp.BackBufferWidth = 800; d3dpp.BackBufferHeight = 600; d3dpp.BackBufferFormat = D3DFMT_A8R8G8B8; //pixel format d3dpp.BackBufferCount = 1; d3dpp.MultiSampleType = D3DMULTISAMPLE_NONE; d3dpp.MultiSampleQuality = 0; d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; d3dpp.hDeviceWindow = hwnd; d3dpp.Windowed = false;// fullscreen d3dpp.EnableAutoDepthStencil = true; d3dpp.AutoDepthStencilFormat = D3DFMT_D24S8; // depth format d3dpp.Flags = 0; d3dpp.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT; d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; |
四)創建IDirect3DDevice9對象
在填充完了D3DPRESENT_PARAMETERS結構後,我們就可以用下面的方法創建一個IDirect3DDevice9對象了:
HRESULT IDirect3D9::CreateDevice( UINT Adapter, D3DDEVTYPE DeviceType, HWND hFocusWindow, DWORD BehaviorFlags, D3DPRESENT_PARAMETERS * pPresentationParameters, IDirect3DDevice9** ppReturnedDeviceInterface ); |
l Adapter——指定對象要表示的物理顯示設備
l DeviceType——設備類型,前面說過
l hFocusWindow——同我們在前面d3dpp.hDeviceWindow的相同
l BehaviorFlags——設定爲D3DCREATE_SOFTWARE_VERTEXPROCESSING或者D3DCREATE_HARDWARE_VERTEXPROCESSING
l pPresentationParameters——指定一個已經初始化好的D3DPRESENT_PARAMETERS實例
l ppReturnedDeviceInterface——返回創建的設備
例子:
IDirect3DDevice9* device = 0; hr = d3d9->CreateDevice( D3DADAPTER_DEFAULT,// primary adapter D3DDEVTYPE_HAL,// device type hwnd, // window associated with device D3DCREATE_HARDWARE_VERTEXPROCESSING,// vertex processing type &d3dpp,// present parameters &device);// returned created device if( FAILED(hr) ) { ::MessageBox(0, "CreateDevice() - FAILED", 0, 0); return 0; } |