按照之前兩篇文章将書寫DirectX的遊戲架構代碼
DirectX 遊戲程式設計之開篇
DirectX 遊戲程式設計之3D空間,頂點緩存及索引緩存
開發環境:vs2012, DirectX SDK (June 2010),C++
對外接口:
bool DirectCDemo(HINSTANCE hInstance, RenderFunc renderfunc);
其中RenderFunc為繪制函數,定義為
typedef void (*RenderFunc)();
繪制一個按頂點着色的四面體,代碼可以如下
int WINAPI WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
DirectCDemo(hInstance, RenderVertex);
return 0;
}
通過檢視繪制函數中的頂點資料,索引資料的定義以及繪制流程可以一窺我們的封裝代碼,繪制過程簡單如下:
0 建立視窗,初始化Direct3D。
以下,提供完整的初始化Direct3D過程
bool GameWnd::InitDirect3D(HWND hwnd, bool fullscreen)
{
// Step 1: Create D3DDirect3D
D3DDirect3D = Direct3DCreate9(D3D_SDK_VERSION);
D3DPRESENT_PARAMETERS d3dpp;
// Step 2: Set D3DPRESENT_PARAMETERS
ZeroMemory(&d3dpp, sizeof(d3dpp));
if(isMulBackBuffer)
d3dpp.BackBufferCount = 2;
else d3dpp.BackBufferCount = 1;
// Enable depth and stencil
if(isZBuffer)
d3dpp.EnableAutoDepthStencil = TRUE;
else
d3dpp.EnableAutoDepthStencil = FALSE;
d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
if (fullscreen)
{
d3dpp.BackBufferWidth = window_width;
d3dpp.BackBufferHeight = window_height;
if(COLOR_FORMAT_DEFAULT==32)
d3dpp.BackBufferFormat = D3DFMT_X8R8G8B8;
else
d3dpp.BackBufferFormat = D3DFMT_R5G6B5;
d3dpp.SwapEffect = D3DSWAPEFFECT_FLIP;
d3dpp.Windowed = FALSE;
d3dpp.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT;
}
else
{
d3dpp.Windowed = TRUE;
// Always default display mode in 32 bits.
d3dpp.BackBufferFormat = D3DFMT_X8R8G8B8;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
}
D3DDEVTYPE devtype = D3DDEVTYPE_HAL;
// Set depth and stencil format
if(isStencilBuffer && isZBuffer)
{
d3dpp.AutoDepthStencilFormat = D3DFMT_D24S8;
if (FAILED(D3DDirect3D->CheckDeviceFormat(D3DADAPTER_DEFAULT,devtype,
d3dpp.BackBufferFormat, D3DUSAGE_DEPTHSTENCIL,
D3DRTYPE_SURFACE, d3dpp.AutoDepthStencilFormat)))
{
d3dpp.AutoDepthStencilFormat = D3DFMT_D24X4S4;
if (FAILED(D3DDirect3D->CheckDeviceFormat(D3DADAPTER_DEFAULT,devtype,
d3dpp.BackBufferFormat, D3DUSAGE_DEPTHSTENCIL,
D3DRTYPE_SURFACE, d3dpp.AutoDepthStencilFormat)))
{
// Device does not support stencilbuffer
}
}
}
// Do not use stencil buffer
else if (!isStencilBuffer && isZBuffer)
{
d3dpp.AutoDepthStencilFormat = D3DFMT_D32;
if (FAILED(D3DDirect3D->CheckDeviceFormat(D3DADAPTER_DEFAULT,devtype,
d3dpp.BackBufferFormat, D3DUSAGE_DEPTHSTENCIL,
D3DRTYPE_SURFACE, d3dpp.AutoDepthStencilFormat)))
{
d3dpp.AutoDepthStencilFormat = D3DFMT_D24X8;
if (FAILED(D3DDirect3D->CheckDeviceFormat(D3DADAPTER_DEFAULT,devtype,
d3dpp.BackBufferFormat, D3DUSAGE_DEPTHSTENCIL,
D3DRTYPE_SURFACE, d3dpp.AutoDepthStencilFormat)))
{
// Device does not support required depth buffer
return false;
}
}
}
// Step 3: Create D3DDirect3D device
HRESULT hr = D3DDirect3D->CreateDevice(D3DADAPTER_DEFAULT, devtype, hwnd,
D3DCREATE_HARDWARE_VERTEXPROCESSING, &d3dpp, &D3DDevice);
if (FAILED(hr))
hr = D3DDirect3D->CreateDevice(D3DADAPTER_DEFAULT, devtype, hwnd,
D3DCREATE_MIXED_VERTEXPROCESSING, &d3dpp, &D3DDevice);
if (FAILED(hr))
hr = D3DDirect3D->CreateDevice(D3DADAPTER_DEFAULT, devtype, hwnd,
D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &D3DDevice);
if (!D3DDevice)
{
// Was not able to create DIRECT3D9 device.
return false;
}
D3DDevice->GetDeviceCaps(&D3DCaps);
return true;
}
幾點需要注意:
如果開啟了自動深度緩存,模闆緩存管理,必須設定深度緩存,模闆緩存的格式,否則建立Device失敗
d3dpp.EnableAutoDepthStencil
d3dpp.AutoDepthStencilFormat = D3DFMT_D24S8; // 同時設定深度緩存與模闆緩存位數
d3dpp.AutoDepthStencilFormat = D3DFMT_D24X8; // 隻開啟深度緩存
1 定義頂點資料,我們已經知道可以使用靈活頂點格式(Flexible Vertex Format,FVF)來自定義頂點格式,我們的标準頂點格式被定義為
D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_DIFFUSE | D3DFVF_TEX1
結構體為
struct Vertex
{
Vertex() {}
Vertex(float x, float y, float z,
float nx, float ny, float nz,
Color c,
float u, float v) : position(x,y,z),normal(nx,ny,nz),color(c), texCoords(u,v)
{
}
Position3D position;
Position3D normal;
Color color;
Position2D texCoords;
};
2 按照頂點資料定義索引,其實這就是一個short的索引數組,索引資料的類型以可以在繪制時指定
3 設定錄影機的投影(PROJECT),視圖(VIEW)矩陣
4 渲染材質,這部分将對DirectX的許多參數進行設定,例如開關光照、繪制網格、深度測試、模闆測試等
5 繪制頂點,将設定頂點格式,提供一個更加簡單的頂點繪制函數DrawIndexedPrimitiveUP
HRESULT DrawIndexedPrimitiveUP(
[in] D3DPRIMITIVETYPE PrimitiveType, // 基本圖元類型,基本為三角形清單D3DPT_TRIANGLELIST
[in] UINT MinVertexIndex, // 最小頂點索引,由于使用的是基于0的頂點索引,一般為0
[in] UINT NumVertices, // 頂點數目,并非為索引數目,Demo中為4(四面體)
[in] UINT PrimitiveCount, //圖元數目,三角形個數
[in] const void *pIndexData, // 索引資料
[in] D3DFORMAT IndexDataFormat, // 索引資料類型short則為16
[in] const void *pVertexStreamZeroData, // 頂點資料
[in] UINT VertexStreamZeroStride // 頂點結構大小sizeof(Vertex)
);
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsISO2IDM1QjM3ETOwkDM1EDMy8CX0Vmbu4GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.jpg)
代碼位址git:[email protected]:hrlnldy/directxdemo.git