第一章
Direct3D是一套底層(low-level)圖形API(Application Programming Interface,API)
HAL是一個指示裝置完成某些操作的裝置相關的代碼集
REF裝置,它能以軟體運算方式完全支援Direct3DAPI
在程式中,HAL裝置用值D3DDEVTYPE_HAL來指定,該值是D3DDEVTYPE枚舉類型的一個成員,類似,REF裝置值用D3DDEVTYPE_REF來指定,該值也是D3DDEVTYPE的成員
表面是Direct3D主要用於儲存2D映像資料的一個像素矩陣。( 實際上像素資料存放區在一個線性數組中)
表面的寬度和高度都用像素來度量,跨度則用位元組來度量,更具體的說,跨度可能比寬度更寬,這依賴底層的硬體實現,所以不能簡單的假設pitch= width* sizeof(pixelForamt)
我們用IDirect3DSurface9來描述表面
介面IDirect3DSurface9中最重要的方法如下:
LockRect 該方法用於擷取指向表面儲存區的指標,通過指標運算,可對錶面中的每一個像素進行讀寫操作
UnlockRect 該方法以解除對錶面儲存區的鎖定
GetDesc該方法通過填充結構D3DSURFACE_DESC來擷取該表面的描述資訊
例:鎖定表面儲存區以及將每個像素設為紅色
D3DSURFACE_DESC surfaceDesc;
_surface->GetDesc(&surfaceDesc);
D3DLOCKED_RECT lockedRect;
_surface->LockRect(
&lockedRect,
0,
0);
DWORD *imageData = (DWORD*) lockedRect.pBits;//將bits強制轉換為32位的DWORD類型
for (int i =0 ;i< surfaceDesc.Height;i++)
for (int j = 0; j< surfaceDesc.Width;j++)
{
int index = i * lockedRect.Pitch/4 + j;
imagedata[index] = 0xffff0000;//red
}
_surface->UnlockRect();
結構D3DLOCKED_RECT定義如下
typedef struct _D3DLOCKED_RECT{
INT Pitch;
void* pBits;
}D3DLOCKED_RECT;
多重採樣用於平滑塊狀映像技術
D3DMULTISSAMPLE_TYPE枚舉類型包含了一系列枚舉常量值
*D3DMULTISSAMPLE_NONE禁止多重採樣
*D3DMULTISSAMPLE_1_SAMPLE....D3DMULTISSAMPLE_16_SAMPLE指定從1~16級的多重採樣
還有一個與特定多重採樣類型相關的品質水平(quality level),該水平值用DWORD類型描述
如果使用多重採樣,請用IDirect3D9::CheckDeviceMultiSampleType方法來檢查你的圖形裝置是否支援你所希望採用的多重採用類型,並驗證得到的圖形品質水平是否理想
像素格式可用D3DFORMAT枚舉類型的枚舉常量來定義
表面和其他的Direct3D資源可以放入許多類型的記憶體池中,記憶體池的類型可用D3DPOOL枚舉類型來表示
*D3DPOOL_DEFAULT預設值,指示Direct3D將資源放入最合適該資源類型及其使用方式的儲存區中,該儲存區可能是顯存,AGP,系統儲存區
注意,調用IDirect3DDevice9::Reset前,必須對預設記憶體池中的資源銷毀或釋放,還必須對記憶體池中的資源重現初始化
*D3DPOOL_MANAGE 放入該託管記憶體池中的資源將交由Direct3D管理(這些資源將根據需要被裝置自動轉移到顯存或AGP儲存區中),此外,這些資源將在系統儲存區中保留一個備份,這樣必要時Direct3D會將這些資源自動更新到顯存中
*D3DPOOL_SYSTEMMEM將資源放入系統儲存區中
*D3DPOOL_SCRATCH將資源放入系統儲存區中,不同前述類型
*D3DPOOL_SYSTEMMEM這些資源不受圖形裝置的制約,裝置無法訪問該類型記憶體中的資源,但這些資源之間可以複製
Direct3D維護著一個表面集合,該集合通常由兩到三個表面組成,稱為交換鏈結,該集合用IDirect3DSwapChain9來表示
交換鏈結和頁面置換技術主要用於產生更加平滑的動畫。
深度緩衝是一個只含有特定像素的深度資訊而不含映像資料的表面。
深度緩衝為最終繪製的映像中的每一個像素都保留一個深度項。所以繪製的映像的解析度為640*480時,深度緩衝中將有640*480個深度項
深度緩衝格式:
*D3DFMT_D32 //32位元深度緩衝
*D3DFMT_D24S8//24位元深度緩衝,其中8位保留供模板緩衝使用
*D3DFMT_D24X8//僅指定24位元深度緩衝
*D3DFMT_X4S4//24位元深度緩衝,其中4位保留供模板緩衝使用
*D3DFMT_D16//16位元深度緩衝
兩種不同方式的頂點運算,軟體頂點運算,硬體頂點運算
Direct3D所提供的每一項效能都對應於結構D3DCAP9中的一個資料成員或某一位
我們以某一具體硬體為基礎,可以初始化一個D3DCAPS9類型的執行個體,然後在應用程式中通過檢查該D3DCAPS9執行個體中相應的資料成員或位來判斷該裝置是否支援某項特性
例:檢查某一硬體裝置是否可作硬體頂點運算(即檢驗該裝置是否支援變換和光照的硬體計算)
通過查閱D3DCAPS9的相關SDK文檔,探索資料成員D3DCAPS9::DevCaps的D3DDEVCAPS_HWTRANSFORMANDLIGHT位可用來表示該裝置是否支援變換和光照的硬體計算。
bool supportsHardwareVertexProcessing = false;
if( caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT )
supportsHardwareVertexProcessing = true;
Direct3D初始化:
(1) 擷取介面IDirect3D9指標,該介面用於擷取系統中物理硬體裝置的資訊並建立介面IDirect3DDevice9,該介面是一個c++對象,代表我們用來顯示3D圖形的物理硬體裝置
(2)檢查裝置效能(D3DCAPS9),判斷主顯卡是否支援硬體頂點運算
(3)初始化D3DPRESENT_PARAMETERS結構的一個執行個體,我們可以通過該結構來指定即將建立的介面IDirect3DDevice9的特性
(4)利用D3DPRESENT_PARAMETERS結構建立IDirect3DDevice9對象
擷取介面IDirect3D9的指標
IDirect3D9* _d3d9;
_d3d9 = Direct3DCreate9(D3D_SDK_VERSION);//函數Direct3DCreate9的參數必須是D3D_SDK_VERSION,只有如此方能保證應用程式使用正確的標頭檔。
IDirect3D9 對象主要有兩個用途:裝置枚舉以及建立IDirect3DDevice9類型的對象
裝置枚舉指擷取系統中可用的每塊圖形卡的效能,顯示模式,格式及其他資訊
校正硬體頂點運算:
要進行檢查,必須先根據主顯卡的績效參數初始化一個IDirect3DDevice9類型的對象,
HRESULT IDirect3D9::GetDeviceCaps(
UINT Adapter,//物理顯卡序號
D3DDEVTYPE DeviceType,//裝置類型(D3DDEVTYPE_HAL/D3DDEVTYPE_REF)
D3DCAPS9 *pCaps//初始化的裝置效能結構執行個體
);
例:
D3DCAPS9 caps;
d3d9->GetDeviceCaps(D3DADAPTER_DEFAULT,deviceType,&caps);
int vp = 0;
if (caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT )
vp = D3DCREATE_HARDWARE_VERTEXPROCESSING;
else
vp = D3DCREATE_SOFTWARE_VERTEXPROCESSING;
D3DPRESENT_PARAMETER結構:
typedef struct _D3DPRESENT_PARAMETERS_{
UINT BackBufferWidth;//後台緩衝中表面的寬度,單位為像素
UINT BackBufferHeight;//後台緩衝中表面的寬度,單位為像素
D3DFORMAT BackBufferFormat;//後台緩衝的像素格式(如32位像素格式:D3DFMT_A8R8G8B8).
UINT BackBufferCount;//所需後台緩衝的個數,通常指定為1
D3DMULTISAMPLE_TYPE MultiSampleType;//後台緩衝使用的多重採樣類型
DWORD MultiSampleQuality;//多重採樣品質水平
D3DSWAPEFFECT SwapEffect;//D3DSWAPEFFECT枚舉類型的一個成員,指定交換鏈結中的快取頁面面置換方式指定D3DSWAPEFFECT_DISCARD時效率最高
HWND hDeviceWindow;//裝置相關的視窗控制代碼
BOOL Windowed;//true視窗模式,false全螢幕模式
BOOL EnableAutoDepthStencil;//true表示Direct3D自動建立並維護深度緩衝或模式緩衝
D3DFORMAT AutoDepthStencilFormat;//深度緩衝或模板緩衝的像素格式
DWORD Flags;//一些附加特性 0無標記,D3DPRESENTFLAG_LOCKABLE_DEPTHBUFFER 可鎖定後台緩衝
UINT FullScreen_RefreshRateInHz;//重新整理頻率 預設:D3DPRESENT_RATE_DEFAULT
UINT PresentationInterval;//D3DPRESENT集合的一個成員,D3DPRESENT_INTERVAL_IMMEDIATE立即提交,D3DPRESENT_INTERVAL_DEFAULT 有Direct3D來選擇提交頻率,通常該值等於重新整理頻率
}D3DPRESENT_PARAMETERS;
建立IDirect3DDevice9類型的對象:
HRESULT IDirect3D9::CreateDevice(
UINT Adapter, //哪塊物理顯卡
D3DDEVTYPE DeviceType,//裝置類型 ,D3DDEVTYPE_HAL
HWND hFocusWindow,//與裝置相關的視窗控制代碼
DWORD BehaviorFlags,//D3DCREATE_HARDWARE_VERTEXPROCESSING或D3DCREATE_SOFTWARE_VERTEXPROCESSING
D3DPRESENT_PARAMETERS *pPresentationParameters,//已經完成的初始化D3DPRESENT_PARAMETERS類型的執行個體
IDirect3DDevice8** ppReturnedDeviceInterface//返回所建立的裝置
);
例:
IDirect3DDevice9* device = 0;
hr = d3d9->CreateDevice(
D3DADAPTER_DEFAULT,
D3DDEVTYPE_HAL,
hwnd,
D3DCREATE_HARDWARE_VERTEXPROCESSING,
&d3dpp,
&device);
if (FAILED(hr))
{
return 0;
}