فهرست منبع

Started work on MeshHeap and transient meshes
Meshes share a common base

Marko Pintera 12 سال پیش
والد
کامیت
d7cf519627

+ 7 - 0
CamelotCore/CamelotCore.vcxproj

@@ -290,6 +290,9 @@
     <ClInclude Include="Include\CmGpuResourceRTTI.h" />
     <ClInclude Include="Include\CmGpuResourceRTTI.h" />
     <ClInclude Include="Include\CmGpuParam.h" />
     <ClInclude Include="Include\CmGpuParam.h" />
     <ClInclude Include="Include\CmInputFwd.h" />
     <ClInclude Include="Include\CmInputFwd.h" />
+    <ClInclude Include="Include\CmMeshBase.h" />
+    <ClInclude Include="Include\CmMeshBaseRTTI.h" />
+    <ClInclude Include="Include\CmMeshHeap.h" />
     <ClInclude Include="Include\CmOSInputHandler.h" />
     <ClInclude Include="Include\CmOSInputHandler.h" />
     <ClInclude Include="Include\CmPixelData.h" />
     <ClInclude Include="Include\CmPixelData.h" />
     <ClInclude Include="Include\CmPixelDataRTTI.h" />
     <ClInclude Include="Include\CmPixelDataRTTI.h" />
@@ -347,6 +350,7 @@
     <ClInclude Include="Include\CmTextureView.h" />
     <ClInclude Include="Include\CmTextureView.h" />
     <ClInclude Include="Include\CmTextData.h" />
     <ClInclude Include="Include\CmTextData.h" />
     <ClInclude Include="Include\CmTimerQuery.h" />
     <ClInclude Include="Include\CmTimerQuery.h" />
+    <ClInclude Include="Include\CmTransientMesh.h" />
     <ClInclude Include="Include\CmVertexBuffer.h" />
     <ClInclude Include="Include\CmVertexBuffer.h" />
     <ClInclude Include="Include\CmHighLevelGpuProgram.h" />
     <ClInclude Include="Include\CmHighLevelGpuProgram.h" />
     <ClInclude Include="Include\CmHighLevelGpuProgramManager.h" />
     <ClInclude Include="Include\CmHighLevelGpuProgramManager.h" />
@@ -452,6 +456,8 @@
     <ClCompile Include="Source\CmImportOptions.cpp" />
     <ClCompile Include="Source\CmImportOptions.cpp" />
     <ClCompile Include="Source\CmIndexBuffer.cpp" />
     <ClCompile Include="Source\CmIndexBuffer.cpp" />
     <ClCompile Include="Source\CmIndexData.cpp" />
     <ClCompile Include="Source\CmIndexData.cpp" />
+    <ClCompile Include="Source\CmMeshBase.cpp" />
+    <ClCompile Include="Source\CmMeshHeap.cpp" />
     <ClCompile Include="Source\CmMeshManager.cpp" />
     <ClCompile Include="Source\CmMeshManager.cpp" />
     <ClCompile Include="Source\CmOcclusionQuery.cpp" />
     <ClCompile Include="Source\CmOcclusionQuery.cpp" />
     <ClCompile Include="Source\CmOSInputHandler.cpp" />
     <ClCompile Include="Source\CmOSInputHandler.cpp" />
@@ -468,6 +474,7 @@
     <ClCompile Include="Source\CmTextureView.cpp" />
     <ClCompile Include="Source\CmTextureView.cpp" />
     <ClCompile Include="Source\CmTextData.cpp" />
     <ClCompile Include="Source\CmTextData.cpp" />
     <ClCompile Include="Source\CmTimerQuery.cpp" />
     <ClCompile Include="Source\CmTimerQuery.cpp" />
+    <ClCompile Include="Source\CmTransientMesh.cpp" />
     <ClCompile Include="Source\CmVertexBuffer.cpp" />
     <ClCompile Include="Source\CmVertexBuffer.cpp" />
     <ClCompile Include="Source\CmHighLevelGpuProgram.cpp" />
     <ClCompile Include="Source\CmHighLevelGpuProgram.cpp" />
     <ClCompile Include="Source\CmHighLevelGpuProgramManager.cpp" />
     <ClCompile Include="Source\CmHighLevelGpuProgramManager.cpp" />

+ 21 - 0
CamelotCore/CamelotCore.vcxproj.filters

@@ -510,6 +510,18 @@
     <ClInclude Include="Include\CmTimerQuery.h">
     <ClInclude Include="Include\CmTimerQuery.h">
       <Filter>Source Files\RenderSystem</Filter>
       <Filter>Source Files\RenderSystem</Filter>
     </ClInclude>
     </ClInclude>
+    <ClInclude Include="Include\CmMeshHeap.h">
+      <Filter>Header Files\Resources</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\CmTransientMesh.h">
+      <Filter>Header Files\Resources</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\CmMeshBase.h">
+      <Filter>Header Files\Resources</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\CmMeshBaseRTTI.h">
+      <Filter>Header Files\RTTI</Filter>
+    </ClInclude>
   </ItemGroup>
   </ItemGroup>
   <ItemGroup>
   <ItemGroup>
     <ClCompile Include="Source\CmApplication.cpp">
     <ClCompile Include="Source\CmApplication.cpp">
@@ -797,5 +809,14 @@
     <ClCompile Include="Source\CmTimerQuery.cpp">
     <ClCompile Include="Source\CmTimerQuery.cpp">
       <Filter>Source Files\RenderSystem</Filter>
       <Filter>Source Files\RenderSystem</Filter>
     </ClCompile>
     </ClCompile>
