天天看點

Direct-X學習筆記--Direct-X的初始化

一.環境配置

從網上下載下傳到DirectX SDK,輕按兩下安裝,即可得到以下檔案。

Direct-X學習筆記--Direct-X的初始化

打開VS2012,打開項目的通用屬性,按照圖中方法配置庫檔案以及包含目錄。

Direct-X學習筆記--Direct-X的初始化

這樣,環境就配置好了。

二.初始化步驟總覽

要想使用Direct-X這麼強大的功能的圖形API,自然要做一番準備工作。具體就分為這麼幾步: (1) 獲得一個IDirect3D9接口指針。這個接口用于獲得實體裝置的資訊和建立一個IDirect3DDevice9接口,它是一個代表我們顯示3D圖形的實體裝置的C++對象。

(2) 檢查裝置的技術特性(D3DCAPS9),搞清楚主顯示卡是否支援硬體頂點處理。我們需要知道假如它能支援,我們就能建立IDirect3DDevice9接口。

(3)初始化一個D3DPRESENT_PARAMETERS結構執行個體,這個結構包含了許多資料成員,它們允許我們指定将要建立的IDirect3DDevice9接口的特性。

(4) 建立一個基于已經初始化好的D3DPRESENT_PARAMETERS結構的IDirect3DDevice9對象。它是一個代表我們顯示3D圖形的實體裝置的C++對象。

三.建立Direct3D接口對象

Direct3DCreate9 的唯一一個參數總是D3D_SDK_VERSION,這可以保證應用程式通過正确的頭檔案被生成。如果函數調用失敗,那麼它将傳回一個空指針。

//第一步:建立D3D接口對象
	LPDIRECT3D9 pD3D = NULL;//建立接口對象 
	if (NULL == (pD3D = Direct3DCreate9(D3D_SDK_VERSION)))//初始化D3D接口對象,檢查SDK版本
		return E_FAIL;
           

四.檢查裝置資訊(是否支援頂點硬體處理)

當我們建立一個IDirect3DDevice9對象來表示主顯示裝置時,必須要設定其頂點處理的類型。如果可以的話,當然要選用硬體頂點處理,但是由于并非所有顯示卡都支援硬體頂點處理,是以我們必須首先檢查顯示卡是否支援。

通過以下方法檢測,原型如下:

HRESULT IDirect3D9::GetDeviceCaps(

UINT Adapter,

D3DDEVTYPE DeviceType,

D3DCAPS9 *pCaps

); 注:

 Adapter——指定要獲得哪個顯示擴充卡的特性

 DeviceType — — 指定裝置類型( 硬體裝置( D3DDEVTYPE_HAL ), 軟體裝置(D3DDEVTYPE_REF))

 PCaps——傳回一個已初始化的D3DCAPS9 結構

例子:

//第二步:擷取硬體裝置資訊
	D3DCAPS9 caps;
	int vp = 0;
	if (FAILED(pD3D->GetDeviceCaps(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, &caps)))
	{
		return E_FAIL;
	}
	if (caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT)//D3DDVCAPS_HWTRANSFORMANDLIGHT表示顯示卡可以支援變換和光照
		vp = D3DCREATE_HARDWARE_VERTEXPROCESSING;//如果硬體支援頂點運算,采用硬體頂點運算
	else
		vp = D3DCREATE_SOFTWARE_VERTEXPROCESSING;//不支援硬體頂點運算,采用軟體頂點運算
           

五.填充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;

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結構體
	D3DPRESENT_PARAMETERS d3dpp;
	ZeroMemory(&d3dpp, sizeof(d3dpp));//清除内容

	d3dpp.BackBufferWidth = WINDOW_WIDE;
	d3dpp.BackBufferHeight = WINDOW_HEIGHT; //背景緩沖區的長寬
	d3dpp.BackBufferFormat = D3DFMT_A8R8G8B8; //背景緩沖區像素格式
	d3dpp.BackBufferCount = 1; // 背景緩沖區(寬度?)
	d3dpp.MultiSampleType = D3DMULTISAMPLE_NONE;//多重采樣類型
	d3dpp.MultiSampleQuality = 0;//多重采樣類型
	d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;//如何将背景緩沖區的内容複制到前台
	d3dpp.hDeviceWindow = hWnd;//視窗的句柄(如果設為NULL,就會在目前激活的視窗上繪制)
	d3dpp.Windowed = true;//繪制窗體的顯示模式,true表示視窗模式,false表示全屏模式
	d3dpp.EnableAutoDepthStencil = true;//是否為應用程式自動管理深度緩存
	d3dpp.AutoDepthStencilFormat = D3DFMT_D24S8; //設定深度緩沖的像素格式
	d3dpp.Flags = 0;//附加屬性,通常為0
	d3dpp.FullScreen_RefreshRateInHz = 0;//全屏時螢幕重新整理率
	d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;//背景緩沖區與前台緩沖區最大交換頻率
           

