diff --git a/source/graphics/ModelDef.cpp b/source/graphics/ModelDef.cpp index 67bce614c3..fe4244fe7d 100755 --- a/source/graphics/ModelDef.cpp +++ b/source/graphics/ModelDef.cpp @@ -12,11 +12,12 @@ #include "FilePacker.h" #include "FileUnpacker.h" + /////////////////////////////////////////////////////////////////////////////// // CModelDef Constructor CModelDef::CModelDef() : m_NumVertices(0), m_pVertices(0), m_NumFaces(0), m_pFaces(0), m_NumBones(0), m_Bones(0), - m_NumPropPoints(0), m_PropPoints(0), m_RenderData(0) + m_NumPropPoints(0), m_PropPoints(0) { } @@ -24,7 +25,8 @@ CModelDef::CModelDef() // CModelDef Destructor CModelDef::~CModelDef() { - delete m_RenderData; + for(RenderDataMap::iterator it = m_RenderData.begin(); it != m_RenderData.end(); ++it) + delete it->second; delete[] m_pVertices; delete[] m_pFaces; delete[] m_Bones; @@ -134,11 +136,24 @@ void CModelDef::Save(const char* filename,const CModelDef* mdef) } -// Set render data. This can only be done once at the moment. -// TODO: Is there a need to re-create render data? Perhaps reacting to render path changes? -void CModelDef::SetRenderData(CSharedRenderData* data) +/////////////////////////////////////////////////////////////////////////////// +// SetRenderData: Set the render data object for the given key, +void CModelDef::SetRenderData(const void* key, CModelDefRPrivate* data) { - debug_assert(m_RenderData == 0); - m_RenderData = data; + delete m_RenderData[key]; + m_RenderData[key] = data; } +/////////////////////////////////////////////////////////////////////////////// +// GetRenderData: Get the render data object for the given key, +// or 0 if no such object exists. +// Reference count of the render data object is automatically increased. +CModelDefRPrivate* CModelDef::GetRenderData(const void* key) const +{ + RenderDataMap::const_iterator it = m_RenderData.find(key); + + if (it != m_RenderData.end()) + return it->second; + + return 0; +} diff --git a/source/graphics/ModelDef.h b/source/graphics/ModelDef.h index 17f6d8362b..a8f462b8fe 100755 --- a/source/graphics/ModelDef.h +++ b/source/graphics/ModelDef.h @@ -11,10 +11,13 @@ #include "CStr.h" #include "Vector3D.h" +#include "MeshManager.h" #include "SkeletonAnimDef.h" +#include #include class CMeshManager; +class CModelDef; /////////////////////////////////////////////////////////////////////////////// // SPropPoint: structure describing a prop point @@ -69,13 +72,12 @@ struct SModelFace //////////////////////////////////////////////////////////////////////////////////////// -// CSharedRenderData: render data for a CModelDef, shared between all model render data -// instances that refer to the same CModelDef. -class CSharedRenderData +// CModelDefRPrivate +class CModelDefRPrivate { public: - CSharedRenderData() { } - virtual ~CSharedRenderData() { } + CModelDefRPrivate() { } + virtual ~CModelDefRPrivate() { } }; @@ -84,7 +86,7 @@ public: // information of a model class CModelDef { -friend class CMeshManager; + friend class CMeshManager; public: // current file version given to saved animations enum { FILE_VERSION = 2 }; @@ -123,9 +125,24 @@ public: // null if no match (case insensitive search) SPropPoint* FindPropPoint(const char* name) const; + /** + * SetRenderData: Register renderer private data. Use the key to + * distinguish between private data used by different render paths. + * The private data will be managed by this CModelDef object: + * It will be deleted when CModelDef is destructed or when private + * data is registered using the same key. + * + * @param key The opaque key that is used to identify the caller. + * The given private data can be retrieved by passing key to GetRenderData. + * @param data The private data. + * + * postconditions : data is bound to the lifetime of this CModelDef + * object. + */ + void SetRenderData(const void* key, CModelDefRPrivate* data); + // accessor: render data - CSharedRenderData* GetRenderData() const { return m_RenderData; } - void SetRenderData(CSharedRenderData* data); + CModelDefRPrivate* GetRenderData(const void* key) const; public: // vertex data @@ -141,8 +158,11 @@ public: u32 m_NumPropPoints; SPropPoint* m_PropPoints; - // renderdata shared by models of the same modeldef - CSharedRenderData* m_RenderData; +private: + // renderdata shared by models of the same modeldef, + // by render path + typedef std::map RenderDataMap; + RenderDataMap m_RenderData; protected: static CModelDef* Load(const char* filename); diff --git a/source/graphics/RenderableObject.h b/source/graphics/RenderableObject.h index 650ab6a9c5..86d78a1f32 100755 --- a/source/graphics/RenderableObject.h +++ b/source/graphics/RenderableObject.h @@ -84,13 +84,10 @@ public: void InvalidateBounds() { m_BoundsValid = false; } - // set the object renderdata - // TODO,RC 10/04/04 - need to delete existing renderdata here, or can we - // assume the renderer won't set renderdata when an object already has it? - // - just debug_assert we've no renderdata at the minute + // Set the object renderdata and free previous renderdata, if any. void SetRenderData(CRenderData* renderdata) { - debug_assert(m_RenderData==0); - m_RenderData=renderdata; + delete m_RenderData; + m_RenderData = renderdata; } // return object renderdata - can be null if renderer hasn't yet diff --git a/source/renderer/Renderer.cpp b/source/renderer/Renderer.cpp index 8d74c68bf9..f6872c1c1b 100755 --- a/source/renderer/Renderer.cpp +++ b/source/renderer/Renderer.cpp @@ -1081,6 +1081,7 @@ void CRenderer::FlushFrame() oglCheck(); // Prepare model renderers + PROFILE_START("prepare models"); m_Models.NormalFF->PrepareModels(); m_Models.PlayerFF->PrepareModels(); if (m_Models.NormalHWLit) @@ -1088,6 +1089,7 @@ void CRenderer::FlushFrame() if (m_Models.PlayerHWLit) m_Models.PlayerHWLit->PrepareModels(); m_Models.Transparency->PrepareModels(); + PROFILE_END("prepare models"); if (!m_ShadowRendered) { if (m_Options.m_Shadows) { @@ -1297,21 +1299,6 @@ bool CRenderer::LoadTexture(CTexture* texture,u32 wrapflags) // BindTexture: bind a GL texture object to current active unit void CRenderer::BindTexture(int unit,GLuint tex) { -#if 0 - glActiveTextureARB(GL_TEXTURE0+unit); - if (tex==m_ActiveTextures[unit]) return; - - if (tex) { - glBindTexture(GL_TEXTURE_2D,tex); - if (!m_ActiveTextures[unit]) { - glEnable(GL_TEXTURE_2D); - } - } else if (m_ActiveTextures[unit]) { - glDisable(GL_TEXTURE_2D); - } - m_ActiveTextures[unit]=tex; -#endif - glActiveTextureARB(GL_TEXTURE0+unit); glBindTexture(GL_TEXTURE_2D,tex); diff --git a/source/renderer/TransparencyRenderer.cpp b/source/renderer/TransparencyRenderer.cpp index e8f1f96857..cd6befd2e6 100755 --- a/source/renderer/TransparencyRenderer.cpp +++ b/source/renderer/TransparencyRenderer.cpp @@ -277,6 +277,7 @@ void TransparencyRenderer::PrepareModels() // upload everything to vertex buffer tmdl->m_Array.Upload(); } + tmdl->m_UpdateFlags = 0; // resort model indices from back to front, according to camera position - and store // the returned sqrd distance to the centre of the nearest triangle