+    <ClCompile Include="Source\CmMeshHeap.cpp">
+      <Filter>Source Files\Resources</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\CmTransientMesh.cpp">
+      <Filter>Source Files\Resources</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\CmMeshBase.cpp">
+      <Filter>Source Files\Resources</Filter>
+    </ClCompile>
   </ItemGroup>
   </ItemGroup>
 </Project>
 </Project>

+ 1 - 1
CamelotCore/Include/CmCoreThreadAccessor.h

@@ -180,7 +180,7 @@ namespace CamelotFramework
 
 
 
 
 		/** @copydoc RenderSystem::render() */
 		/** @copydoc RenderSystem::render() */
-		void render(const MeshPtr& mesh, UINT32 indexOffset = 0, UINT32 indexCount = 0, bool useIndices = true, DrawOperationType drawOp = DOT_TRIANGLE_LIST)
+		void render(const MeshBasePtr& mesh, UINT32 indexOffset = 0, UINT32 indexCount = 0, bool useIndices = true, DrawOperationType drawOp = DOT_TRIANGLE_LIST)
 		{
 		{
 			mCommandQueue->queue(boost::bind(&RenderSystem::render, RenderSystem::instancePtr(), mesh, indexOffset, indexCount, useIndices, drawOp));
 			mCommandQueue->queue(boost::bind(&RenderSystem::render, RenderSystem::instancePtr(), mesh, indexOffset, indexCount, useIndices, drawOp));
 		}
 		}

+ 6 - 48
CamelotCore/Include/CmMesh.h

@@ -1,7 +1,7 @@
 #pragma once
 #pragma once
 
 
 #include "CmPrerequisites.h"
 #include "CmPrerequisites.h"
-#include "CmGpuResource.h"
+#include "CmMeshBase.h"
 #include "CmMeshData.h"
 #include "CmMeshData.h"
 #include "CmVertexData.h"
 #include "CmVertexData.h"
 #include "CmIndexData.h"
 #include "CmIndexData.h"
