為學習 Shader 編程,決定脫離 DXUT 框架、直接修改 DirectX SDK 範例 D3DX9 Create Device 建立極簡 HLSL 執行環境。完整步驟如下:
HRESULT LoadMesh(IDirect3DDevice9* pd3dDevice, WCHAR* strFileName, ID3DXMesh** ppMesh) {
ID3DXMesh* pMesh = NULL;
D3DXLoadMeshFromX(strFileName, D3DXMESH_MANAGED, pd3dDevice, NULL, NULL, NULL, NULL, &pMesh);
if (!(pMesh->GetFVF() & D3DFVF_NORMAL)) {
ID3DXMesh* pTempMesh;
pMesh->CloneMeshFVF(pMesh->GetOptions(), pMesh->GetFVF() | D3DFVF_NORMAL, pd3dDevice, &pTempMesh);
D3DXComputeNormals(pTempMesh, NULL);
pMesh = pTempMesh;
}
*ppMesh = pMesh;
return S_OK;
}
BasicHLSL.fx 效果檔 (D3DXCreateEffectFromFile)。Tiny_skin.dds (D3DXCreateTextureFromFileEx)。HRESULT OnCreateDevice() {
D3DXCreateEffectFromFile(g_pd3dDevice, L"BasicHLSL.fx", NULL, NULL, D3DXSHADER_NO_PRESHADER, NULL, &g_pEffect, NULL);
D3DXCreateTextureFromFileEx(g_pd3dDevice, L"Tiny_skin.dds", D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, 0,
D3DFMT_UNKNOWN, D3DPOOL_MANAGED, D3DX_DEFAULT, D3DX_DEFAULT, 0, NULL, NULL, &g_pMeshTexture);
// 設定材質、矩陣、光源參數...
return S_OK;
}
RenderSceneWithTexture3Light。Begin/End 与 BeginPass/EndPass 繪製 g_pMesh->DrawSubset(0)。VOID Render() {
g_pd3dDevice->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DXCOLOR(0.0f,0.25f,0.25f,0.55f), 1.0f, 0);
if (SUCCEEDED(g_pd3dDevice->BeginScene())) {
D3DXMATRIXA16 mWorldViewProjection = g_world * g_view * g_proj;
g_pEffect->SetMatrix("g_mWorldViewProjection", &mWorldViewProjection);
g_pEffect->SetMatrix("g_mWorld", &g_world);
g_pEffect->SetValue("g_LightDir", g_vLightDir, sizeof(D3DXVECTOR3)*MAX_LIGHTS);
g_pEffect->SetValue("g_LightDiffuse", g_vLightDiffuse, sizeof(D3DXCOLOR)*MAX_LIGHTS);
g_pEffect->SetTechnique("RenderSceneWithTexture3Light");
UINT cPasses; g_pEffect->Begin(&cPasses, 0);
for (UINT iPass = 0; iPass < cPasses; iPass++) {
g_pEffect->BeginPass(iPass);
g_pMesh->DrawSubset(0);
g_pEffect->EndPass();
}
g_pEffect->End();
g_pd3dDevice->EndScene();
}
g_pd3dDevice->Present(NULL, NULL, NULL, NULL);
}
Cleanup() 依序釋放 Mesh、Device、D3D 介面。wWinMain:InitD3D → LoadMesh("tiny.x") → OnCreateDevice() → 顯示視窗 → 訊息迴圈呼叫 Render()。
#include <Windows.h> #include <mmsystem.h> #include <d3dx9.h>
LPDIRECT3D9 g_pD3D = NULL;
LPDIRECT3DDEVICE9 g_pd3dDevice = NULL;
D3DXMATRIXA16 g_world, g_view, g_proj;
ID3DXEffect* g_pEffect = NULL;
ID3DXMesh* g_pMesh = NULL;
IDirect3DTexture9* g_pMeshTexture = NULL;
#define MAX_LIGHTS 3
D3DXVECTOR3 g_vLightDir[MAX_LIGHTS];
D3DXCOLOR g_vLightDiffuse[MAX_LIGHTS];
將 Tiny.x、Tiny_skin.dds、BasicHLSL.fx 放置專案目錄,並將 .fx 加入專案。編譯執行即可看到套用 HLSL 著色的 Tiny 模型旋轉動畫。