Просмотр исходного кода

Beggining work on fonts
Made vector/map a plain serializable type

Marko Pintera 13 лет назад
Родитель
Сommit
e02ce5a386

+ 7 - 0
CamelotCore/CamelotCore.vcxproj

@@ -192,6 +192,10 @@
     <ClInclude Include="Include\CmDeferredRenderContext.h" />
     <ClInclude Include="Include\CmDeferredRenderContext.h" />
     <ClInclude Include="Include\CmDepthStencilStateRTTI.h" />
     <ClInclude Include="Include\CmDepthStencilStateRTTI.h" />
     <ClInclude Include="Include\CmDepthStencilState.h" />
     <ClInclude Include="Include\CmDepthStencilState.h" />
+    <ClInclude Include="Include\CmFont.h" />
+    <ClInclude Include="Include\CmFontDesc.h" />
+    <ClInclude Include="Include\CmFontManager.h" />
+    <ClInclude Include="Include\CmFontRTTI.h" />
     <ClInclude Include="Include\CmGpuBuffer.h" />
     <ClInclude Include="Include\CmGpuBuffer.h" />
     <ClInclude Include="Include\CmGpuBufferView.h" />
     <ClInclude Include="Include\CmGpuBufferView.h" />
     <ClInclude Include="Include\CmGpuParamBlock.h" />
     <ClInclude Include="Include\CmGpuParamBlock.h" />
@@ -215,6 +219,7 @@
     <ClInclude Include="Include\CmOcclusionQuery.h" />
     <ClInclude Include="Include\CmOcclusionQuery.h" />
     <ClInclude Include="Include\CmPixelBuffer.h" />
     <ClInclude Include="Include\CmPixelBuffer.h" />
     <ClInclude Include="Include\CmGpuProgIncludeImporter.h" />
     <ClInclude Include="Include\CmGpuProgIncludeImporter.h" />
+    <ClInclude Include="Include\CmTextRenderer.h" />
     <ClInclude Include="Include\CmTextureView.h" />
     <ClInclude Include="Include\CmTextureView.h" />
     <ClInclude Include="Include\CmVertexBuffer.h" />
     <ClInclude Include="Include\CmVertexBuffer.h" />
     <ClInclude Include="Include\CmHighLevelGpuProgram.h" />
     <ClInclude Include="Include\CmHighLevelGpuProgram.h" />
@@ -293,6 +298,8 @@
     <ClCompile Include="Source\CmCoreGpuObjectManager.cpp" />
     <ClCompile Include="Source\CmCoreGpuObjectManager.cpp" />
     <ClCompile Include="Source\CmDeferredRenderContext.cpp" />
     <ClCompile Include="Source\CmDeferredRenderContext.cpp" />
     <ClCompile Include="Source\CmDepthStencilState.cpp" />
     <ClCompile Include="Source\CmDepthStencilState.cpp" />
+    <ClCompile Include="Source\CmFont.cpp" />
+    <ClCompile Include="Source\CmFontManager.cpp" />
     <ClCompile Include="Source\CmGpuBuffer.cpp" />
     <ClCompile Include="Source\CmGpuBuffer.cpp" />
     <ClCompile Include="Source\CmGpuBufferView.cpp" />
     <ClCompile Include="Source\CmGpuBufferView.cpp" />
     <ClCompile Include="Source\CmGpuParamBlock.cpp" />
     <ClCompile Include="Source\CmGpuParamBlock.cpp" />

+ 27 - 0
CamelotCore/CamelotCore.vcxproj.filters

@@ -82,6 +82,12 @@
     <Filter Include="Source Files\Win32">
     <Filter Include="Source Files\Win32">
       <UniqueIdentifier>{5a1e28c5-e784-44e6-974f-f1d0d66474ed}</UniqueIdentifier>
       <UniqueIdentifier>{5a1e28c5-e784-44e6-974f-f1d0d66474ed}</UniqueIdentifier>
     </Filter>
     </Filter>
+    <Filter Include="Header Files\Text">
+      <UniqueIdentifier>{1daa1a6e-95c0-4e63-b339-4a884773fa64}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Source Files\Text">
+      <UniqueIdentifier>{96b913ee-4ffb-4c60-9aa9-a51e0faf8060}</UniqueIdentifier>
+    </Filter>
   </ItemGroup>
   </ItemGroup>
   <ItemGroup>
   <ItemGroup>
     <ClInclude Include="Include\CmConfigOptionMap.h">
     <ClInclude Include="Include\CmConfigOptionMap.h">
@@ -393,6 +399,21 @@
     <ClInclude Include="Include\CmGpuProgramImportOptionsRTTI.h">
     <ClInclude Include="Include\CmGpuProgramImportOptionsRTTI.h">
       <Filter>Header Files\RTTI</Filter>
       <Filter>Header Files\RTTI</Filter>
     </ClInclude>
     </ClInclude>
+    <ClInclude Include="Include\CmFont.h">
+      <Filter>Header Files\Text</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\CmFontDesc.h">
+      <Filter>Header Files\Text</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\CmTextRenderer.h">
+      <Filter>Header Files\Text</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\CmFontRTTI.h">
+      <Filter>Header Files\RTTI</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\CmFontManager.h">
+      <Filter>Header Files\Text</Filter>
+    </ClInclude>
   </ItemGroup>
   </ItemGroup>
   <ItemGroup>
   <ItemGroup>
     <ClCompile Include="Source\CamelotRenderer.cpp">
     <ClCompile Include="Source\CamelotRenderer.cpp">
@@ -608,5 +629,11 @@
     <ClCompile Include="Source\CmGpuProgramImportOptions.cpp">
     <ClCompile Include="Source\CmGpuProgramImportOptions.cpp">
       <Filter>Source Files\Importer</Filter>
       <Filter>Source Files\Importer</Filter>
     </ClCompile>
     </ClCompile>