@@ -10,13 +10,7 @@
 
 
 namespace CamelotFramework
 namespace CamelotFramework
 {
 {
-	enum class MeshBufferType
-	{
-		Static,
-		Dynamic
-	};
-
-	class CM_EXPORT Mesh : public GpuResource
+	class CM_EXPORT Mesh : public MeshBase
 	{
 	{
 	public:
 	public:
 		virtual ~Mesh();
 		virtual ~Mesh();
@@ -51,49 +45,18 @@ namespace CamelotFramework
 		 */
 		 */
 		UINT32 mapToSubresourceIdx() const { return 0; }
 		UINT32 mapToSubresourceIdx() const { return 0; }
 
 
-		void clearSubMeshes();
-
-		void addSubMesh(UINT32 indexOffset, UINT32 indexCount, DrawOperationType drawOp = DOT_TRIANGLE_LIST);
-
-		/**
-		 * @brief	Sets a set of sub-meshes containing data used for rendering a 
-		 * 			certain portion of this mesh. Overwrites any previous sub-meshes.
-		 * 			
-		 * @note	Sim thread only.
-		 */
-		void setSubMeshes(const Vector<SubMesh>::type& subMeshes);
-
-		/**
-		 * @brief	Retrieves a sub-mesh containing data used for rendering a
-		 * 			certain portion of this mesh.
-		 * 			
-		 * @note	Sim thread only.
-		 */
-		const SubMesh& getSubMesh(UINT32 subMeshIdx = 0) const;
-
-		/**
-		 * @brief	Retrieves a total number of sub-meshes in this mesh.
-		 * 			
-		 * @note	Sim thread only.
-		 */
-		UINT32 getNumSubMeshes() const;
-
 		const AABox& getBounds() const;
 		const AABox& getBounds() const;
 		const AABox& getBounds(UINT32 submeshIdx) const;
 		const AABox& getBounds(UINT32 submeshIdx) const;
 
 
 		/**
 		/**
-		 * @brief	Get vertex data used for rendering.
-		 *  
-		 * @note	Core thread only.
+		 * @copydoc MeshBase::getVertexData
 		 */
 		 */
-		std::shared_ptr<VertexData> getVertexData() const;
+		virtual std::shared_ptr<VertexData> getVertexData() const;
 
 
 		/**
 		/**
-		 * @brief	Get index data used for rendering.
-		 *  
-		 * @note	Core thread only.
+		 * @copydoc MeshBase::getIndexData
 		 */
 		 */
-		std::shared_ptr<IndexData> getIndexData() const;
+		virtual std::shared_ptr<IndexData> getIndexData() const;
 
 
 		/**
 		/**
 		 * @brief	Returns a dummy mesh, containing just one triangle. Don't modify the returned mesh.
 		 * @brief	Returns a dummy mesh, containing just one triangle. Don't modify the returned mesh.
@@ -117,11 +80,6 @@ namespace CamelotFramework
 		std::shared_ptr<VertexData> mVertexData; // Core thread
 		std::shared_ptr<VertexData> mVertexData; // Core thread
 		std::shared_ptr<IndexData> mIndexData; // Core thread
 		std::shared_ptr<IndexData> mIndexData; // Core thread
 
 
-		Vector<SubMesh>::type mSubMeshes; // Sim thread
-		SubMesh mDefaultSubMesh; // Immutable
-
-		UINT32 mNumVertices; // Immutable
-		UINT32 mNumIndices; // Immutable
 		VertexDataDescPtr mVertexDesc; // Immutable
 		VertexDataDescPtr mVertexDesc; // Immutable
 		MeshBufferType mBufferType; // Immutable
 		MeshBufferType mBufferType; // Immutable
 		IndexBuffer::IndexType mIndexType; // Immutable
 		IndexBuffer::IndexType mIndexType; // Immutable

+ 113 - 0
CamelotCore/Include/CmMeshBase.h

@@ -0,0 +1,113 @@
+#pragma once
+
+#include "CmPrerequisites.h"
+#include "CmGpuResource.h"
+#include "CmDrawOps.h"
+#include "CmSubMesh.h"
+
+namespace CamelotFramework
+{
+	enum class MeshBufferType
+	{
+		Static,
+		Dynamic
+	};
+
+	class CM_EXPORT MeshBase : public GpuResource
+	{
+	public:
+		MeshBase(UINT32 numVertices, UINT32 numIndices, DrawOperationType drawOp = DOT_TRIANGLE_LIST);
+		virtual ~MeshBase();
+
+		void clearSubMeshes();
+
+		void addSubMesh(UINT32 indexOffset, UINT32 indexCount, DrawOperationType drawOp = DOT_TRIANGLE_LIST);
+
+		/**
+		 * @brief	Sets a set of sub-meshes containing data used for rendering a 
+		 * 			certain portion of this mesh. Overwrites any previous sub-meshes.
+		 * 			
+		 * @note	Sim thread only.
+		 */
+		void setSubMeshes(const Vector<SubMesh>::type& subMeshes);
+
+		/**
+		 * @brief	Retrieves a sub-mesh containing data used for rendering a
+		 * 			certain portion of this mesh.
+		 * 			
+		 * @note	Sim thread only.
+		 */
+		const SubMesh& getSubMesh(UINT32 subMeshIdx = 0) const;
+
+		/**
+		 * @brief	Retrieves a total number of sub-meshes in this mesh.
+		 * 			
+		 * @note	Sim thread only.
+		 */
+		UINT32 getNumSubMeshes() const;
+
+		/**
+		 * @brief	Get vertex data used for rendering.
+		 *  
+		 * @note	Core thread only. Internal method.
+		 */
+		virtual std::shared_ptr<VertexData> getVertexData() const = 0;
+
+		/**
+		 * @brief	Get index data used for rendering.
+		 *  
+		 * @note	Core thread only. Internal method.
+		 */
+		virtual std::shared_ptr<IndexData> getIndexData() const = 0;
+
+		/**
+		 * @brief	Returns an offset into the vertex buffers that is returned
+		 * 			by getVertexData that signifies where this meshes vertices
+		 * 			begin.
+		 * 			
+		 * @note	Used when multiple meshes share the same buffers.
+		 * 			
+		 *			Core thread only. Internal method.
+		 */
+		virtual UINT32 getVertexOffset() const { return 0; }
+
+		/**
+		 * @brief	Returns an offset into the index buffer that is returned
+		 * 			by getIndexData that signifies where this meshes indices
+		 * 			begin.
+		 * 			
+		 * @note	Used when multiple meshes share the same buffers.
+		 * 			
+		 *			Core thread only. Internal method.
+		 */
+		virtual UINT32 getIndexOffset() const { return 0; }
+
+		/**
+		 * @brief	Called whenever this mesh starts being used on the GPU.
+		 * 			
+		 * @note	Needs to be called after all commands referencing this 
+		 * 			mesh have been sent to the GPU.
+		 * 			
+		 *			Core thread only. Internal method.
+		 */
+		virtual void notifyUsedOnGPU() { }
+
+	protected:
+		Vector<SubMesh>::type mSubMeshes; // Sim thread
+		SubMesh mDefaultSubMesh; // Immutable
+
+		UINT32 mNumVertices; // Immutable
+		UINT32 mNumIndices; // Immutable
+
+		/************************************************************************/
+		/* 								SERIALIZATION                      		*/
+		/************************************************************************/
+	private:
+		MeshBase(); // Serialization only
+
+	public:
+		friend class MeshBaseRTTI;
+		static RTTITypeBase* getRTTIStatic();
+		virtual RTTITypeBase* getRTTI() const;
+	};
+}

+ 57 - 0
CamelotCore/Include/CmMeshBaseRTTI.h

@@ -0,0 +1,57 @@
+#pragma once
+
+#include "CmPrerequisites.h"
+#include "CmRTTIType.h"
+#include "CmApplication.h"
+#include "CmMeshBase.h"
+#include "CmException.h"
+
+namespace CamelotFramework
+{
+	CM_ALLOW_MEMCPY_SERIALIZATION(SubMesh);
+
+	class MeshBaseRTTI : public RTTIType<MeshBase, GpuResource, MeshBaseRTTI>
+	{
+		SubMesh& getSubMesh(MeshBase* obj, UINT32 arrayIdx) { return obj->mSubMeshes[arrayIdx]; }
+		void setSubMesh(MeshBase* obj, UINT32 arrayIdx, SubMesh& value) { obj->mSubMeshes[arrayIdx] = value; }
+		UINT32 getNumSubmeshes(MeshBase* obj) { return (UINT32)obj->mSubMeshes.size(); }
+		void setNumSubmeshes(MeshBase* obj, UINT32 numElements) { obj->mSubMeshes.resize(numElements); }
+
+		SubMesh& getDefaultSubMesh(MeshBase* obj) { return obj->mDefaultSubMesh; }
+		void setDefaultSubMesh(MeshBase* obj, SubMesh& value) { obj->mDefaultSubMesh = value; }
+
+		UINT32& getNumVertices(MeshBase* obj) { return obj->mNumVertices; }
+		void setNumVertices(MeshBase* obj, UINT32& value) { obj->mNumVertices = value; }
+
+		UINT32& getNumIndices(MeshBase* obj) { return obj->mNumIndices; }
+		void setNumIndices(MeshBase* obj, UINT32& value) { obj->mNumIndices = value; }
+
+	public:
+		MeshBaseRTTI()
+		{
+			addPlainField("mNumVertices", 0, &MeshBaseRTTI::getNumVertices, &MeshBaseRTTI::setNumVertices);
+			addPlainField("mNumIndices", 1, &MeshBaseRTTI::getNumIndices, &MeshBaseRTTI::setNumIndices);
+
+			addPlainArrayField("mSubMeshes", 2, &MeshBaseRTTI::getSubMesh, 
+				&MeshBaseRTTI::getNumSubmeshes, &MeshBaseRTTI::setSubMesh, &MeshBaseRTTI::setNumSubmeshes);
+
+			addPlainField("mDefaultSubMesh", 3, &MeshBaseRTTI::getDefaultSubMesh, &MeshBaseRTTI::setDefaultSubMesh);
+		}
+
+		virtual std::shared_ptr<IReflectable> newRTTIObject() 
+		{
+			CM_EXCEPT(InternalErrorException, "Cannot instantiate an abstract class.");
+		}
+
+		virtual const String& getRTTIName() 
+		{
+			static String name = "MeshBase";
+			throw name;
+		}
+
+		virtual UINT32 getRTTIId() 
+		{
+			return TID_MeshBase;
+		}
+	};
+}

+ 11 - 0
CamelotCore/Include/CmMeshHeap.h

@@ -0,0 +1,11 @@
+#pragma once
+
+#include "CmPrerequisites.h"
+
+namespace CamelotFramework
+{
+	class CM_EXPORT MeshHeap
+	{
+
+	};
+}

+ 8 - 1
CamelotCore/Include/CmPrerequisites.h

@@ -139,6 +139,9 @@ namespace CamelotFramework
 	class Resources;
 	class Resources;
 	class Texture;
 	class Texture;
 	class Mesh;
 	class Mesh;
+	class MeshBase;
+	class TransientMesh;
+	class MeshHeap;
 	class Font;
 	class Font;
 	class OSDropTarget;
 	class OSDropTarget;
 	// Scene
 	// Scene
@@ -177,6 +180,9 @@ namespace CamelotFramework
 	typedef std::shared_ptr<GpuBuffer> GpuBufferPtr;
 	typedef std::shared_ptr<GpuBuffer> GpuBufferPtr;
 	typedef std::shared_ptr<VertexDeclaration> VertexDeclarationPtr;
 	typedef std::shared_ptr<VertexDeclaration> VertexDeclarationPtr;
 	typedef std::shared_ptr<Mesh> MeshPtr;
 	typedef std::shared_ptr<Mesh> MeshPtr;
+	typedef std::shared_ptr<MeshBase> MeshBasePtr;
+	typedef std::shared_ptr<MeshHeap> MeshHeapPtr;
+	typedef std::shared_ptr<TransientMesh> TransientMeshPtr;
 	typedef std::shared_ptr<Texture> TexturePtr;
 	typedef std::shared_ptr<Texture> TexturePtr;
 	typedef std::shared_ptr<Resource> ResourcePtr;
 	typedef std::shared_ptr<Resource> ResourcePtr;
 	typedef std::shared_ptr<Technique> TechniquePtr;
 	typedef std::shared_ptr<Technique> TechniquePtr;
@@ -273,7 +279,8 @@ namespace CamelotFramework
 		TID_GpuResource = 1061,
 		TID_GpuResource = 1061,
 		TID_PixelData = 1062,
 		TID_PixelData = 1062,
 		TID_GpuResourceData = 1063,
 		TID_GpuResourceData = 1063,
-		TID_VertexDataDesc = 1064
+		TID_VertexDataDesc = 1064,
+		TID_MeshBase = 1065
 	};
 	};
 }
 }
 
 

+ 1 - 1
CamelotCore/Include/CmRenderSystem.h

@@ -191,7 +191,7 @@ namespace CamelotFramework
 		 * @param	useIndices	(optional) If true, drawing is done using the index buffer on the mesh and the provided offset and size, otherwise all mesh vertices are drawn sequentially.
 		 * @param	useIndices	(optional) If true, drawing is done using the index buffer on the mesh and the provided offset and size, otherwise all mesh vertices are drawn sequentially.
 		 * @param	drawOp	   	(optional) Draw operation to use when rendering.
 		 * @param	drawOp	   	(optional) Draw operation to use when rendering.
 		 */
 		 */
-		virtual void render(const MeshPtr& mesh, UINT32 indexOffset = 0, UINT32 indexCount = 0, bool useIndices = true, DrawOperationType drawOp = DOT_TRIANGLE_LIST);
+		virtual void render(const MeshBasePtr& mesh, UINT32 indexOffset = 0, UINT32 indexCount = 0, bool useIndices = true, DrawOperationType drawOp = DOT_TRIANGLE_LIST);
 
 
 		/**
 		/**
 		 * @brief	Draw an object based on currently set
 		 * @brief	Draw an object based on currently set

+ 58 - 0
CamelotCore/Include/CmTransientMesh.h

@@ -0,0 +1,58 @@
+#pragma once
+
+#include "CmPrerequisites.h"
+#include "CmMeshBase.h"
+
+namespace CamelotFramework
+{
+	class CM_EXPORT TransientMesh : public MeshBase
+	{
+	public:
+		virtual ~TransientMesh();
+
+		/**
+		 * @copydoc GpuResource::writeSubresource
+		 */
+		virtual void writeSubresource(UINT32 subresourceIdx, const GpuResourceData& data, bool discardEntireBuffer);
+
+		/**
+		 * @copydoc GpuResource::readSubresource
+		 */
+		virtual void readSubresource(UINT32 subresourceIdx, GpuResourceData& data);
+
+		 /**
+		 * @copydoc MeshBase::getVertexData
+		 */
+		std::shared_ptr<VertexData> getVertexData() const;
+
+		 /**
+		 * @copydoc MeshBase::getIndexData
+		 */
+		std::shared_ptr<IndexData> getIndexData() const;
+
+		/**
+		 * @copydoc MeshBase::getVertexOffset
+		 */
+		virtual UINT32 getVertexOffset() const;
+
+		 /**
+		 * @copydoc MeshBase::getIndexOffset
+		 */
+		virtual UINT32 getIndexOffset() const;
+
+		 /**
+		 * @copydoc MeshBase::notifyUsedOnGPU
+		 */
+		virtual void notifyUsedOnGPU();
+
+	protected:
+		friend class MeshHeap;
+
+		TransientMesh(const MeshHeapPtr& parentHeap, UINT32 id, UINT32 numIndices, 
+			UINT32 numVertices, DrawOperationType drawOp = DOT_TRIANGLE_LIST);
+
+	protected:
+		MeshHeapPtr mParentHeap;
+		UINT32 mId;
+	};
+}

