首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> 關於.NET

從零打造可執行 HLSL Shader 的 DirectX 9 範例程式

     編輯:關於.NET

為學習 Shader 編程,決定脫離 DXUT 框架、直接修改 DirectX SDK 範例 D3DX9 Create Device 建立極簡 HLSL 執行環境。完整步驟如下:

1. 載入 .X 模型

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;
}

2. 裝置建立後初始化

  • 載入 BasicHLSL.fx 效果檔 (D3DXCreateEffectFromFile)。
  • 載入貼圖 Tiny_skin.dds (D3DXCreateTextureFromFileEx)。
  • 設定 Shader 參數:材質顏色、View/Projection/World 矩陣、三組平行光源方向與顏色。
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;
}

3. 渲染迴圈

  • 清除 Render Target 與 Z-Buffer。
  • 計算 World-View-Projection 矩陣。
  • 更新 Shader 參數:光源方向/顏色、WVP/World 矩陣、時間參數。
  • 設定 Technique 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);
}

4. 資源釋放與主迴圈整合

  • Cleanup() 依序釋放 Mesh、Device、D3D 介面。
  • 修改 wWinMain:InitD3D → LoadMesh("tiny.x") → OnCreateDevice() → 顯示視窗 → 訊息迴圈呼叫 Render()。

5. 全域變數與標頭檔


#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];

6. 部署檔案

將 Tiny.x、Tiny_skin.dds、BasicHLSL.fx 放置專案目錄,並將 .fx 加入專案。編譯執行即可看到套用 HLSL 著色的 Tiny 模型旋轉動畫。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved