補充八叉樹場景管理與資源載入優化。同一模型大量實例化 (如 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;
};
// 初始化模型
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();
簡潔直觀,資源自動復用。
透過單例資源管理器與參考計數,實現貼圖、模型、特效的高效復用。模型資料進一步封裝共享緩衝區與幾何資訊,支援大量實例化渲染。架構簡單易擴展,歡迎指教更優設計。