+ 13 - 89
CamelotCore/Source/CmMesh.cpp

@@ -17,37 +17,34 @@ namespace CamelotFramework
 {
 {
 	Mesh::Mesh(UINT32 numVertices, UINT32 numIndices, const VertexDataDescPtr& vertexDesc, 
 	Mesh::Mesh(UINT32 numVertices, UINT32 numIndices, const VertexDataDescPtr& vertexDesc, 
 		MeshBufferType bufferType, DrawOperationType drawOp, IndexBuffer::IndexType indexType)
 		MeshBufferType bufferType, DrawOperationType drawOp, IndexBuffer::IndexType indexType)
-		:mVertexData(nullptr), mIndexData(nullptr), mNumVertices(numVertices), mNumIndices(numIndices), 
-		mVertexDesc(vertexDesc), mBufferType(bufferType), mIndexType(indexType),
-		mDefaultSubMesh(0, numIndices, drawOp)
+		:MeshBase(numVertices, numIndices, drawOp), mVertexData(nullptr), mIndexData(nullptr),
+		mVertexDesc(vertexDesc), mBufferType(bufferType), mIndexType(indexType)
 	{
 	{
-		mSubMeshes.reserve(10);
+
 	}
 	}
 
 
 	Mesh::Mesh(UINT32 numVertices, UINT32 numIndices, const VertexDataDescPtr& vertexDesc, 
 	Mesh::Mesh(UINT32 numVertices, UINT32 numIndices, const VertexDataDescPtr& vertexDesc, 
 		const MeshDataPtr& initialMeshData, MeshBufferType bufferType, DrawOperationType drawOp, IndexBuffer::IndexType indexType)
 		const MeshDataPtr& initialMeshData, MeshBufferType bufferType, DrawOperationType drawOp, IndexBuffer::IndexType indexType)
-		:mVertexData(nullptr), mIndexData(nullptr), mNumVertices(numVertices), mNumIndices(numIndices), 
+		:MeshBase(numVertices, numIndices, drawOp), mVertexData(nullptr), mIndexData(nullptr),
 		mVertexDesc(vertexDesc), mBufferType(bufferType), mIndexType(indexType), 
 		mVertexDesc(vertexDesc), mBufferType(bufferType), mIndexType(indexType), 
-		mTempInitialMeshData(initialMeshData), mDefaultSubMesh(0, numIndices, drawOp)
+		mTempInitialMeshData(initialMeshData)
 	{
 	{
-		mSubMeshes.reserve(10);
+
 	}
 	}
 
 
 	Mesh::Mesh(const MeshDataPtr& initialMeshData, MeshBufferType bufferType, DrawOperationType drawOp)
 	Mesh::Mesh(const MeshDataPtr& initialMeshData, MeshBufferType bufferType, DrawOperationType drawOp)
-		:mVertexData(nullptr), mIndexData(nullptr), mNumVertices(initialMeshData->getNumVertices()), 
-		mNumIndices(initialMeshData->getNumIndices()), mBufferType(bufferType), mIndexType(initialMeshData->getIndexType()),
-		mVertexDesc(initialMeshData->getVertexDesc()), mTempInitialMeshData(initialMeshData),
-		mDefaultSubMesh(0, initialMeshData->getNumIndices(), drawOp)
+		:MeshBase(initialMeshData->getNumVertices(), initialMeshData->getNumIndices(), drawOp), 
+		mVertexData(nullptr), mIndexData(nullptr), mIndexType(initialMeshData->getIndexType()),
+		mVertexDesc(initialMeshData->getVertexDesc()), mTempInitialMeshData(initialMeshData)
 	{
 	{
-		mSubMeshes.reserve(10);
+
 	}
 	}
 
 
 	Mesh::Mesh()
 	Mesh::Mesh()
-		:mVertexData(nullptr), mIndexData(nullptr), mNumVertices(0), mNumIndices(0), 
-		mBufferType(MeshBufferType::Static), mIndexType(IndexBuffer::IT_32BIT),
-		mDefaultSubMesh(0, 0, DOT_TRIANGLE_LIST)
+		:MeshBase(0, 0, DOT_TRIANGLE_LIST), mVertexData(nullptr), mIndexData(nullptr), 
+		mBufferType(MeshBufferType::Static), mIndexType(IndexBuffer::IT_32BIT)
 	{
 	{
-		mSubMeshes.reserve(10);
+
 	}
 	}
 
 
 	Mesh::~Mesh()
 	Mesh::~Mesh()
@@ -250,79 +247,6 @@ namespace CamelotFramework
 		return mIndexData;
 		return mIndexData;
 	}
 	}
 
 