六.建立IDirect3DDevice9 對象

最後一步,通過以下方法就可以建立一個IDirect3DDevice9對象啦。 HRESULT IDirect3D9::CreateDevice(

UINT Adapter,

D3DDEVTYPE DeviceType,

HWND hFocusWindow,

DWORD BehaviorFlags,

D3DPRESENT_PARAMETERS *pPresentationParameters,

IDirect3DDevice9** ppReturnedDeviceInterface

);

Adapter——指定對象要表示的實體顯示裝置

DeviceType——裝置類型,前面說過

hFocusWindow——同我們在前面d3dpp.hDeviceWindow 的相同

BehaviorFlags — — 設定為D3DCREATE_SOFTWARE_VERTEXPROCESSING 或者

D3DCREATE_HARDWARE_VERTEXPROCESSING

pPresentationParameters——指定一個已經初始化好的D3DPRESENT_PARAMETERS執行個體 ppReturnedDeviceInterface——傳回建立的裝置

例子:

//第四步:建立D3D裝置接口
	if (FAILED(pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, vp, &d3dpp, &g_pd3dDevice)))
		return E_FAIL;
           

七.綜合Demo

用初始化函數将D3D初始化的四個步驟包含起來

HRESULT Init(HWND hWnd)//d3d初始化
{
	//第一步:建立D3D接口對象
	LPDIRECT3D9 pD3D = NULL;//建立接口對象 
	if (NULL == (pD3D = Direct3DCreate9(D3D_SDK_VERSION)))//初始化D3D接口對象,進行DX版本協商
		return E_FAIL;

	//第二步:擷取硬體裝置資訊
	D3DCAPS9 caps;
	int vp = 0;
	if (FAILED(pD3D->GetDeviceCaps(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, &caps)))
	{
		return E_FAIL;
	}
	if (caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT)//D3DDVCAPS_HWTRANSFORMANDLIGHT表示顯示卡可以支援變換和光照
		vp = D3DCREATE_HARDWARE_VERTEXPROCESSING;//如果硬體支援頂點運算,采用硬體頂點運算
	else
		vp = D3DCREATE_SOFTWARE_VERTEXPROCESSING;//不支援硬體頂點運算,采用軟體頂點運算

	//第三步:填寫D3DPRESENT_PARAMETERS結構體
	D3DPRESENT_PARAMETERS d3dpp;
	ZeroMemory(&d3dpp, sizeof(d3dpp));//清除内容

	d3dpp.BackBufferWidth = WINDOW_WIDE;
	d3dpp.BackBufferHeight = WINDOW_HEIGHT; //背景緩沖區的長寬
	d3dpp.BackBufferFormat = D3DFMT_A8R8G8B8; //背景緩沖區像素格式
	d3dpp.BackBufferCount = 1; // 背景緩沖區(寬度?)
	d3dpp.MultiSampleType = D3DMULTISAMPLE_NONE;//多重采樣類型
	d3dpp.MultiSampleQuality = 0;//多重采樣類型
	d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;//如何将背景緩沖區的内容複制到前台
	d3dpp.hDeviceWindow = hWnd;//視窗的句柄(如果設為NULL,就會在目前激活的視窗上繪制)
	d3dpp.Windowed = true;//繪制窗體的顯示模式,true表示視窗模式,false表示全屏模式
	d3dpp.EnableAutoDepthStencil = true;//是否為應用程式自動管理深度緩存
	d3dpp.AutoDepthStencilFormat = D3DFMT_D24S8; //設定深度緩沖的像素格式
	d3dpp.Flags = 0;//附加屬性,通常為0
	d3dpp.FullScreen_RefreshRateInHz = 0;//全屏時螢幕重新整理率
	d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;//背景緩沖區與前台緩沖區最大交換頻率

	//第四步:建立D3D裝置接口
	if (FAILED(pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, vp, &d3dpp, &g_pd3dDevice)))
		return E_FAIL;

	//釋放掉LPDIRECT3D9接口對象
	SAFE_RELEASE(pD3D);
}
           

繼續閱讀