+    <ClCompile Include="Source\CmFont.cpp">
+      <Filter>Source Files\Text</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\CmFontManager.cpp">
+      <Filter>Source Files\Text</Filter>
+    </ClCompile>
   </ItemGroup>
   </ItemGroup>
 </Project>
 </Project>

+ 7 - 5
CamelotCore/Include/CmBlendStateRTTI.h

@@ -11,7 +11,7 @@ namespace CamelotEngine
 	{	
 	{	
 		enum { id = TID_BLEND_STATE_DESC }; enum { hasDynamicSize = 1 };
 		enum { id = TID_BLEND_STATE_DESC }; enum { hasDynamicSize = 1 };
 
 
-		static void toMemory(BLEND_STATE_DESC& data, char* memory)
+		static void toMemory(const BLEND_STATE_DESC& data, char* memory)
 		{ 
 		{ 
 			UINT32 size = getDynamicSize(data);
 			UINT32 size = getDynamicSize(data);
 
 
@@ -21,17 +21,19 @@ namespace CamelotEngine
 			memcpy(memory, &data, size); 
 			memcpy(memory, &data, size); 
 		}
 		}
 
 
-		static void fromMemory(BLEND_STATE_DESC& data, char* memory)
+		static UINT32 fromMemory(BLEND_STATE_DESC& data, char* memory)
 		{ 
 		{ 
 			UINT32 size;
 			UINT32 size;
 			memcpy(&size, memory, sizeof(UINT32)); 
 			memcpy(&size, memory, sizeof(UINT32)); 
 			memory += sizeof(UINT32);
 			memory += sizeof(UINT32);
 
 
-			size -= sizeof(UINT32);
-			memcpy((void*)&data, memory, size); 
+			UINT32 dataSize = size - sizeof(UINT32);
+			memcpy((void*)&data, memory, dataSize); 
+
+			return size;
 		}
 		}
 
 
-		static UINT32 getDynamicSize(BLEND_STATE_DESC& data)	
+		static UINT32 getDynamicSize(const BLEND_STATE_DESC& data)	
 		{ 
 		{ 
 			UINT64 dataSize = sizeof(data) + sizeof(UINT32);
 			UINT64 dataSize = sizeof(data) + sizeof(UINT32);
 
 

+ 45 - 0
CamelotCore/Include/CmFont.h

@@ -0,0 +1,45 @@
+#pragma once
+
+#include "CmPrerequisites.h"
+#include "CmResource.h"
+#include "CmFontDesc.h"
+
+namespace CamelotEngine
+{
+	// TODO - When saved on disk font currently stores a copy of the texture pages. This should be acceptable
+	// if you import a new TrueType or OpenType font since the texture will be generated on the spot
+	// but if you use a bitmap texture to initialize the font manually, then you will potentially have duplicate textures.
+	// Also, changing the source texture will not automatically update the font because there is no direct link between them.
+	// -- This is probably not a large problem, but it is something to keep an eye out.
+	class CM_EXPORT Font : public Resource
+	{
+	public:
+		virtual ~Font();
+
+		void initialize(const FONT_DESC& fontDesc, vector<TexturePtr>::type texturePages);
+
+	protected:
+		friend class FontManager;
+
+		Font();
+
+	private:
+		vector<TexturePtr>::type mTexturePages;
+		FONT_DESC mFontDesc;
+
+		/************************************************************************/
+		/* 								SERIALIZATION                      		*/
+		/************************************************************************/
+	public:
+		friend class FontRTTI;
+		static RTTITypeBase* getRTTIStatic();
+		virtual RTTITypeBase* getRTTI() const;
+
+		/************************************************************************/
+		/* 								STATICS		                     		*/
+		/************************************************************************/
+		
+	public:
+		static FontHandle create(const FONT_DESC& fontDesc, vector<TexturePtr>::type texturePages);
+	};
+}

+ 153 - 0
CamelotCore/Include/CmFontDesc.h

@@ -0,0 +1,153 @@
+#pragma once
+
+#include "CmPrerequisites.h"
+
+namespace CamelotEngine
+{
+	struct KerningPair
+	{
+		UINT32 leftCharId;
+		UINT32 rightCharId;
+		INT32 amount;
+	};
+
+	struct CHAR_DESC
+	{
+		UINT32 charId;
+		UINT32 page;
+		float uvX, uvY;
+		float uvWidth, uvHeight;
+		UINT32 width, height;
+		INT32 xOffset, yOffset;
+		INT32 xAdvance, yAdvance;
+
+		vector<KerningPair>::type kerningPairs;
+	};
+
+	struct FONT_DESC
+	{
+		map<UINT32, CHAR_DESC>::type characters;
+	};
+
+	// Make CHAR_DESC serializable
+	template<> struct RTTIPlainType<CHAR_DESC>
+	{	
+		enum { id = TID_CHAR_DESC }; enum { hasDynamicSize = 1 };
+
+		static void toMemory(const CHAR_DESC& data, char* memory)
+		{ 
+			UINT32 size = getDynamicSize(data);
+
+			memcpy(memory, &size, sizeof(UINT32));
+			memory += sizeof(UINT32);
+
+			memory = rttiWriteElem(data.charId, memory);
+			memory = rttiWriteElem(data.page, memory);
+			memory = rttiWriteElem(data.uvX, memory);
+			memory = rttiWriteElem(data.uvY, memory);
+			memory = rttiWriteElem(data.uvWidth, memory);
+			memory = rttiWriteElem(data.uvHeight, memory);
+			memory = rttiWriteElem(data.width, memory);
+			memory = rttiWriteElem(data.height, memory);
+			memory = rttiWriteElem(data.xOffset, memory);
+			memory = rttiWriteElem(data.yOffset, memory);
+			memory = rttiWriteElem(data.xAdvance, memory);
+			memory = rttiWriteElem(data.yAdvance, memory);
+			memory = rttiWriteElem(data.kerningPairs, memory);
+		}
+
+		static UINT32 fromMemory(CHAR_DESC& data, char* memory)
+		{ 
+			UINT32 size;
+			memcpy(&size, memory, sizeof(UINT32)); 
+			memory += sizeof(UINT32);
+
+			memory = rttiReadElem(data.charId, memory);
+			memory = rttiReadElem(data.page, memory);
+			memory = rttiReadElem(data.uvX, memory);
+			memory = rttiReadElem(data.uvY, memory);
+			memory = rttiReadElem(data.uvWidth, memory);
+			memory = rttiReadElem(data.uvHeight, memory);
+			memory = rttiReadElem(data.width, memory);
+			memory = rttiReadElem(data.height, memory);
+			memory = rttiReadElem(data.xOffset, memory);
+			memory = rttiReadElem(data.yOffset, memory);
+			memory = rttiReadElem(data.xAdvance, memory);
+			memory = rttiReadElem(data.yAdvance, memory);
+			memory = rttiReadElem(data.kerningPairs, memory);
+
+			return size;
+		}
+
+		static UINT32 getDynamicSize(const CHAR_DESC& data)	
+		{ 
+			UINT64 dataSize = sizeof(data.charId)
+				+ sizeof(data.page)
+				+ sizeof(data.uvX)
+				+ sizeof(data.uvY)
+				+ sizeof(data.uvWidth)
+				+ sizeof(data.uvHeight)
+				+ sizeof(data.width)
+				+ sizeof(data.height)
+				+ sizeof(data.xOffset)
+				+ sizeof(data.yOffset)
+				+ sizeof(data.xAdvance)
+				+ sizeof(data.yAdvance)
+				+ RTTIPlainType<std::vector<KerningPair>>::getDynamicSize(data.kerningPairs);
+
+			dataSize += sizeof(UINT32);
+
+#if CM_DEBUG_MODE
+			if(dataSize > std::numeric_limits<UINT32>::max())
+			{
+				CM_EXCEPT(InternalErrorException, "Data overflow! Size doesn't fit into 32 bits.");
+			}
+#endif
+
+			return (UINT32)dataSize;
+		}	
+	}; 
+
+	// Make FONT_DESC serializable
+	template<> struct RTTIPlainType<FONT_DESC>
+	{	
+		enum { id = TID_FONT_DESC }; enum { hasDynamicSize = 1 };
+
+		static void toMemory(const FONT_DESC& data, char* memory)
+		{ 
+			UINT32 size = getDynamicSize(data);
+
+			memcpy(memory, &size, sizeof(UINT32));
+			memory += sizeof(UINT32);
+			
+			RTTIPlainType<std::map<UINT32, CHAR_DESC>>::toMemory(data.characters, memory);
+		}
+
+		static UINT32 fromMemory(FONT_DESC& data, char* memory)
+		{ 
+			UINT32 size;
+			memcpy(&size, memory, sizeof(UINT32)); 
+			memory += sizeof(UINT32);
+
+			RTTIPlainType<std::map<UINT32, CHAR_DESC>>::fromMemory(data.characters, memory);
+
+			return size;
+		}
+
+		static UINT32 getDynamicSize(const FONT_DESC& data)	
+		{ 
+			UINT64 dataSize = sizeof(UINT32);
+			dataSize += RTTIPlainType<std::map<UINT32, CHAR_DESC>>::getDynamicSize(data.characters);
+
+
+#if CM_DEBUG_MODE
+			if(dataSize > std::numeric_limits<UINT32>::max())
+			{
+				CM_EXCEPT(InternalErrorException, "Data overflow! Size doesn't fit into 32 bits.");
+			}
+#endif
+
+			return (UINT32)dataSize;
+		}	
+	}; 
+}

+ 14 - 0
CamelotCore/Include/CmFontManager.h

@@ -0,0 +1,14 @@
+#pragma once
+
+#include "CmPrerequisites.h"
+#include "CmModule.h"
+
+namespace CamelotEngine
+{
+	class CM_EXPORT FontManager : public Module<FontManager>
+	{
+	public:
+		FontPtr create(const FONT_DESC& fontDesc, vector<TexturePtr>::type texturePages) const;
+		FontPtr createEmpty() const;
+	};
+}

+ 75 - 0
CamelotCore/Include/CmFontRTTI.h

@@ -0,0 +1,75 @@
+#pragma once
+
+#include "CmPrerequisites.h"
+#include "CmRTTIType.h"
+#include "CmFont.h"
+#include "CmFontManager.h"
+#include "CmTexture.h"
+
+namespace CamelotEngine
+{
+	class CM_EXPORT FontRTTI : public RTTIType<Font, Resource, FontRTTI>
+	{
+	private:
+		FONT_DESC& getFontDesc(Font* obj)
+		{
+			return obj->mFontDesc;
+		}
+
+		void setFontDesc(Font* obj, FONT_DESC& val)
+		{
+			obj->mFontDesc = val;
+		}
+
+		TexturePtr getTexture(Font* obj, UINT32 idx)
+		{
+			return obj->mTexturePages.at(idx);
+		}
+
+		void setTexture(Font* obj, UINT32 idx, TexturePtr value)
+		{
+			obj->mTexturePages[idx] = value;
+		}
+
+		UINT32 getTextureArraySize(Font* obj)
+		{
+			return (UINT32)obj->mTexturePages.size();
+		}
+
+		void setTextureArraySize(Font* obj, UINT32 size)
+		{
+			obj->mTexturePages.resize(size);
+		}
+
+	public:
+		FontRTTI()
+		{
+			addPlainField("mFontDesc", 0, &FontRTTI::getFontDesc, &FontRTTI::setFontDesc);
+			addReflectablePtrArrayField("mTexturePages", 1, &FontRTTI::getTexture, &FontRTTI::getTextureArraySize, &FontRTTI::setTexture, &FontRTTI::setTextureArraySize);
+		}
+
+		virtual const String& getRTTIName()
+		{
+			static String name = "Font";
+			return name;
+		}
+
+		virtual UINT32 getRTTIId()
+		{
+			return TID_Font;
+		}
+
+		virtual std::shared_ptr<IReflectable> newRTTIObject()
+		{
+			return FontManager::instance().createEmpty();
+		}
+
+	protected:
+		virtual void onDeserializationEnded(IReflectable* obj)
+		{
+			Font* font = static_cast<Font*>(obj);
+			
+			//font->initialize();
+		}
+	};
+}

+ 11 - 1
CamelotCore/Include/CmPrerequisites.h

@@ -129,6 +129,7 @@ namespace CamelotEngine {
 	class PassParameters;
 	class PassParameters;
 	class AsyncOp;
 	class AsyncOp;
 	class HardwareBufferManager;
 	class HardwareBufferManager;
+	class FontManager;
 	class CommandQueue;
 	class CommandQueue;
 	class DeferredRenderContext;
 	class DeferredRenderContext;
 	class DepthStencilState;
 	class DepthStencilState;
@@ -153,6 +154,7 @@ namespace CamelotEngine {
 	class Resources;
 	class Resources;
 	class Texture;
 	class Texture;
 	class Mesh;
 	class Mesh;
+	class Font;
 	// Scene
 	// Scene
 	class GameObject;
 	class GameObject;
 	class Component;
 	class Component;
@@ -166,6 +168,7 @@ namespace CamelotEngine {
 	struct BLEND_STATE_DESC;
 	struct BLEND_STATE_DESC;
 	struct RENDER_TARGET_BLEND_STATE_DESC;
 	struct RENDER_TARGET_BLEND_STATE_DESC;
 	struct RENDER_TEXTURE_DESC;
 	struct RENDER_TEXTURE_DESC;
+	struct FONT_DESC;
 }
 }
 
 
 /************************************************************************/
 /************************************************************************/
@@ -212,6 +215,7 @@ namespace CamelotEngine
 	typedef std::shared_ptr<GpuProgInclude> GpuProgIncludePtr;
 	typedef std::shared_ptr<GpuProgInclude> GpuProgIncludePtr;
 	typedef std::shared_ptr<ImportOptions> ImportOptionsPtr;
 	typedef std::shared_ptr<ImportOptions> ImportOptionsPtr;
 	typedef std::shared_ptr<const ImportOptions> ConstImportOptionsPtr;
 	typedef std::shared_ptr<const ImportOptions> ConstImportOptionsPtr;
+	typedef std::shared_ptr<Font> FontPtr;
 }
 }
 
 
 /************************************************************************/
 /************************************************************************/
@@ -260,7 +264,12 @@ namespace CamelotEngine
 		TID_SHADER_PARAM_BLOCK_DESC = 1047,
 		TID_SHADER_PARAM_BLOCK_DESC = 1047,
 		TID_ImportOptions = 1048,
 		TID_ImportOptions = 1048,
 		TID_GpuProgramImportOptions = 1049,
 		TID_GpuProgramImportOptions = 1049,
-		TID_MaterialParamStruct = 1050
+		TID_MaterialParamStruct = 1050,
+		TID_Font = 1051,
+		TID_FONT_DESC = 1052,
+		TID_CHAR_DESC = 1053,
+		TID_STDVECTOR = 1054,
+		TID_STDMAP = 1055
 	};
 	};
 
 
 	/**
 	/**
@@ -307,6 +316,7 @@ namespace CamelotEngine
 	typedef ResourceHandle<DepthStencilState> DepthStencilStateHandle;
 	typedef ResourceHandle<DepthStencilState> DepthStencilStateHandle;
 	typedef ResourceHandle<BlendState> BlendStateHandle;
 	typedef ResourceHandle<BlendState> BlendStateHandle;
 	typedef ResourceHandle<GpuProgInclude> GpuProgIncludeHandle;
 	typedef ResourceHandle<GpuProgInclude> GpuProgIncludeHandle;
+	typedef ResourceHandle<Font> FontHandle;
 }
 }
 
 
 #endif
 #endif

+ 15 - 9
CamelotCore/Include/CmShaderRTTI.h

@@ -11,7 +11,7 @@ namespace CamelotEngine
 	{	
 	{	
 		enum { id = TID_SHADER_DATA_PARAM_DESC }; enum { hasDynamicSize = 1 };
 		enum { id = TID_SHADER_DATA_PARAM_DESC }; enum { hasDynamicSize = 1 };
 
 
-		static void toMemory(SHADER_DATA_PARAM_DESC& data, char* memory)
+		static void toMemory(const SHADER_DATA_PARAM_DESC& data, char* memory)
 		{ 
 		{ 
 			UINT32 size = getDynamicSize(data);
 			UINT32 size = getDynamicSize(data);
 
 
@@ -27,7 +27,7 @@ namespace CamelotEngine
 			memory = rttiWriteElem(data.elementSize, memory);
 			memory = rttiWriteElem(data.elementSize, memory);
 		}
 		}
 
 
-		static void fromMemory(SHADER_DATA_PARAM_DESC& data, char* memory)
+		static UINT32 fromMemory(SHADER_DATA_PARAM_DESC& data, char* memory)
 		{ 
 		{ 
 			UINT32 size;
 			UINT32 size;
 			memcpy(&size, memory, sizeof(UINT32)); 
 			memcpy(&size, memory, sizeof(UINT32)); 
@@ -39,9 +39,11 @@ namespace CamelotEngine
 			memory = rttiReadElem(data.name, memory);
 			memory = rttiReadElem(data.name, memory);
 			memory = rttiReadElem(data.gpuVariableName, memory);
 			memory = rttiReadElem(data.gpuVariableName, memory);
 			memory = rttiReadElem(data.elementSize, memory);
 			memory = rttiReadElem(data.elementSize, memory);
+
+			return size;
 		}
 		}
 
 
-		static UINT32 getDynamicSize(SHADER_DATA_PARAM_DESC& data)	
+		static UINT32 getDynamicSize(const SHADER_DATA_PARAM_DESC& data)	
 		{ 
 		{ 
 			UINT64 dataSize = rttiGetElemSize(data.arraySize) + rttiGetElemSize(data.hidden) + rttiGetElemSize(data.type) + 
 			UINT64 dataSize = rttiGetElemSize(data.arraySize) + rttiGetElemSize(data.hidden) + rttiGetElemSize(data.type) + 
 				rttiGetElemSize(data.name) + rttiGetElemSize(data.gpuVariableName) + rttiGetElemSize(data.elementSize) + sizeof(UINT32);
 				rttiGetElemSize(data.name) + rttiGetElemSize(data.gpuVariableName) + rttiGetElemSize(data.elementSize) + sizeof(UINT32);
@@ -61,7 +63,7 @@ namespace CamelotEngine
 	{	
 	{	
 		enum { id = TID_SHADER_OBJECT_PARAM_DESC }; enum { hasDynamicSize = 1 };
 		enum { id = TID_SHADER_OBJECT_PARAM_DESC }; enum { hasDynamicSize = 1 };
 
 
-		static void toMemory(SHADER_OBJECT_PARAM_DESC& data, char* memory)
+		static void toMemory(const SHADER_OBJECT_PARAM_DESC& data, char* memory)
 		{ 
 		{ 
 			UINT32 size = getDynamicSize(data);
 			UINT32 size = getDynamicSize(data);
 
 
@@ -75,7 +77,7 @@ namespace CamelotEngine
 			memory = rttiWriteElem(data.gpuVariableName, memory);
 			memory = rttiWriteElem(data.gpuVariableName, memory);
 		}
 		}
 
 
-		static void fromMemory(SHADER_OBJECT_PARAM_DESC& data, char* memory)
+		static UINT32 fromMemory(SHADER_OBJECT_PARAM_DESC& data, char* memory)
 		{ 
 		{ 
 			UINT32 size;
 			UINT32 size;
 			memcpy(&size, memory, sizeof(UINT32)); 
 			memcpy(&size, memory, sizeof(UINT32)); 
@@ -85,9 +87,11 @@ namespace CamelotEngine
 			memory = rttiReadElem(data.type, memory);
 			memory = rttiReadElem(data.type, memory);
 			memory = rttiReadElem(data.name, memory);
 			memory = rttiReadElem(data.name, memory);
 			memory = rttiReadElem(data.gpuVariableName, memory);
 			memory = rttiReadElem(data.gpuVariableName, memory);
+
+			return size;
 		}
 		}
 
 
-		static UINT32 getDynamicSize(SHADER_OBJECT_PARAM_DESC& data)	
+		static UINT32 getDynamicSize(const SHADER_OBJECT_PARAM_DESC& data)	
 		{ 
 		{ 
 			UINT64 dataSize = rttiGetElemSize(data.hidden) + rttiGetElemSize(data.type) + 
 			UINT64 dataSize = rttiGetElemSize(data.hidden) + rttiGetElemSize(data.type) + 
 				rttiGetElemSize(data.name) + rttiGetElemSize(data.gpuVariableName) + sizeof(UINT32);
 				rttiGetElemSize(data.name) + rttiGetElemSize(data.gpuVariableName) + sizeof(UINT32);
@@ -107,7 +111,7 @@ namespace CamelotEngine
 	{	
 	{	
 		enum { id = TID_SHADER_PARAM_BLOCK_DESC }; enum { hasDynamicSize = 1 };
 		enum { id = TID_SHADER_PARAM_BLOCK_DESC }; enum { hasDynamicSize = 1 };
 
 
-		static void toMemory(SHADER_PARAM_BLOCK_DESC& data, char* memory)
+		static void toMemory(const SHADER_PARAM_BLOCK_DESC& data, char* memory)
 		{ 
 		{ 
 			UINT32 size = getDynamicSize(data);
 			UINT32 size = getDynamicSize(data);
 
 
@@ -120,7 +124,7 @@ namespace CamelotEngine
 			memory = rttiWriteElem(data.name, memory);
 			memory = rttiWriteElem(data.name, memory);
 		}
 		}
 
 
-		static void fromMemory(SHADER_PARAM_BLOCK_DESC& data, char* memory)
+		static UINT32 fromMemory(SHADER_PARAM_BLOCK_DESC& data, char* memory)
 		{ 
 		{ 
 			UINT32 size;
 			UINT32 size;
 			memcpy(&size, memory, sizeof(UINT32)); 
 			memcpy(&size, memory, sizeof(UINT32)); 
@@ -129,9 +133,11 @@ namespace CamelotEngine
 			memory = rttiReadElem(data.shared, memory);
 			memory = rttiReadElem(data.shared, memory);
 			memory = rttiReadElem(data.usage, memory);
 			memory = rttiReadElem(data.usage, memory);
 			memory = rttiReadElem(data.name, memory);
 			memory = rttiReadElem(data.name, memory);
+
+			return size;
 		}
 		}
 
 
-		static UINT32 getDynamicSize(SHADER_PARAM_BLOCK_DESC& data)	
+		static UINT32 getDynamicSize(const SHADER_PARAM_BLOCK_DESC& data)	
 		{ 
 		{ 
 			UINT64 dataSize = rttiGetElemSize(data.shared) + rttiGetElemSize(data.usage) + 
 			UINT64 dataSize = rttiGetElemSize(data.shared) + rttiGetElemSize(data.usage) + 
 				rttiGetElemSize(data.name) + sizeof(UINT32);
 				rttiGetElemSize(data.name) + sizeof(UINT32);

+ 0 - 0
CamelotCore/Include/CmTextRenderer.h


+ 4 - 0
CamelotCore/Source/CmApplication.cpp

@@ -24,6 +24,7 @@
 #include "CmRendererManager.h"
 #include "CmRendererManager.h"
 #include "CmMeshManager.h"
 #include "CmMeshManager.h"
 #include "CmMaterialManager.h"
 #include "CmMaterialManager.h"
+#include "CmFontManager.h"
 #include "CmRenderer.h"
 #include "CmRenderer.h"
 #include "CmDeferredRenderContext.h"
 #include "CmDeferredRenderContext.h"
 
 
@@ -77,6 +78,8 @@ namespace CamelotEngine
 
 
 		MeshManager::startUp(new MeshManager());
 		MeshManager::startUp(new MeshManager());
 		MaterialManager::startUp(new MaterialManager());
 		MaterialManager::startUp(new MaterialManager());
+		FontManager::startUp(new FontManager());
+
 		Importer::startUp(new Importer());
 		Importer::startUp(new Importer());
 		loadPlugin("CamelotFreeImgImporter"); // TODO - Load this automatically somehow
 		loadPlugin("CamelotFreeImgImporter"); // TODO - Load this automatically somehow
 		loadPlugin("CamelotFBXImporter"); // TODO - Load this automatically somehow
 		loadPlugin("CamelotFBXImporter"); // TODO - Load this automatically somehow
@@ -146,6 +149,7 @@ namespace CamelotEngine
 		mPrimaryRenderWindow = nullptr;
 		mPrimaryRenderWindow = nullptr;
 
 
 		Importer::shutDown();
 		Importer::shutDown();
+		FontManager::shutDown();
 		MaterialManager::shutDown();
 		MaterialManager::shutDown();
 		MeshManager::shutDown();
 		MeshManager::shutDown();
 
 

+ 41 - 0
CamelotCore/Source/CmFont.cpp

@@ -0,0 +1,41 @@
+#include "CmFont.h"
+#include "CmFontRTTI.h"
+#include "CmFontManager.h"
+
+namespace CamelotEngine
+{
+	Font::Font()
+	{
+
+	}
+
+	Font::~Font()
+	{
+
+	}
+
+	void Font::initialize(const FONT_DESC& fontDesc, vector<TexturePtr>::type texturePages)
+	{
+		mFontDesc = fontDesc;
+		mTexturePages = texturePages;
+
+		Resource::initialize();
+	}
+
+	FontHandle Font::create(const FONT_DESC& fontDesc, vector<TexturePtr>::type texturePages)
+	{
+		FontPtr newFont = FontManager::instance().create(fontDesc, texturePages);
+
+		return Resource::_createResourceHandle(newFont);
+	}
+
+	RTTITypeBase* Font::getRTTIStatic()
+	{
+		return FontRTTI::instance();
+	}
+
+	RTTITypeBase* Font::getRTTI() const
+	{
+		return Font::getRTTIStatic();
+	}
+}

+ 22 - 0
CamelotCore/Source/CmFontManager.cpp

@@ -0,0 +1,22 @@
+#include "CmFontManager.h"
+#include "CmFont.h"
+
+namespace CamelotEngine
+{
+	FontPtr FontManager::create(const FONT_DESC& fontDesc, vector<TexturePtr>::type texturePages) const
+	{
+		FontPtr newFont(new Font(), &CoreGpuObject::_deleteDelayed);
+		newFont->setThisPtr(newFont);
+		newFont->initialize(fontDesc, texturePages);
+
+		return newFont;
+	}
+
+	FontPtr FontManager::createEmpty() const
+	{
+		FontPtr newFont(new Font(), &CoreGpuObject::_deleteDelayed);
+		newFont->setThisPtr(newFont);
+
+		return newFont;
+	}
+}

+ 3 - 0
CamelotFontImporter/Source/CmFontImporter.cpp

@@ -1,5 +1,8 @@
 #include "CmFontImporter.h"
 #include "CmFontImporter.h"
 
 
+#include <ft2build.h>
+#include FT_FREETYPE_H
+
 namespace CamelotEngine
 namespace CamelotEngine
 {
 {
 	FontImporter::FontImporter()
 	FontImporter::FontImporter()

+ 125 - 9
CamelotUtility/Include/CmRTTIPrerequisites.h

@@ -11,7 +11,7 @@ namespace CamelotEngine
 	*			otherwise sizeof() is used.
 	*			otherwise sizeof() is used.
 	 */
 	 */
 	template<class ElemType>
 	template<class ElemType>
-	UINT32 rttiGetElemSize(ElemType& data)
+	UINT32 rttiGetElemSize(const ElemType& data)
 	{
 	{
 		if(RTTIPlainType<ElemType>::hasDynamicSize == 1)
 		if(RTTIPlainType<ElemType>::hasDynamicSize == 1)
 			return RTTIPlainType<ElemType>::getDynamicSize(data);
 			return RTTIPlainType<ElemType>::getDynamicSize(data);
@@ -27,7 +27,7 @@ namespace CamelotEngine
 	 *			bytes written and returns pointer to new memory.
 	 *			bytes written and returns pointer to new memory.
 	 */
 	 */
 	template<class ElemType>
 	template<class ElemType>
-	char* rttiWriteElem(ElemType& data, char* memory)
+	char* rttiWriteElem(const ElemType& data, char* memory)
 	{
 	{
 		RTTIPlainType<ElemType>::toMemory(data, memory);
 		RTTIPlainType<ElemType>::toMemory(data, memory);
 
 
@@ -59,17 +59,18 @@ namespace CamelotEngine
 		enum { id = 0 }; 
 		enum { id = 0 }; 
 		enum { hasDynamicSize = 0 };
 		enum { hasDynamicSize = 0 };
 
 
-		static void toMemory(T& data, char* memory)	
+		static void toMemory(const T& data, char* memory)	
 		{ 
 		{ 
 			memcpy(memory, &data, sizeof(T)); 
 			memcpy(memory, &data, sizeof(T)); 
 		}
 		}
 
 
-		static void fromMemory(T& data, char* memory)
+		static UINT32 fromMemory(T& data, char* memory)
 		{
 		{
 			memcpy(&data, memory, sizeof(T)); 
 			memcpy(&data, memory, sizeof(T)); 
+			return sizeof(T);
 		}
 		}
 
 
-		static UINT32 getDynamicSize(T& data)
+		static UINT32 getDynamicSize(const T& data)
 		{ 
 		{ 
 			assert(false); 
 			assert(false); 
 			return sizeof(T);
 			return sizeof(T);
@@ -79,11 +80,126 @@ namespace CamelotEngine
 #define CM_ALLOW_MEMCPY_SERIALIZATION(type)				\
 #define CM_ALLOW_MEMCPY_SERIALIZATION(type)				\
 	template<> struct RTTIPlainType<##type##>			\
 	template<> struct RTTIPlainType<##type##>			\
 	{	enum { id=0 }; enum { hasDynamicSize = 0 };		\
 	{	enum { id=0 }; enum { hasDynamicSize = 0 };		\
-	static void toMemory(##type##& data, char* memory)		\
+	static void toMemory(const type& data, char* memory)	\
 	{ memcpy(memory, &data, sizeof(##type##)); }			\
 	{ memcpy(memory, &data, sizeof(##type##)); }			\
-	static void fromMemory(##type##& data, char* memory)	\
-	{ memcpy(&data, memory, sizeof(##type##)); }			\
-	static UINT32 getDynamicSize(##type##& data)			\
+	static UINT32 fromMemory(##type##& data, char* memory)	\
+	{ memcpy(&data, memory, sizeof(##type##)); return sizeof(##type##); }			\
+	static UINT32 getDynamicSize(const type& data)		\
 	{ assert(false); return sizeof(##type##); }				\
 	{ assert(false); return sizeof(##type##); }				\
 	}; 
 	}; 
+
+	// RTTI types for some standard classes
+	template<class T> struct RTTIPlainType<std::vector<T>>
+	{	
+		enum { id = TID_STDVECTOR }; enum { hasDynamicSize = 1 };
+
+		static void toMemory(const std::vector<T>& data, char* memory)
+		{ 
+			UINT32 size = (UINT32)data.size();
+
+			memcpy(memory, &size, sizeof(UINT32));
+			memory += sizeof(UINT32);
+
+			for(auto iter = data.begin(); iter != data.end(); ++iter)
+			{
+				UINT32 elementSize = RTTIPlainType<T>::getDynamicSize(*iter);
+				RTTIPlainType<T>::toMemory(*iter, memory);
+
+				memory += elementSize;
+			}
+		}
+
+		static UINT32 fromMemory(std::vector<T>& data, char* memory)
+		{ 
+			UINT32 size;
+			memcpy(&size, memory, sizeof(UINT32)); 
+			memory += sizeof(UINT32);
+
+			for(UINT32 i = 0; i < size; i++)
+			{
+				T element;
+				UINT32 elementSize = RTTIPlainType<T>::fromMemory(element, memory);
+				data.push_back(element);
+
+				memory += elementSize;
+			}
+
+			return size;
+		}
+
+		static UINT32 getDynamicSize(const std::vector<T>& data)	
+		{ 
+			UINT64 dataSize = sizeof(UINT32);
+
+			for(auto iter = data.begin(); iter != data.end(); ++iter)
+				dataSize += RTTIPlainType<T>::getDynamicSize(*iter);		
+
+			assert(dataSize <= std::numeric_limits<UINT32>::max());
+
+			return (UINT32)dataSize;
+		}	
+	}; 
+
+	template<class Key, class Value> struct RTTIPlainType<std::map<Key, Value>>
+	{	
+		enum { id = TID_STDMAP }; enum { hasDynamicSize = 1 };
+
+		static void toMemory(const std::map<Key, Value>& data, char* memory)
+		{ 
+			UINT32 size = (UINT32)data.size();
+
+			memcpy(memory, &size, sizeof(UINT32));
+			memory += sizeof(UINT32);
+
+			for(auto iter = data.begin(); iter != data.end(); ++iter)
+			{
+				UINT32 keySize = RTTIPlainType<Key>::getDynamicSize(iter->first);
+				RTTIPlainType<Key>::toMemory(iter->first, memory);
+
+				memory += keySize;
+
+				UINT32 valueSize = RTTIPlainType<Value>::getDynamicSize(iter->second);
+				RTTIPlainType<Value>::toMemory(iter->second, memory);
+
+				memory += valueSize;
+			}
+		}
+
+		static UINT32 fromMemory(std::map<Key, Value>& data, char* memory)
+		{ 
+			UINT32 size;
+			memcpy(&size, memory, sizeof(UINT32)); 
+			memory += sizeof(UINT32);
+
+			for(UINT32 i = 0; i < size; i++)
+			{
+				Key key;
+				UINT32 keySize = RTTIPlainType<Key>::fromMemory(key, memory);
+				memory += keySize;
+
+				Value value;
+				UINT32 valueSize = RTTIPlainType<Value>::fromMemory(value, memory);
+				memory += valueSize;
+
+				data[key] = value; 
+			}
+
+			return size;
+		}
+
+		static UINT32 getDynamicSize(const std::map<Key, Value>& data)	
+		{ 
+			UINT64 dataSize = sizeof(UINT32);
+
+			for(auto iter = data.begin(); iter != data.end(); ++iter)
+			{
+				dataSize += RTTIPlainType<Key>::getDynamicSize(iter->first);		
+				dataSize += RTTIPlainType<Value>::getDynamicSize(iter->second);
+			}
+
+			assert(dataSize <= std::numeric_limits<UINT32>::max());
+
+			return (UINT32)dataSize;
+		}	
+	}; 
 }
 }

+ 9 - 7
CamelotUtility/Include/CmString.h

@@ -365,7 +365,7 @@ namespace CamelotEngine {
 	{	
 	{	
 		enum { id = 20 }; enum { hasDynamicSize = 1 };
 		enum { id = 20 }; enum { hasDynamicSize = 1 };
 
 
-		static void toMemory(String& data, char* memory)
+		static void toMemory(const String& data, char* memory)
 		{ 
 		{ 
 			UINT32 size = getDynamicSize(data);
 			UINT32 size = getDynamicSize(data);
 
 
@@ -375,22 +375,24 @@ namespace CamelotEngine {
 			memcpy(memory, data.data(), size); 
 			memcpy(memory, data.data(), size); 
 		}
 		}
 
 
-		static void fromMemory(String& data, char* memory)
+		static UINT32 fromMemory(String& data, char* memory)
 		{ 
 		{ 
 			UINT32 size;
 			UINT32 size;
 			memcpy(&size, memory, sizeof(UINT32)); 
 			memcpy(&size, memory, sizeof(UINT32)); 
 			memory += sizeof(UINT32);
 			memory += sizeof(UINT32);
 
 
-			size -= sizeof(UINT32);
-			char* buffer = new char[size + 1]; // TODO - Use a better allocator
-			memcpy(buffer, memory, size); 
-			buffer[size] = '\0';
+			UINT32 stringSize = size - sizeof(UINT32);
+			char* buffer = new char[stringSize + 1]; // TODO - Use a better allocator
+			memcpy(buffer, memory, stringSize); 
+			buffer[stringSize] = '\0';
 			data = String(buffer);
 			data = String(buffer);
 
 
 			delete[] buffer; 
 			delete[] buffer; 
+
+			return size;
 		}
 		}
 
 
-		static UINT32 getDynamicSize(String& data)	
+		static UINT32 getDynamicSize(const String& data)	
 		{ 
 		{ 
 			UINT64 dataSize = data.size() * sizeof(String::value_type) + sizeof(UINT32);
 			UINT64 dataSize = data.size() * sizeof(String::value_type) + sizeof(UINT32);
 
 

+ 4 - 0
Dependencies.txt

@@ -21,6 +21,10 @@ CamelotFreeImgImporter (optional) relies on:
  - FreeImage 3.13.1
  - FreeImage 3.13.1
   - http://freeimage.sourceforge.net
   - http://freeimage.sourceforge.net
 
 
+CamelotFontImporter (optional) relies on:
+ - Freetype 2.3.5
+  - http://www.freetype.org
+
 Place plug-in specific dependency files in:
 Place plug-in specific dependency files in:
  - Library include files in (CamelotRootDir)/(PluginDir)/Dependencies/Include
  - Library include files in (CamelotRootDir)/(PluginDir)/Dependencies/Include
  - Static library files in (CamelotRootDir)/(PluginDir)/Dependencies/lib/(Platform)/(Configuration)
  - Static library files in (CamelotRootDir)/(PluginDir)/Dependencies/lib/(Platform)/(Configuration)

+ 24 - 0
TODO.txt

@@ -7,6 +7,30 @@
    - Frustum culling and octree (or some other) acceleration structure
    - Frustum culling and octree (or some other) acceleration structure
    - Render queue and sorting
    - Render queue and sorting
 
 
+----------------------- CAMELOT 2D / GUI -----------------------------------------------------------
+
+Figure out how to initialize material/font/etc without going to render thread
+ - Rename CoreGpuObject to CoreObject
+  - initialize_internal->initializeGpuData
+  - destroy_internal->destroyGpuData
+  - add a bit-flag "requiresGpuInitialization"
+Figure out how to store texture references in a font?
+ - Currently I store a copy of the textures but how do I automatically update the font if they change?
+ - Flesh out the dependencies system?
+ - I can import texture as normal, and keep it as an actual TextureHandle, only keep it hidden
+   if it was created automatically (by FontImporter) for example?
+    - But then who deletes the texture?
+	- Set up an "internalResource" system where resources hold references to each other and also release them?
+	 - In inspector they can be expanded as children of the main resource, but cannot be directly modified?
+	 - Deleting the main resource deletes the children too
+
+
+ Can I make RTTIPlainType for vector?
+ FontRTTI doesn't properly initialize or serialize FontDesc
+ FontDEsc doesn't have RTTIPlainType defined
+
+ Names: TextMesh & SpriteMesh instead of 2DText and 2DSprite!
+
 -----------------------IMMEDIATE TODO---------------------------------------------------------------
 -----------------------IMMEDIATE TODO---------------------------------------------------------------
 
 
  Assets manifest
  Assets manifest