1.4
初始化Direct3D
下面幾點(diǎn)說(shuō)明怎樣初始化Direct3D。根據(jù)下邊的步驟你能初始化Direct3D:
1.
獲得一個(gè)IDirect3D9接口指針。這個(gè)接口用于獲得物理設(shè)備的信息和創(chuàng)建一個(gè)IDirect3DDevice9接口,它是一個(gè)代表我們顯示3D圖形的物理設(shè)備的C++對(duì)象。
2.
檢查設(shè)備能力(D3DCAPS9),搞清楚主顯卡是否支持硬件頂點(diǎn)處理。我們需要知道假如它能支持,我們就能創(chuàng)建IDirect3DDevice9接口。
3.
初始化一個(gè)D3DPRESENT_PARAMETERS結(jié)構(gòu)實(shí)例,這個(gè)結(jié)構(gòu)包含了許多數(shù)據(jù)成員允許我們指定將要?jiǎng)?chuàng)建的IDirect3DDevice9接口的特性。
4.
創(chuàng)建一個(gè)基于已經(jīng)初始化好的D3DPRESENT_PARAMETERS結(jié)構(gòu)的IDirect3DDevice9對(duì)象。它是一個(gè)代表我們顯示3D圖形的物理設(shè)備的C++對(duì)象。
請(qǐng)注意,我們使用主顯示設(shè)備繪制3D圖形,如果你的機(jī)子只有一塊顯卡,那它就是主顯示設(shè)備。如果你有多個(gè)顯卡,那么你當(dāng)前使用的顯卡將會(huì)成為主顯示設(shè)備(如:用來(lái)顯示W(wǎng)indows桌面的顯卡)。
1.4.1獲得IDirect3D9接口
Direct3D的初始化是從獲得一個(gè)IDirect3D9接口指針開(kāi)始的。使用一個(gè)專門的Direct3D函數(shù)來(lái)完成這個(gè)工作是非常容易的,代碼如下:
|
IDirect3D9* _d3d9;
_d3d9 =
Direct3DCreate9(D3D_SDK_VERSION);
|
Direct3DCreate9的唯一一個(gè)參數(shù)總是D3D_SDK_VERSION,這可以保證應(yīng)用程序通過(guò)正確的頭文件被生成。如果函數(shù)調(diào)用失敗,那么它將返回一個(gè)空指針。
IDirect3D9對(duì)象通常有兩個(gè)用途:設(shè)備列舉和創(chuàng)建IDirect3DDevice9對(duì)象。設(shè)備列舉即為查明系統(tǒng)中顯示設(shè)備的技術(shù)特性,顯示模式、格式,以及其它每一種顯卡各自支持的特性。創(chuàng)建代表物理設(shè)備的IDirect3DDevice9對(duì)象,我們需要利用這個(gè)物理設(shè)備的顯示模式結(jié)構(gòu)和格式來(lái)創(chuàng)建它。為了找到一個(gè)工作配置,我們必須使用IDirect3D9的列舉方法。
然而,設(shè)備列舉實(shí)在太慢了,為了使Direct3D運(yùn)行得盡可能快,我們通常不使用這個(gè)測(cè)試,除了下一節(jié)所談到的一項(xiàng)測(cè)試。為了安全跳過(guò)它,我們可以選擇總是被所有顯卡都支持的“安全”配置。
1.4.2
檢測(cè)硬件頂點(diǎn)處理
當(dāng)我們創(chuàng)建一個(gè)IDirect3DDevice9對(duì)象來(lái)表示主顯示設(shè)備時(shí),必須要設(shè)定其頂點(diǎn)處理的類型。如果可以的話,當(dāng)然要選用硬件頂點(diǎn)處理,但是由于并非所有顯卡都支持硬件頂點(diǎn)處理,因此我們必須首先檢查顯卡是否支持。
首先我們要根據(jù)主顯示設(shè)備的技術(shù)特性來(lái)初始化D3DCAPS9實(shí)例。可以使用如下方法:
|
HRESULT
IDirect3D9::GetDeviceCaps(
UINT Adapter,
D3DDEVTYPE
DeviceType,
D3DCAPS9 *pCaps
);
|
Adapter——指定要獲得哪個(gè)顯示適配器的特性
DeviceType——指定設(shè)備類型(硬件設(shè)備(D3DDEVTYPE_HAL),軟件設(shè)備(D3DDEVTYPE_REF))
PCaps——返回一個(gè)已初始化的D3DCAPS9結(jié)構(gòu)
然后,我們就可以象1.3.8部分那樣檢測(cè)顯卡的能力了。下面就是代碼片段:
// Fill D3DCAPS9 structure with the capabilities of the primary display adapter.
D3DCAPS9 caps;
d3d9->GetDeviceCaps(
D3DADAPTER_DEFAULT, // Denotes primary display adapter.
deviceType, // Specifies the device type, usually D3DDEVTYPE HAL.
&caps); // Return filled D3DCAPS9 structure that contains
// the capabilities of the primary display adapter.
// 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來(lái)存儲(chǔ)頂點(diǎn)處理類型。這是因?yàn)樵谏院髣?chuàng)建IDirect3DDevice9對(duì)象時(shí)要求指定其頂點(diǎn)處理的類型。
注意:標(biāo)識(shí)符D3DCREATE_HARDWARE_VERTEXPROCESSING和D3DCREATE_SOFTWARE_VERTEXPROCESSING是預(yù)定義的值,它們分別代表硬件頂點(diǎn)處理和軟件頂點(diǎn)處理。
技巧:若我們開(kāi)發(fā)有一些新的,高級(jí)特性的程序,在使用前我們總是先檢查硬件是否支持這些特性。
注意:如果一個(gè)應(yīng)用程序在你的機(jī)子上不能運(yùn)行,說(shuō)明它用到的一些特性可能你的顯卡并不支持,可以試試把設(shè)備類型換成REF。
1.4.3
填充D3DPRESENT_PARAMETERS結(jié)構(gòu)
初始化過(guò)程的下一步是填充一個(gè)D3DPRESENT_PARAMETERS結(jié)構(gòu)的實(shí)例。這個(gè)結(jié)構(gòu)用于設(shè)定我們將要?jiǎng)?chuàng)建的IDirect3DDevice9對(duì)象的一些特性,它的定義如下:
|
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;
|
下面介紹其比較重要的數(shù)據(jù)成員,至于更詳細(xì)的信息,請(qǐng)查閱SDK:
BackBufferWidth——后備緩沖表面的寬度(以像素為單位)
BackBufferHeight——后備緩沖表面的高度(以像素為單位)
BackBufferFormat——后備緩沖表面的像素格式(如:32位像素格式為D3DFMT——A8R8G8B8)
BackBufferCount——后備緩沖表面的數(shù)量,通常設(shè)為“1”,即只有一個(gè)后備表面
MultiSampleType——全屏抗鋸齒的類型,詳情請(qǐng)看SDK
MultiSampleQuality——全屏抗鋸齒的質(zhì)量等級(jí),詳情看SDK
SwapEffect——指定表面在交換鏈中是如何被交換的,取D3DSWAPEFFECT枚舉類型中的一個(gè)成員。其中D3DSWAPEFFECT_DISCARD是最有效的
hDeviceWindow——與設(shè)備相關(guān)的窗口句柄,你想在哪個(gè)窗口繪制就寫那個(gè)窗口的句柄
Windowed——BOOL型,設(shè)為true則為窗口模式,false則為全屏模式
EnableAutoDepthStencil——設(shè)為true,D3D將自動(dòng)創(chuàng)建深度/模版緩沖
AutoDepthStencilFormat——深度/模版緩沖的格式
Flags——一些附加特性,設(shè)為0或D3DPRESENTFLAG類型的一個(gè)成員。下列兩個(gè)最常用的標(biāo)志
全部的標(biāo)志請(qǐng)查閱SDK:
D3DPRESENTFLAG_LOCKABLE_BACKBUFFER——設(shè)定后備表面能夠被鎖定,這會(huì)降低應(yīng)用程序的性能
D3DPRESENTFLAG_DISCARD_DEPTHSTENCIL——深度/模版緩沖在調(diào)用IDirect3DDevice9::present方法后將被刪除,這有利于提升程序性能
FullScreen_RefreshRateInHz——刷新率,設(shè)定D3DPRESENT_RATE_DEFAULT使用默認(rèn)刷新率
PresentationInterval——屬于D3DPRESENT成員,又有兩個(gè)常用標(biāo)志,其余請(qǐng)查SDK:
D3DPRESENT_INTERVAL_IMMEDIATE——立即交換
D3DPRESENT_INTERVAL_DEFAULT——D3D選擇交換速度,通常等于刷新率
填充示例如下:
|
D3DPRESENT_PARAMETERS
d3dpp;
d3dpp.BackBufferWidth =
800;
d3dpp.BackBufferHeight =
600;
d3dpp.BackBufferFormat =
D3DFMT_A8R8G8B8; //像素格式
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;
|
1.4.4
創(chuàng)建IDirect3DDevice9對(duì)象
在填充完了D3DPRESENT_PARAMETERS結(jié)構(gòu)后,我們就可以用下面的方法創(chuàng)建一個(gè)IDirect3DDevice9對(duì)象了:
|
HRESULT
IDirect3D9::CreateDevice(
UINT Adapter,
D3DDEVTYPE
DeviceType,
HWND hFocusWindow,
DWORD BehaviorFlags,
D3DPRESENT_PARAMETERS *pPresentationParameters,
IDirect3DDevice9**
ppReturnedDeviceInterface
);
|
Adapter——指定對(duì)象要表示的物理顯示設(shè)備
DeviceType——設(shè)備類型,前面說(shuō)過(guò)
hFocusWindow——同我們?cè)谇懊鎑3dpp.hDeviceWindow的相同
BehaviorFlags——設(shè)定為D3DCREATE_SOFTWARE_VERTEXPROCESSING或者D3DCREATE_HARDWARE_VERTEXPROCESSING
pPresentationParameters——指定一個(gè)已經(jīng)初始化好的D3DPRESENT_PARAMETERS實(shí)例
ppReturnedDeviceInterface——返回創(chuàng)建的設(shè)備
例子:
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;
}