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

自製 3D 圖形引擎 (四):WuguiEngine 模型、特效、貼圖資源管理

     編輯:關於C++

前言

補充八叉樹場景管理與資源載入優化。同一模型大量實例化 (如 10000 隻老虎) 時,重複從檔案讀取會導致載入緩慢與記憶體浪費。WuguiEngine 採用資源復用機制解決此問題。

資源復用架構

資源類型與描述

enum ResourceType { RTTexture = 0, RTMesh = 1, RTEffect = 2 };

struct StructRes {
    StructRes(void* pRes, ResourceType type) {
        pResource = pRes; useCount = 1; resourceType = type;
    }
    ResourceType resourceType;
    void* pResource;
    int useCount;
};

資源管理器 (單例模式)

class ResourceManager {
public:
    static ResourceManager* GetInstance();
    void* GetD3DResource(string filename, GraphicsDevice* pDevice, ResourceType type);
    void DisposeD3DResource(string filename);
protected:
    ResourceManager();
    map resourceTable;
    static ResourceManager* pInstance;
};
  • resourceTable 以檔案名為鍵對應 StructRes*。
  • useCount 參考計數:取得 +1、釋放 -1,歸零時真正釋放資源。

核心取得流程

void* ResourceManager::GetD3DResource(string filename, GraphicsDevice* pDevice, ResourceType type) {
    auto it = resourceTable.find(filename);
    if (it != resourceTable.end()) { // 已載入
        it->second->useCount++;
        return it->second->pResource;
    }
    // 未載入,依類型建立
    if (type == RTTexture) {
        IDirect3DTexture9* pTexture;
        LPSTR str = UtilityTools::ConvertStringLPSTR(&filename);
        if (D3DXCreateTextureFromFileExA(pDevice->GetLPDIRECT3DDEVICE9(), str,
            D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, 0,
            D3DFMT_UNKNOWN, D3DPOOL_MANAGED,
            D3DX_DEFAULT, D3DX_DEFAULT, 0, NULL, NULL, &pTexture) != D3D_OK)
            throw "Exception To Create Texture";
        delete str;
        StructRes* pRes = new StructRes(pTexture, type);
        resourceTable.insert(make_pair(filename, pRes));
        return pTexture;
    }
    // RTMesh, RTEffect 類似處理...
}

使用範例

ResourceManager* pResMgr = ResourceManager::GetInstance();
pTexture = (IDirect3DTexture9*)pResMgr->GetD3DResource(filename, device, RTTexture);

模型資源封裝

模型較貼圖複雜,涉及 VertexBuffer、IndexBuffer、包圍球等共享資料。封裝 ModelResource 類別:

class ModelResource : IDisposed {
public:
    ModelResource(string filename, GraphicsDevice* device);
    virtual void Dispose();
    ID3DXMesh* GetD3DMesh();
    IDirect3DVertexBuffer9* GetVertexBuffer();
    IDirect3DIndexBuffer9* GetIndexBuffer();
    BoundingSphere* GetOriginalSphere();
protected:
    void Initialize();
    void CalculateBoundingSphere();
    string filename;
    GraphicsDevice* pDevice;
    ID3DXMesh* pMesh;
    IDirect3DVertexBuffer9* pVertexBuffer;
    IDirect3DIndexBuffer9* pIndexBuffer;
    BoundingSphere* pOriginalSphere;
    DWORD FVF;
};
  • 頂點/索引緩衝區、原始包圍球屬共享資料。
  • 材質 (含貼圖)、變換 另行封裝於 Model 類別。

實際使用範例

// 初始化模型
pModel = new Model("Content\\Tiger.x", pDevice);
pModel->SetDiffuseMap("Content\\Tiger.bmp");
pModel->SetPosition(D3DXVECTOR3(0,0,-20));
// 設定特效
pModel->SetEffect(new SimpleEffect(pDevice, pModel, "SimpleTexture.fx"));
pModel->GetEffect()->Initialize();

簡潔直觀,資源自動復用。

總結

透過單例資源管理器與參考計數,實現貼圖、模型、特效的高效復用。模型資料進一步封裝共享緩衝區與幾何資訊,支援大量實例化渲染。架構簡單易擴展,歡迎指教更優設計。

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