-	void Mesh::clearSubMeshes()
-	{
-		THROW_IF_CORE_THREAD;
-
-		mSubMeshes.clear();
-	}
-
-	void Mesh::addSubMesh(UINT32 indexOffset, UINT32 indexCount, DrawOperationType drawOp)
-	{
-		if((indexOffset + indexCount) >= mNumIndices)
-		{
-			LOGWRN("Provided sub-mesh references indexes out of range. Sub-mesh range: " 
-				+ toString(indexOffset) + " .. " + toString(indexOffset + indexCount) + "." \
-				"Valid range is: 0 .. " + toString(mNumIndices) + ". Ignoring command.");
-
-			return;
-		}
-
-		mSubMeshes.push_back(SubMesh(indexOffset, indexCount, drawOp));
-	}
-
-	void Mesh::setSubMeshes(const Vector<SubMesh>::type& subMeshes)
-	{
-		THROW_IF_CORE_THREAD;
-
-		for(auto& subMesh : subMeshes)
-		{
-			if((subMesh.indexOffset + subMesh.indexCount) >= mNumIndices)
-			{
-				LOGWRN("Provided sub-mesh references indexes out of range. Sub-mesh range: " 
-					+ toString(subMesh.indexOffset) + " .. " + toString(subMesh.indexOffset + subMesh.indexCount) + "." \
-					"Valid range is: 0 .. " + toString(mNumIndices) + ". Ignoring command.");
-
-				return;
-			}
-		}
-
-		mSubMeshes = subMeshes;
-	}
-
-	const SubMesh& Mesh::getSubMesh(UINT32 subMeshIdx) const
-	{
-		THROW_IF_CORE_THREAD;
-
-		if(mSubMeshes.size() == 0 && subMeshIdx == 0)
-		{
-			return mDefaultSubMesh;
-		}
-
-		if(subMeshIdx < 0 || subMeshIdx >= mSubMeshes.size())
-		{
-			CM_EXCEPT(InvalidParametersException, "Invalid sub-mesh index (" 
-				+ toString(subMeshIdx) + "). Number of sub-meshes available: " + toString((int)mSubMeshes.size()));
-		}
-
-		return mSubMeshes[subMeshIdx];
-	}
-
-	UINT32 Mesh::getNumSubMeshes() const
-	{
-		THROW_IF_CORE_THREAD;
-
-		if(mSubMeshes.size() > 0)
-			return (UINT32)mSubMeshes.size();
-		else
-		{
-			if(mDefaultSubMesh.indexCount > 0)
-				return 1;
-			else
-				return 0;
-		}
-	}
-
 	void Mesh::initialize_internal()
 	void Mesh::initialize_internal()
 	{
 	{
 		THROW_IF_NOT_CORE_THREAD;
 		THROW_IF_NOT_CORE_THREAD;

+ 110 - 0
CamelotCore/Source/CmMeshBase.cpp

@@ -0,0 +1,110 @@
+#include "CmMeshBase.h"
+#include "CmMeshBaseRTTI.h"
+#include "CmCoreThread.h"
+#include "CmDebug.h"
+
+namespace CamelotFramework
+{
+	MeshBase::MeshBase(UINT32 numVertices, UINT32 numIndices, DrawOperationType drawOp)
+		:mNumIndices(numIndices), mNumVertices(numVertices), mDefaultSubMesh(0, numIndices, drawOp)
+	{
+		mSubMeshes.reserve(10);
+	}
+
+	MeshBase::MeshBase()
+	{
+		mSubMeshes.reserve(10);
+	}
+
+	MeshBase::~MeshBase()
+	{
+
+	}
+
+	void MeshBase::clearSubMeshes()
+	{
+		THROW_IF_CORE_THREAD;
+
+		mSubMeshes.clear();
+	}
+
+	void MeshBase::addSubMesh(UINT32 indexOffset, UINT32 indexCount, DrawOperationType drawOp)
+	{
+		if((indexOffset + indexCount) >= mNumIndices)
+		{
+			LOGWRN("Provided sub-mesh references indexes out of range. Sub-mesh range: " 
+				+ toString(indexOffset) + " .. " + toString(indexOffset + indexCount) + "." \
+				"Valid range is: 0 .. " + toString(mNumIndices) + ". Ignoring command.");
+
+			return;
+		}
+
+		mSubMeshes.push_back(SubMesh(indexOffset, indexCount, drawOp));
+	}
+
+	void MeshBase::setSubMeshes(const Vector<SubMesh>::type& subMeshes)
+	{
+		THROW_IF_CORE_THREAD;
+
+		for(auto& subMesh : subMeshes)
+		{
+			if((subMesh.indexOffset + subMesh.indexCount) >= mNumIndices)
+			{
+				LOGWRN("Provided sub-mesh references indexes out of range. Sub-mesh range: " 
+					+ toString(subMesh.indexOffset) + " .. " + toString(subMesh.indexOffset + subMesh.indexCount) + "." \
+					"Valid range is: 0 .. " + toString(mNumIndices) + ". Ignoring command.");
+
+				return;
+			}
+		}
+
+		mSubMeshes = subMeshes;
+	}
+
+	const SubMesh& MeshBase::getSubMesh(UINT32 subMeshIdx) const
+	{
+		THROW_IF_CORE_THREAD;
+
+		if(mSubMeshes.size() == 0 && subMeshIdx == 0)
+		{
+			return mDefaultSubMesh;
+		}
+
+		if(subMeshIdx < 0 || subMeshIdx >= mSubMeshes.size())
+		{
+			CM_EXCEPT(InvalidParametersException, "Invalid sub-mesh index (" 
+				+ toString(subMeshIdx) + "). Number of sub-meshes available: " + toString((int)mSubMeshes.size()));
+		}
+
+		return mSubMeshes[subMeshIdx];
+	}
+
+	UINT32 MeshBase::getNumSubMeshes() const
+	{
+		THROW_IF_CORE_THREAD;
+
+		if(mSubMeshes.size() > 0)
+			return (UINT32)mSubMeshes.size();
+		else
+		{
+			if(mDefaultSubMesh.indexCount > 0)
+				return 1;
+			else
+				return 0;
+		}
+	}
+
+	/************************************************************************/
+	/* 								SERIALIZATION                      		*/
+	/************************************************************************/
+
+	RTTITypeBase* MeshBase::getRTTIStatic()
+	{
+		return MeshBaseRTTI::instance();
+	}
+
+	RTTITypeBase* MeshBase::getRTTI() const
+	{
+		return MeshBase::getRTTIStatic();
+	}
+}

+ 6 - 0
CamelotCore/Source/CmMeshHeap.cpp

@@ -0,0 +1,6 @@
+#include "CmMeshHeap.h"
+
+namespace CamelotFramework
+{
+
+}

+ 3 - 26
CamelotCore/Source/CmMeshRTTI.h

@@ -8,30 +8,14 @@
 
 
 namespace CamelotFramework
 namespace CamelotFramework
 {
 {
-	CM_ALLOW_MEMCPY_SERIALIZATION(SubMesh);
-
-	class MeshRTTI : public RTTIType<Mesh, GpuResource, MeshRTTI>
+	class MeshRTTI : public RTTIType<Mesh, MeshBase, MeshRTTI>
 	{
 	{
-		SubMesh& getSubMesh(Mesh* obj, UINT32 arrayIdx) { return obj->mSubMeshes[arrayIdx]; }
-		void setSubMesh(Mesh* obj, UINT32 arrayIdx, SubMesh& value) { obj->mSubMeshes[arrayIdx] = value; }
-		UINT32 getNumSubmeshes(Mesh* obj) { return (UINT32)obj->mSubMeshes.size(); }
-		void setNumSubmeshes(Mesh* obj, UINT32 numElements) { obj->mSubMeshes.resize(numElements); }
-
-		SubMesh& getDefaultSubMesh(Mesh* obj) { return obj->mDefaultSubMesh; }
-		void setDefaultSubMesh(Mesh* obj, SubMesh& value) { obj->mDefaultSubMesh = value; }
-
 		VertexDataDescPtr getVertexDesc(Mesh* obj) { return obj->mVertexDesc; }
 		VertexDataDescPtr getVertexDesc(Mesh* obj) { return obj->mVertexDesc; }
 		void setVertexDesc(Mesh* obj, VertexDataDescPtr value) { obj->mVertexDesc = value; }
 		void setVertexDesc(Mesh* obj, VertexDataDescPtr value) { obj->mVertexDesc = value; }
 
 
 		IndexBuffer::IndexType& getIndexType(Mesh* obj) { return obj->mIndexType; }
 		IndexBuffer::IndexType& getIndexType(Mesh* obj) { return obj->mIndexType; }
 		void setIndexType(Mesh* obj, IndexBuffer::IndexType& value) { obj->mIndexType = value; }
 		void setIndexType(Mesh* obj, IndexBuffer::IndexType& value) { obj->mIndexType = value; }
 
 
-		UINT32& getNumVertices(Mesh* obj) { return obj->mNumVertices; }
-		void setNumVertices(Mesh* obj, UINT32& value) { obj->mNumVertices = value; }
-
-		UINT32& getNumIndices(Mesh* obj) { return obj->mNumIndices; }
-		void setNumIndices(Mesh* obj, UINT32& value) { obj->mNumIndices = value; }
-
 		UINT32& getBufferType(Mesh* obj) { return (UINT32&)obj->mBufferType; }
 		UINT32& getBufferType(Mesh* obj) { return (UINT32&)obj->mBufferType; }
 		void setBufferType(Mesh* obj, UINT32& value) { obj->mBufferType = (MeshBufferType)value; }
 		void setBufferType(Mesh* obj, UINT32& value) { obj->mBufferType = (MeshBufferType)value; }
 
 
@@ -58,16 +42,9 @@ namespace CamelotFramework
 			addReflectablePtrField("mVertexDesc", 0, &MeshRTTI::getVertexDesc, &MeshRTTI::setVertexDesc);
 			addReflectablePtrField("mVertexDesc", 0, &MeshRTTI::getVertexDesc, &MeshRTTI::setVertexDesc);
 
 
 			addPlainField("mIndexType", 1, &MeshRTTI::getIndexType, &MeshRTTI::setIndexType);
 			addPlainField("mIndexType", 1, &MeshRTTI::getIndexType, &MeshRTTI::setIndexType);
-			addPlainField("mNumVertices", 2, &MeshRTTI::getNumVertices, &MeshRTTI::setNumVertices);
-			addPlainField("mNumIndices", 3, &MeshRTTI::getNumIndices, &MeshRTTI::setNumIndices);
-			addPlainField("mBufferType", 4, &MeshRTTI::getBufferType, &MeshRTTI::setBufferType);
-
-			addReflectablePtrField("mMeshData", 5, &MeshRTTI::getMeshData, &MeshRTTI::setMeshData);
-
-			addPlainArrayField("mSubMeshes", 6, &MeshRTTI::getSubMesh, 
-				&MeshRTTI::getNumSubmeshes, &MeshRTTI::setSubMesh, &MeshRTTI::setNumSubmeshes);
+			addPlainField("mBufferType", 2, &MeshRTTI::getBufferType, &MeshRTTI::setBufferType);
 
 
-			addPlainField("mDefaultSubMesh", 7, &MeshRTTI::getDefaultSubMesh, &MeshRTTI::setDefaultSubMesh);
+			addReflectablePtrField("mMeshData", 3, &MeshRTTI::getMeshData, &MeshRTTI::setMeshData);
 		}
 		}
 
 
 		virtual void onDeserializationEnded(IReflectable* obj)
 		virtual void onDeserializationEnded(IReflectable* obj)

+ 1 - 1
CamelotCore/Source/CmRenderSystem.cpp

@@ -208,7 +208,7 @@ namespace CamelotFramework {
         return false;
         return false;
 	}
 	}
 
 
-	void RenderSystem::render(const MeshPtr& mesh, UINT32 indexOffset, UINT32 indexCount, bool useIndices, DrawOperationType drawOp)
+	void RenderSystem::render(const MeshBasePtr& mesh, UINT32 indexOffset, UINT32 indexCount, bool useIndices, DrawOperationType drawOp)
 	{
 	{
 		THROW_IF_NOT_CORE_THREAD;
 		THROW_IF_NOT_CORE_THREAD;
 
 

+ 56 - 0
CamelotCore/Source/CmTransientMesh.cpp

@@ -0,0 +1,56 @@
+#include "CmTransientMesh.h"
+#include "CmVertexData.h"
+#include "CmIndexData.h"
+
+namespace CamelotFramework
+{
+	TransientMesh::TransientMesh(const MeshHeapPtr& parentHeap, UINT32 id, UINT32 numIndices, UINT32 numVertices, DrawOperationType drawOp)
+		:MeshBase(numVertices, numIndices, drawOp), mParentHeap(parentHeap), mId(id)
+	{
+
+	}
+
+	TransientMesh::~TransientMesh()
+	{
+
+	}
+
+	void TransientMesh::writeSubresource(UINT32 subresourceIdx, const GpuResourceData& data, bool discardEntireBuffer)
+	{
+		CM_EXCEPT(InvalidStateException, "Updating is not supported on a transient mesh.");
+	}
+
+	void TransientMesh::readSubresource(UINT32 subresourceIdx, GpuResourceData& data)
+	{
+		CM_EXCEPT(InvalidStateException, "Reading is not supported on a transient mesh.");
+	}
+
+	std::shared_ptr<VertexData> TransientMesh::getVertexData() const
+	{
+		// TODO - Get vertex data from parent MeshHeap
+		return nullptr;
+	}
+
+	std::shared_ptr<IndexData> TransientMesh::getIndexData() const
+	{
+		// TODO - Get index data from parent MeshHeap
+		return nullptr;
+	}
+
+	UINT32 TransientMesh::getVertexOffset() const
+	{
+		// TODO - Get vertex offset from parent MeshHeap
+		return 0;
+	}
+
+	UINT32 TransientMesh::getIndexOffset() const
+	{
+		// TODO - Get index offset from parent MeshHeap
+		return 0;
+	}
+
+	void TransientMesh::notifyUsedOnGPU()
+	{
+		// TODO - Refresh EventQuery
+	}
+}

+ 43 - 1
Opts.txt

@@ -31,4 +31,46 @@ TransientMesh
 ----------
 ----------
 
 
 BIG TODO FINALLY: Reorganize GUI so it all uses one big vertex buffer (probably in the form of a TransientMesh). This means I need better support for drawing individual objects
 BIG TODO FINALLY: Reorganize GUI so it all uses one big vertex buffer (probably in the form of a TransientMesh). This means I need better support for drawing individual objects
-from a transient mesh by drawing only parts of its buffer. But only do this after I have optimized and tested the normal mesh (on all render systems)
+from a transient mesh by drawing only parts of its buffer. But only do this after I have optimized and tested the normal mesh (on all render systems)
+
+
+----------
+
+Transient mesh brainstorming:
+How to release memory from transient mesh?
+ - Make it use non-CoreAccessor interface?
+
+
+TransientMesh
+ Upon construction we specify vertex and index format, including initial vertex/index buffer sizes
+   MeshChunk allocate(UINT32 numVertices, UINT32 numIndices)
+    - Thread safe method (custom mutex), returns a MeshChunk which contains an unique index
+    - Each allocation represents its own SubMesh - there can't be multiple sub-meshes per allocation
+   deallocate(MeshChunk chunk)
+    - I could make MeshChunk as GpuResource, so I can write to it directly
+   How do I set materials per sub-mesh?
+    - I keep a mapping MeshChunk->Material in GUIManager 
+   I will need to update Render method so it can accept MeshChunk?
+    - Or should TransientMesh derive from Mesh?
+   When calling Render I need to provide index offset/length, however since I will be
+   supporting defragmenting that can change internally at any time. It would be ideal to 
+   retrieve that data when on core thread.
+    - Maybe even rethink Mesh submeshes so that they have a unified interface?
+	- BUT: I can handle defragment on the CPU. I just need to find offsets and sizes, and actual
+	  memory copies can be done on the core thread later.
+
+Name it MeshHeap instead of TransientMesh
+ - It can derive from a common class MeshBase (which Mesh also derives from)
+ - Render can then accept MeshBase instead of Mesh
+
+
+-----------
+
+POTENTIALLY
+
+I could have normal Meshes use one big vertex/index buffer in the background.
+ - However that means Dynamic/Static tags don't mean anything
+ - writeSubresource discard is ignored
+ - It's not as clear to the user
+ - Need to implement reading as well
+ - Not sure if it would work well with a bunch of smaller allocations (Although I think we would avoid those in any case)