From e3137cd3024dda1f09f4a4a09c82849812b5f5e9 Mon Sep 17 00:00:00 2001 From: Calefaction Date: Mon, 8 Nov 2004 22:02:01 +0000 Subject: [PATCH] Various updates, including the new MeshManager This was SVN commit r1295. --- source/graphics/MeshManager.cpp | 65 +++++++++++++++++++++++++++++++ source/graphics/MeshManager.h | 23 +++++++++++ source/graphics/Model.cpp | 6 +-- source/graphics/ModelDef.cpp | 12 ------ source/graphics/ModelDef.h | 14 +++---- source/graphics/ObjectEntry.cpp | 6 ++- source/graphics/ObjectManager.cpp | 2 - 7 files changed, 103 insertions(+), 25 deletions(-) create mode 100755 source/graphics/MeshManager.cpp create mode 100755 source/graphics/MeshManager.h diff --git a/source/graphics/MeshManager.cpp b/source/graphics/MeshManager.cpp new file mode 100755 index 0000000000..9522036969 --- /dev/null +++ b/source/graphics/MeshManager.cpp @@ -0,0 +1,65 @@ +#include "precompiled.h" +#include "graphics/MeshManager.h" +#include "CLogger.h" + +CMeshManager::CMeshManager() +{ +} + +CMeshManager::~CMeshManager() +{ +} + +CModelDef *CMeshManager::GetMesh(const char *filename) +{ + mesh_map::iterator iter; + CStr fn(filename); + if((iter = m_MeshMap.find(fn.GetHashCode())) == m_MeshMap.end()) + { + try + { + CModelDef *model = CModelDef::Load(filename); + if(!model) + return NULL; + + LOG(MESSAGE, "mesh", "Loading mesh '%s'...\n", filename); + model->m_Hash = fn.GetHashCode(); + model->m_RefCount = 1; + m_MeshMap[model->m_Hash] = model; + return model; + } + catch(...) + { + LOG(ERROR, "mesh", "Could not load mesh '%s'\n!", filename); + return NULL; + } + } + else + { + LOG(MESSAGE, "mesh", "Loading mesh '%s%' (cached)...\n", filename); + CModelDef *model = (CModelDef *)(*iter).second; + model->m_RefCount++; + return model; + } +} + +int CMeshManager::ReleaseMesh(CModelDef *mesh) +{ + if(!mesh) + return 0; + + mesh_map::iterator iter = m_MeshMap.find(mesh->m_Hash); + if(iter == m_MeshMap.end()) + return 0; + + mesh->m_RefCount--; + if(mesh->m_RefCount <= 0) + { + m_MeshMap.erase(iter); + delete mesh; + mesh = NULL; + return 0; + } + + return mesh->m_RefCount; +} diff --git a/source/graphics/MeshManager.h b/source/graphics/MeshManager.h new file mode 100755 index 0000000000..397322196f --- /dev/null +++ b/source/graphics/MeshManager.h @@ -0,0 +1,23 @@ +#ifndef __H_MESHMANAGER_H__ +#define __H_MESHMANAGER_H__ + +#include "singleton.h" +#include "graphics/ModelDef.h" + +#define g_MeshManager CMeshManager::GetSingleton() + +typedef STL_HASH_MAP mesh_map; + +class CMeshManager : public Singleton +{ +public: + CMeshManager(); + ~CMeshManager(); + + CModelDef *GetMesh(const char *filename); + int ReleaseMesh(CModelDef *mesh); +private: + mesh_map m_MeshMap; +}; + +#endif \ No newline at end of file diff --git a/source/graphics/Model.cpp b/source/graphics/Model.cpp index 493cfa42af..d164f6720e 100755 --- a/source/graphics/Model.cpp +++ b/source/graphics/Model.cpp @@ -14,7 +14,7 @@ #include "SkeletonAnim.h" #include "SkeletonAnimDef.h" #include "SkeletonAnimManager.h" -#include "ProgramManager.h" +#include "MeshManager.h" ///////////////////////////////////////////////////////////////////////////////////////////////////////////// // Constructor @@ -42,6 +42,8 @@ void CModel::ReleaseData() delete m_Props[i].m_Model; } m_Props.clear(); + if(m_pModelDef) + g_MeshManager.ReleaseMesh(m_pModelDef); } ///////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -356,6 +358,4 @@ void CModel::SetMaterial(const CMaterial &material) if(m_Material.GetTexture().Trim(PS_TRIM_BOTH).Length() > 0) { } - if(m_Material.GetVertexProgram().Trim(PS_TRIM_BOTH).Length() > 0) - m_VertexProgram = g_ProgramManager.FindVertexProgram(m_Material.GetVertexProgram().Trim(PS_TRIM_BOTH).c_str()); } diff --git a/source/graphics/ModelDef.cpp b/source/graphics/ModelDef.cpp index fbbcd5f73e..c0176405a9 100755 --- a/source/graphics/ModelDef.cpp +++ b/source/graphics/ModelDef.cpp @@ -30,17 +30,6 @@ CModelDef::~CModelDef() delete[] m_PropPoints; } -/////////////////////////////////////////////////////////////////////////////// -// Call at shutdown to free memory -void CModelDef::Shutdown() -{ - for (std::vector::iterator iter = m_LoadedModelDefs.begin(); iter != m_LoadedModelDefs.end(); ++iter) - delete *iter; -} -// The list of allocated models which are to be freed -std::vector CModelDef::m_LoadedModelDefs; - - /////////////////////////////////////////////////////////////////////////////// // FindPropPoint: find and return pointer to prop point matching given name; // return null if no match (case insensitive search) @@ -107,7 +96,6 @@ CModelDef* CModelDef::Load(const char* filename) delete mdef; throw CFileUnpacker::CFileEOFError(); } - m_LoadedModelDefs.push_back(mdef); return mdef; } diff --git a/source/graphics/ModelDef.h b/source/graphics/ModelDef.h index e3d2fab628..2bbecb0abf 100755 --- a/source/graphics/ModelDef.h +++ b/source/graphics/ModelDef.h @@ -14,6 +14,8 @@ #include "SkeletonAnimDef.h" #include +class CMeshManager; + /////////////////////////////////////////////////////////////////////////////// // SPropPoint: structure describing a prop point struct SPropPoint @@ -71,6 +73,7 @@ struct SModelFace // information of a model class CModelDef { +friend class CMeshManager; public: // current file version given to saved animations enum { FILE_VERSION = 2 }; @@ -84,11 +87,7 @@ public: // destructor virtual ~CModelDef(); - // shutdown memory-freer - static void Shutdown(); - // model I/O functions - static CModelDef* Load(const char* filename); static void Save(const char* filename,const CModelDef* mdef); public: @@ -126,9 +125,10 @@ public: // prop point data u32 m_NumPropPoints; SPropPoint* m_PropPoints; - - // all loaded models, to be freed on shutdown - static std::vector m_LoadedModelDefs; +protected: + static CModelDef* Load(const char* filename); + int m_RefCount; + size_t m_Hash; }; #endif diff --git a/source/graphics/ObjectEntry.cpp b/source/graphics/ObjectEntry.cpp index 3137bc1a70..7baa04b608 100755 --- a/source/graphics/ObjectEntry.cpp +++ b/source/graphics/ObjectEntry.cpp @@ -6,6 +6,7 @@ #include "ModelDef.h" #include "CLogger.h" #include "MaterialManager.h" +#include "MeshManager.h" #include "UnitManager.h" @@ -52,7 +53,10 @@ bool CObjectEntry::BuildModel() const char* modelfilename = m_ModelName.c_str(); try { - modeldef=CModelDef::Load(modelfilename); + //modeldef=CModelDef::Load(modelfilename); + modeldef = g_MeshManager.GetMesh(modelfilename); + if(!modeldef) + throw false; } catch (...) { LOG(ERROR, LOG_CATEGORY, "CObjectEntry::BuildModel(): Model %s failed to load", modelfilename); return false; diff --git a/source/graphics/ObjectManager.cpp b/source/graphics/ObjectManager.cpp index 307b1fd7f9..69277b4e48 100755 --- a/source/graphics/ObjectManager.cpp +++ b/source/graphics/ObjectManager.cpp @@ -20,8 +20,6 @@ CObjectManager::~CObjectManager() delete m_ObjectTypes[i].m_Objects[j]; } } - - CModelDef::Shutdown(); } CObjectEntry* CObjectManager::FindObject(const char* objectname)