Browse Source

Massive amount of bugfixes to the way how are resources serialized/deserialized, initialized and released

Marko Pintera 13 years ago
parent
commit
7b80bdaff7
41 changed files with 370 additions and 276 deletions
  1. 84 77
      CamelotClient/CamelotClient.cpp
  2. 8 0
      CamelotD3D11RenderSystem/Source/CmD3D11HLSLProgram.cpp
  3. 20 4
      CamelotD3D11RenderSystem/Source/CmD3D11RenderStateManager.cpp
  4. 3 0
      CamelotD3D11RenderSystem/Source/CmD3D11RenderSystem.cpp
  5. 7 3
      CamelotD3D11RenderSystem/Source/CmD3D11RenderWindow.cpp
  6. 3 3
      CamelotD3D9Renderer/Source/CmD3D9Texture.cpp
  7. 1 1
      CamelotFBXImporter/Include/CmFBXImporter.h
  8. 3 5
      CamelotFBXImporter/Source/CmFBXImporter.cpp
  9. 1 1
      CamelotFreeImgImporter/Include/CmFreeImgImporter.h
  10. 4 6
      CamelotFreeImgImporter/Source/CmFreeImgImporter.cpp
  11. 11 20
      CamelotGLRenderer/Include/CmGLGpuProgramManager.h
  12. 2 17
      CamelotGLRenderer/Source/CmGLGpuProgramManager.cpp
  13. 3 3
      CamelotGLRenderer/Source/CmGLTexture.cpp
  14. 17 14
      CamelotGLRenderer/Source/GLSL/include/CmGLSLGpuProgram.h
  15. 4 5
      CamelotGLRenderer/Source/GLSL/src/CmGLSLGpuProgram.cpp
  16. 10 6
      CamelotGLRenderer/Source/GLSL/src/CmGLSLProgram.cpp
  17. 5 0
      CamelotRenderer.sln
  18. 1 1
      CamelotRenderer/Include/CmCoreGpuObject.h
  19. 1 1
      CamelotRenderer/Include/CmImporter.h
  20. 7 1
      CamelotRenderer/Include/CmMeshDataRTTI.h
  21. 2 0
      CamelotRenderer/Include/CmRenderStateManager.h
  22. 24 21
      CamelotRenderer/Include/CmResourceHandle.h
  23. 8 14
      CamelotRenderer/Include/CmResources.h
  24. 1 7
      CamelotRenderer/Include/CmSpecificImporter.h
  25. 5 2
      CamelotRenderer/Include/CmTextureRTTI.h
  26. 2 1
      CamelotRenderer/Include/CmVertexDeclarationRTTI.h
  27. 11 6
      CamelotRenderer/Source/CmCoreGpuObject.cpp
  28. 1 0
      CamelotRenderer/Source/CmHighLevelGpuProgram.cpp
  29. 2 2
      CamelotRenderer/Source/CmImporter.cpp
  30. 40 4
      CamelotRenderer/Source/CmMesh.cpp
  31. 2 0
      CamelotRenderer/Source/CmMeshData.cpp
  32. 1 7
      CamelotRenderer/Source/CmMeshRTTI.h
  33. 15 0
      CamelotRenderer/Source/CmRenderStateManager.cpp
  34. 7 17
      CamelotRenderer/Source/CmResources.cpp
  35. 0 4
      CamelotRenderer/Source/CmSpecificImporter.cpp
  36. 3 3
      CamelotRenderer/Source/CmTexture.cpp
  37. 12 0
      CamelotRenderer/TODO.txt
  38. 7 0
      CamelotUtility/Include/CmBinarySerializer.h
  39. 1 1
      CamelotUtility/Include/CmMath.h
  40. 5 1
      CamelotUtility/Include/CmPixelDataRTTI.h
  41. 26 18
      CamelotUtility/Source/CmBinarySerializer.cpp

+ 84 - 77
CamelotClient/CamelotClient.cpp

@@ -32,8 +32,8 @@ int CALLBACK WinMain(
 	_In_  int nCmdShow
 	)
 {
-	//gApplication().startUp("CamelotGLRenderSystem", "CamelotForwardRenderer");
-	gApplication().startUp("CamelotD3D9RenderSystem", "CamelotForwardRenderer");
+	gApplication().startUp("CamelotGLRenderSystem", "CamelotForwardRenderer");
+	//gApplication().startUp("CamelotD3D9RenderSystem", "CamelotForwardRenderer");
 	//gApplication().startUp("CamelotD3D11RenderSystem", "CamelotForwardRenderer");
 
 	RenderSystem* renderSystem = RenderSystem::instancePtr();
@@ -57,27 +57,27 @@ int CALLBACK WinMain(
 	HighLevelGpuProgramPtr vertProg;
 
 	/////////////////// HLSL 9 SHADERS //////////////////////////
-	String fragShaderCode = "sampler2D tex;			\
-							float4 ps_main(float2 uv : TEXCOORD0) : COLOR0		\
-							{														\
-							float4 color = tex2D(tex, uv);				\
-							return color;										\
-							}";
-
-	fragProg =  HighLevelGpuProgram::create(fragShaderCode, "ps_main", "hlsl", GPT_FRAGMENT_PROGRAM, GPP_PS_2_0);
-
-	String vertShaderCode = "float4x4 matViewProjection;	\
-							void vs_main(										\
-							float4 inPos : POSITION,							\
-							float2 uv : TEXCOORD0,								\
-							out float4 oPosition : POSITION,					\
-							out float2 oUv : TEXCOORD0)							\
-							{														\
-							oPosition = mul(matViewProjection, inPos);			\
-							oUv = uv;											\
-							}";
-
-	vertProg =  HighLevelGpuProgram::create(vertShaderCode, "vs_main", "hlsl", GPT_VERTEX_PROGRAM, GPP_VS_2_0);
+	//String fragShaderCode = "sampler2D tex;			\
+	//						float4 ps_main(float2 uv : TEXCOORD0) : COLOR0		\
+	//						{														\
+	//						float4 color = tex2D(tex, uv);				\
+	//						return color;										\
+	//						}";
+
+	//fragProg =  HighLevelGpuProgram::create(fragShaderCode, "ps_main", "hlsl", GPT_FRAGMENT_PROGRAM, GPP_PS_2_0);
+
+	//String vertShaderCode = "float4x4 matViewProjection;	\
+	//						void vs_main(										\
+	//						float4 inPos : POSITION,							\
+	//						float2 uv : TEXCOORD0,								\
+	//						out float4 oPosition : POSITION,					\
+	//						out float2 oUv : TEXCOORD0)							\
+	//						{														\
+	//						oPosition = mul(matViewProjection, inPos);			\
+	//						oUv = uv;											\
+	//						}";
+
+	//vertProg =  HighLevelGpuProgram::create(vertShaderCode, "vs_main", "hlsl", GPT_VERTEX_PROGRAM, GPP_VS_2_0);
 
 	/////////////////// HLSL 11 SHADERS //////////////////////////
 	//String fragShaderCode = "SamplerState samp : register(s0);			\
@@ -127,41 +127,39 @@ int CALLBACK WinMain(
 	//vertProg =  HighLevelGpuProgram::create(vertShaderCode, "vs_main", "cg", GPT_VERTEX_PROGRAM, GPP_VS_2_0);
 
 	///////////////// GLSL SHADERS ////////////////////////////
-	//String fragShaderCode = " #version 400 \n \
-	//						  uniform sampler2D tex; \
-	//						  in vec2 texcoord0; \
-	//						  out vec4 fragColor; \
-	//						  void main() \
-	//						  {\
-	//							  vec4 texColor = texture2D(tex, texcoord0.st);\
-	//							  fragColor = texColor; \
-	//						  }";
-
-	//fragProg = HighLevelGpuProgram::create(fragShaderCode, "main", "glsl", GPT_FRAGMENT_PROGRAM, GPP_PS_2_0);
-
-	//// TODO - Make sure to document the strict input parameter naming. (Exact supported names are in GLSLParamParser)
-	//String vertShaderCode = "#version 400 \n \
-	//						 uniform mainFragBlock { mat4 matViewProjection; }; \
-	//						 in vec4 cm_position; \
-	//						 in vec2 cm_texcoord0; \
-	//						 out vec2 texcoord0; \
-	//						 void main() \
-	//						 { \
-	//							texcoord0 = cm_texcoord0; \
-	//							gl_Position = cm_position * matViewProjection; \
-	//						 }";
-
-	//vertProg = HighLevelGpuProgram::create(vertShaderCode, "main", "glsl", GPT_VERTEX_PROGRAM, GPP_VS_2_0);
-
-	HighLevelGpuProgramHandle vertProgRef(vertProg);
-
-	gResources().create(vertProgRef, "C:\\vertProgCg.vprog", true);
-	vertProgRef = static_resource_cast<HighLevelGpuProgram>(gResources().load("C:\\vertProgCg.vprog"));
-
-	HighLevelGpuProgramHandle fragProgRef(fragProg);
-
-	gResources().create(fragProgRef, "C:\\fragProgCg.vprog", true);
-	fragProgRef = static_resource_cast<HighLevelGpuProgram>(gResources().load("C:\\fragProgCg.vprog"));
+	String fragShaderCode = " #version 400 \n \
+							  uniform sampler2D tex; \
+							  in vec2 texcoord0; \
+							  out vec4 fragColor; \
+							  void main() \
+							  {\
+								  vec4 texColor = texture2D(tex, texcoord0.st);\
+								  fragColor = texColor; \
+							  }";
+
+	fragProg = HighLevelGpuProgram::create(fragShaderCode, "main", "glsl", GPT_FRAGMENT_PROGRAM, GPP_PS_2_0);
+
+	// TODO - Make sure to document the strict input parameter naming. (Exact supported names are in GLSLParamParser)
+	String vertShaderCode = "#version 400 \n \
+							 uniform mainFragBlock { mat4 matViewProjection; }; \
+							 in vec4 cm_position; \
+							 in vec2 cm_texcoord0; \
+							 out vec2 texcoord0; \
+							 void main() \
+							 { \
+								texcoord0 = cm_texcoord0; \
+								gl_Position = cm_position * matViewProjection; \
+							 }";
+
+	vertProg = HighLevelGpuProgram::create(vertShaderCode, "main", "glsl", GPT_VERTEX_PROGRAM, GPP_VS_2_0);
+
+	HighLevelGpuProgramHandle vertProgRef = gResources().create(vertProg, "C:\\vertProgCg.vprog", true);
+	gResources().unload(vertProgRef);
+	vertProgRef = gResources().load("C:\\vertProgCg.vprog");
+
+	HighLevelGpuProgramHandle fragProgRef = gResources().create(fragProg, "C:\\fragProgCg.vprog", true);
+	gResources().unload(fragProgRef);
+	fragProgRef = gResources().load("C:\\fragProgCg.vprog");
 
 	ShaderPtr testShader = Shader::create("TestShader");
 	testShader->addParameter("matViewProjection", "matViewProjection", GPDT_MATRIX_4X4);
@@ -186,38 +184,43 @@ int CALLBACK WinMain(
 	newPassDX11->setVertexProgram(vertProgRef);
 	newPassDX11->setFragmentProgram(fragProgRef);
 
-	MaterialHandle testMaterial = Material::create();
-	testMaterial.waitUntilLoaded(); // TODO - Material doesn't do anything GPU specific, so technically it should be possible to initialize on the spot
+	MaterialPtr testMaterial = Material::create();
+	testMaterial->waitUntilInitialized(); // TODO - Material doesn't do anything GPU specific, so technically it should be possible to initialize on the spot
 	// but is that a good idea?
 	testMaterial->setShader(testShader);
 
 	testMaterial->setMat4("matViewProjection", Matrix4::IDENTITY);
 
-	gResources().create(testMaterial, "C:\\testMaterial.mat", true);
-	testMaterial = static_resource_cast<MaterialHandle>(gResources().load("C:\\testMaterial.mat"));
-	testMaterial.waitUntilLoaded();
+	MaterialHandle testMaterialRef = gResources().create(testMaterial, "C:\\testMaterial.mat", true);
+	//testMaterialRef = gResources().load("C:\\testMaterial.mat");
+	//testMaterialRef.waitUntilLoaded();
 
 	/*TextureRef testTex = static_resource_cast<Texture>(Importer::instance().import("C:\\ImportTest.tga"));*/
-	TextureHandle testTex = static_resource_cast<Texture>(Importer::instance().import("C:\\ArenaTowerDFS.psd"));
-	MeshHandle dbgMesh = static_resource_cast<Mesh>(Importer::instance().import("C:\\X_Arena_Tower.FBX"));
+	TexturePtr testTex = std::static_pointer_cast<Texture>(Importer::instance().import("C:\\ArenaTowerDFS.psd"));
+	MeshPtr dbgMesh = std::static_pointer_cast<Mesh>(Importer::instance().import("C:\\X_Arena_Tower.FBX"));
 
 	//int tmpFlag = _CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_CHECK_CRT_DF | _CRTDBG_DELAY_FREE_MEM_DF);
 
-	gResources().create(testTex, "C:\\ExportTest.tex", true);
-	gResources().create(dbgMesh, "C:\\ExportMesh.mesh", true);
+	TextureHandle testTexRef = gResources().create(testTex, "C:\\ExportTest.tex", true);
+	MeshHandle dbgMeshRef = gResources().create(dbgMesh, "C:\\ExportMesh.mesh", true);
+
+	gResources().unload(testTexRef);
+	gResources().unload(dbgMeshRef);
 
-	testTex = static_resource_cast<Texture>(gResources().load("C:\\ExportTest.tex"));
-	dbgMesh = static_resource_cast<Mesh>(gResources().load("C:\\ExportMesh.mesh"));
+	testTexRef = static_resource_cast<Texture>(gResources().load("C:\\ExportTest.tex"));
+	dbgMeshRef = static_resource_cast<Mesh>(gResources().load("C:\\ExportMesh.mesh"));
 
-	testMaterial->setTexture("tex", testTex);
+	testMaterial->setTexture("tex", testTexRef);
 	//gResources().create(testMaterial, "C:\\ExportMaterial.mat", true);
 
 	//testMaterial = gResources().load("C:\\ExportMaterial.mat");
 
 	//_ASSERT(_CrtCheckMemory());
 
-	testRenderable->setMesh(dbgMesh);
-	testRenderable->setMaterial(testMaterial);
+	//dbgMeshRef.waitUntilLoaded();
+
+	testRenderable->setMesh(dbgMeshRef);
+	testRenderable->setMaterial(testMaterialRef);
 
 	//// Set the new state for the flag
 	//_CrtSetDbgFlag( tmpFlag );
@@ -226,18 +229,21 @@ int CALLBACK WinMain(
 
 	// Release everything before shutdown
 	
-	testMaterial->destroy();
-	testMaterial.reset();
+	//testMaterial->destroy();
+	testMaterial = nullptr;
 
-	//gResources().unload(testMaterial);
-	gResources().unload(testTex);
-	gResources().unload(dbgMesh);
+	gResources().unload(testMaterialRef);
+	gResources().unload(testTexRef);
+	gResources().unload(dbgMeshRef);
 	gResources().unload(fragProgRef);
 	gResources().unload(vertProgRef);
 
 	fragProg = nullptr;
 	vertProg = nullptr;
 
+	testTex = nullptr;
+	dbgMesh = nullptr;
+
 	testModelGO->destroy();
 	testModelGO = nullptr;
 	testRenderable = nullptr;
@@ -256,6 +262,7 @@ int CALLBACK WinMain(
 	newPassDX11 = nullptr;
 	newTechniqueDX11 = nullptr;
 
+	testShader->destroy();
 	testShader = nullptr;
 	
 	renderWindow = nullptr;

+ 8 - 0
CamelotD3D11RenderSystem/Source/CmD3D11HLSLProgram.cpp

@@ -84,9 +84,17 @@ namespace CamelotEngine
 
     void D3D11HLSLProgram::destroy_internal()
 	{
+		if(mAssemblerProgram != nullptr)
+			mAssemblerProgram->destroy();
+
 		mAssemblerProgram = nullptr;
 		mMicrocode.clear();
 
+		if(mInputDeclaration != nullptr)
+			mInputDeclaration->destroy();
+
+		mInputDeclaration = nullptr;
+
 		HighLevelGpuProgram::destroy_internal();
 	}
 

+ 20 - 4
CamelotD3D11RenderSystem/Source/CmD3D11RenderStateManager.cpp

@@ -9,6 +9,7 @@ namespace CamelotEngine
 	SamplerStatePtr D3D11RenderStateManager::createSamplerState(const SAMPLER_STATE_DESC& desc) const
 	{
 		D3D11SamplerStatePtr samplerState = D3D11SamplerStatePtr(new D3D11SamplerState());
+		samplerState->setThisPtr(samplerState);
 		samplerState->initialize(desc);
 
 		return samplerState;
@@ -17,6 +18,7 @@ namespace CamelotEngine
 	DepthStencilStatePtr D3D11RenderStateManager::createDepthStencilState(const DEPTH_STENCIL_STATE_DESC& desc) const
 	{
 		D3D11DepthStencilStatePtr depthStencilState = D3D11DepthStencilStatePtr(new D3D11DepthStencilState());
+		depthStencilState->setThisPtr(depthStencilState);
 		depthStencilState->initialize(desc);
 
 		return depthStencilState;
@@ -25,6 +27,7 @@ namespace CamelotEngine
 	RasterizerStatePtr D3D11RenderStateManager::createRasterizerState(const RASTERIZER_STATE_DESC& desc) const
 	{
 		D3D11RasterizerStatePtr rasterizerState = D3D11RasterizerStatePtr(new D3D11RasterizerState());
+		rasterizerState->setThisPtr(rasterizerState);
 		rasterizerState->initialize(desc);
 
 		return rasterizerState;
@@ -33,6 +36,7 @@ namespace CamelotEngine
 	BlendStatePtr D3D11RenderStateManager::createBlendState(const BLEND_STATE_DESC& desc) const
 	{
 		D3D11BlendStatePtr blendState = D3D11BlendStatePtr(new D3D11BlendState());
+		blendState->setThisPtr(blendState);
 		blendState->initialize(desc);
 
 		return blendState;
@@ -40,21 +44,33 @@ namespace CamelotEngine
 
 	SamplerStatePtr D3D11RenderStateManager::createEmptySamplerState() const
 	{
-		return D3D11SamplerStatePtr(new D3D11SamplerState());
+		D3D11SamplerStatePtr samplerState(new D3D11SamplerState());
+		samplerState->setThisPtr(samplerState);
+
+		return samplerState;
 	}
 
 	DepthStencilStatePtr D3D11RenderStateManager::createEmptyDepthStencilState() const
 	{
-		return D3D11DepthStencilStatePtr(new D3D11DepthStencilState());
+		D3D11DepthStencilStatePtr depthStencilState(new D3D11DepthStencilState());
+		depthStencilState->setThisPtr(depthStencilState);
+
+		return depthStencilState;
 	}
 
 	RasterizerStatePtr D3D11RenderStateManager::createEmptyRasterizerState() const
 	{
-		return D3D11RasterizerStatePtr(new D3D11RasterizerState());
+		D3D11RasterizerStatePtr rasterizerState(new D3D11RasterizerState());
+		rasterizerState->setThisPtr(rasterizerState);
+
+		return rasterizerState;
 	}
 
 	BlendStatePtr D3D11RenderStateManager::createEmptyBlendState() const
 	{
-		return D3D11BlendStatePtr(new D3D11BlendState());
+		D3D11BlendStatePtr blendState(new D3D11BlendState());
+		blendState->setThisPtr(blendState);
+
+		return blendState;
 	}
 }

+ 3 - 0
CamelotD3D11RenderSystem/Source/CmD3D11RenderSystem.cpp

@@ -357,6 +357,9 @@ namespace CamelotEngine
 	{
 		THROW_IF_NOT_RENDER_THREAD;
 
+		if(!prg.isLoaded())
+			return;
+
 		switch(prg->getType())
 		{
 		case GPT_VERTEX_PROGRAM:

+ 7 - 3
CamelotD3D11RenderSystem/Source/CmD3D11RenderWindow.cpp

@@ -170,8 +170,6 @@ namespace CamelotEngine
 
 	void D3D11RenderWindow::destroy_internal()
 	{
-		_destroySizeDependedD3DResources();
-
 		mActive = false;
 		mClosed = true;
 
@@ -191,6 +189,8 @@ namespace CamelotEngine
 
 		mHWnd = nullptr;
 
+		_destroySizeDependedD3DResources();
+
 		RenderWindow::destroy_internal();
 	}
 
@@ -540,7 +540,11 @@ namespace CamelotEngine
 		SAFE_RELEASE(mBackBuffer);
 		SAFE_RELEASE(mRenderTargetView);
 
-		mDepthStencilBuffer = nullptr;
+		if(mDepthStencilBuffer != nullptr)
+		{
+			mDepthStencilBuffer->destroy();
+			mDepthStencilBuffer = nullptr;
+		}
 	}
 
 	void D3D11RenderWindow::_resizeSwapChainBuffers(unsigned width, unsigned height)

+ 3 - 3
CamelotD3D9Renderer/Source/CmD3D9Texture.cpp

@@ -69,9 +69,9 @@ namespace CamelotEngine
 		if(getUsage() == TU_DEPTHSTENCIL)
 			CM_EXCEPT(InternalErrorException, "Cannot lock a depth stencil texture.");
 
-		UINT32 mipWidth = mipLevel >> mWidth;
-		UINT32 mipHeight = mipLevel >> mHeight;
-		UINT32 mipDepth = mipLevel >> mDepth;
+		UINT32 mipWidth = mWidth >> mipLevel;
+		UINT32 mipHeight = mHeight >> mipLevel;
+		UINT32 mipDepth = mDepth >> mipLevel;
 
 		PixelData lockedArea(mipWidth, mipHeight, mipDepth, mFormat);
 

+ 1 - 1
CamelotFBXImporter/Include/CmFBXImporter.h

@@ -35,7 +35,7 @@ namespace CamelotEngine
 		virtual bool isMagicNumberSupported(const UINT8* magicNumPtr, UINT32 numBytes) const; 
 
 		/** Inherited from SpecificImporter */
-		virtual BaseResourceHandle import(const String& filePath);
+		virtual ResourcePtr import(const String& filePath);
 	private:
 		vector<String>::type mExtensions;
 

+ 3 - 5
CamelotFBXImporter/Source/CmFBXImporter.cpp

@@ -35,7 +35,7 @@ namespace CamelotEngine
 		return true; // FBX files can be plain-text so I don't even check for magic number
 	}
 
-	BaseResourceHandle FBXImporter::import(const String& filePath)
+	ResourcePtr FBXImporter::import(const String& filePath)
 	{
 		FbxManager* fbxManager = nullptr;
 		FbxScene* fbxScene = nullptr;
@@ -47,13 +47,11 @@ namespace CamelotEngine
 
 		shutDownSdk(fbxManager);
 
-		MeshHandle mesh = MeshHandle(Mesh::create());
+		MeshPtr mesh = Mesh::create();
 
-		mesh.waitUntilLoaded();
+		mesh->waitUntilInitialized();
 		mesh->setMeshData(meshData);
 
-		registerLoadedResource(mesh);
-
 		return mesh;
 	}
 

+ 1 - 1
CamelotFreeImgImporter/Include/CmFreeImgImporter.h

@@ -34,7 +34,7 @@ namespace CamelotEngine
 		virtual bool isMagicNumberSupported(const UINT8* magicNumPtr, UINT32 numBytes) const; 
 
 		/** Inherited from SpecificImporter */
-		virtual BaseResourceHandle import(const String& filePath);
+		virtual ResourcePtr import(const String& filePath);
 	private:
 		vector<String>::type mExtensions;
 		std::unordered_map<String, int> mExtensionToFID;

+ 4 - 6
CamelotFreeImgImporter/Source/CmFreeImgImporter.cpp

@@ -127,7 +127,7 @@ namespace CamelotEngine
 		}
 	}
 
-	BaseResourceHandle FreeImgImporter::import(const String& filePath)
+	ResourcePtr FreeImgImporter::import(const String& filePath)
 	{
 		DataStreamPtr fileData = FileSystem::open(filePath, true);
 
@@ -135,10 +135,10 @@ namespace CamelotEngine
 		if(imgData == nullptr || imgData->getData() == nullptr)
 			return nullptr;
 
-		TextureHandle newTexture(Texture::create(TEX_TYPE_2D, 
-			imgData->getWidth(), imgData->getHeight(), imgData->getNumMipmaps(), imgData->getFormat()));
+		TexturePtr newTexture = Texture::create(TEX_TYPE_2D, 
+			imgData->getWidth(), imgData->getHeight(), imgData->getNumMipmaps(), imgData->getFormat());
 
-		newTexture.waitUntilLoaded();
+		newTexture->waitUntilInitialized();
 
 		for(UINT32 mip = 0; mip <= imgData->getNumMipmaps(); ++mip)
 		{
@@ -149,8 +149,6 @@ namespace CamelotEngine
 
 		fileData->close();
 
-		registerLoadedResource(newTexture);
-
 		return newTexture;
 	}
 

+ 11 - 20
CamelotGLRenderer/Include/CmGLGpuProgramManager.h

@@ -32,27 +32,18 @@ THE SOFTWARE.
 #include "CmGLPrerequisites.h"
 #include "CmGpuProgramManager.h"
 
-namespace CamelotEngine {
-
-class CM_RSGL_EXPORT GLGpuProgramManager : public GpuProgramManager
+namespace CamelotEngine 
 {
-public:
-    typedef GpuProgram* (*CreateGpuProgramCallback)(const String& source, const String& entryPoint, const String& language, GpuProgramType gptype, GpuProgramProfile profile);
-
-private:
-    typedef map<String, CreateGpuProgramCallback>::type ProgramMap;
-    ProgramMap mProgramMap;
-
-protected:
-    /// Specialised create method with specific parameters
-    GpuProgram* create(const String& source, const String& entryPoint, const String& language, GpuProgramType gptype, GpuProgramProfile profile);
-
-public:
-    GLGpuProgramManager();
-    ~GLGpuProgramManager();
-    bool registerProgramFactory(const String& syntaxCode, CreateGpuProgramCallback createFn);
-    bool unregisterProgramFactory(const String& syntaxCode);
-};
+	class CM_RSGL_EXPORT GLGpuProgramManager : public GpuProgramManager
+	{
+		public:
+			GLGpuProgramManager();
+			~GLGpuProgramManager();
+
+		protected:
+			/// Specialised create method with specific parameters
+			GpuProgram* create(const String& source, const String& entryPoint, const String& language, GpuProgramType gptype, GpuProgramProfile profile);
+	};
 
 }; //namespace CamelotEngine
 

+ 2 - 17
CamelotGLRenderer/Source/CmGLGpuProgramManager.cpp

@@ -27,6 +27,7 @@ THE SOFTWARE.
 */
 
 #include "CmGLGpuProgramManager.h"
+#include "CmGLSLGpuProgram.h"
 #include "CmException.h"
 
 using namespace CamelotEngine;
@@ -40,24 +41,8 @@ GLGpuProgramManager::~GLGpuProgramManager()
 {
 }
 
-bool GLGpuProgramManager::registerProgramFactory(const String& syntaxCode, CreateGpuProgramCallback createFn)
-{
-    return mProgramMap.insert(ProgramMap::value_type(syntaxCode, createFn)).second;
-}
-
-bool GLGpuProgramManager::unregisterProgramFactory(const String& syntaxCode)
-{
-    return mProgramMap.erase(syntaxCode) != 0;
-}
-
 GpuProgram* GLGpuProgramManager::create(const String& source, const String& entryPoint, const String& language, GpuProgramType gptype, GpuProgramProfile profile)
 {
-    ProgramMap::const_iterator iter = mProgramMap.find(language);
-    if(iter == mProgramMap.end())
-    {
-        CM_EXCEPT(InternalErrorException, "Cannot find propery factory to create GpuProgram of type: " + language);
-    }
-    
-    return (iter->second)(source, entryPoint, language, gptype, profile);
+    return new GLSLGpuProgram(source, entryPoint, language, gptype, profile);
 }
 

+ 3 - 3
CamelotGLRenderer/Source/CmGLTexture.cpp

@@ -243,9 +243,9 @@ namespace CamelotEngine {
 		if(mLockedBuffer != nullptr)
 			CM_EXCEPT(InternalErrorException, "Trying to lock a buffer that's already locked.");
 
-		UINT32 mipWidth = mipLevel >> mWidth;
-		UINT32 mipHeight = mipLevel >> mHeight;
-		UINT32 mipDepth = mipLevel >> mDepth;
+		UINT32 mipWidth = mWidth >> mipLevel;
+		UINT32 mipHeight = mHeight >> mipLevel;
+		UINT32 mipDepth = mDepth >> mipLevel;
 
 		PixelData lockedArea(mipWidth, mipHeight, mipDepth, mFormat);
 

+ 17 - 14
CamelotGLRenderer/Source/GLSL/include/CmGLSLGpuProgram.h

@@ -46,7 +46,23 @@ namespace CamelotEngine {
 	*/
     class CM_RSGL_EXPORT GLSLGpuProgram : public GpuProgram
     {
-    private:
+	public:
+		~GLSLGpuProgram();
+
+		/// get the GLSLProgram for the shader object
+		GLSLProgram* getGLSLProgram(void) const { return mGLSLProgram; }
+
+		void setGLSLProgram(GLSLProgram* program) { mGLSLProgram = program; }
+		
+		/// Get the assigned GL program id
+		const UINT32 getProgramID(void) const { return mProgramID; }
+
+	private:
+		friend class GLGpuProgramManager;
+
+		GLSLGpuProgram(const String& source, const String& entryPoint, const String& language, 
+			GpuProgramType gptype, GpuProgramProfile profile);
+
 		/// GL Handle for the shader object
 		GLSLProgram* mGLSLProgram;
 
@@ -63,19 +79,6 @@ namespace CamelotEngine {
 
 		UINT32 mProgramID;
 		GLenum mProgramType;
-	public:
-		~GLSLGpuProgram();
-		GLSLGpuProgram(GLSLProgram* parent, const String& source, const String& entryPoint, const String& language, 
-			GpuProgramType gptype, GpuProgramProfile profile);
-
-		/// get the GLSLProgram for the shader object
-		GLSLProgram* getGLSLProgram(void) const { return mGLSLProgram; }
-		
-		/// Get the assigned GL program id
-		const UINT32 getProgramID(void) const { return mProgramID; }
-
-    protected:
-		friend class GLSLProgramFactory;
     };
 }
 

+ 4 - 5
CamelotGLRenderer/Source/GLSL/src/CmGLSLGpuProgram.cpp

@@ -39,14 +39,13 @@ namespace CamelotEngine {
 	UINT32 GLSLGpuProgram::mDomainShaderCount = 0;
 	UINT32 GLSLGpuProgram::mHullShaderCount = 0;
     //-----------------------------------------------------------------------------
-	GLSLGpuProgram::GLSLGpuProgram(GLSLProgram* parent, const String& source, const String& entryPoint, const String& language, 
+	GLSLGpuProgram::GLSLGpuProgram(const String& source, const String& entryPoint, const String& language, 
 		GpuProgramType gptype, GpuProgramProfile profile) 
-		:GpuProgram(source, entryPoint, language, gptype, profile), mGLSLProgram(parent)
+		:GpuProgram(source, entryPoint, language, gptype, profile)
     {
-        mType = parent->getType();
         mSyntaxCode = "glsl";
 
-		switch(parent->getType())
+		switch(mType)
 		{
 		case GPT_VERTEX_PROGRAM:
 			mProgramID = ++mVertexShaderCount;
@@ -64,7 +63,7 @@ namespace CamelotEngine {
 			mProgramID = ++mHullShaderCount;
 			break;
 		default:
-			CM_EXCEPT(InternalErrorException, "Invalid gpu program type: " + toString(parent->getType()));
+			CM_EXCEPT(InternalErrorException, "Invalid gpu program type: " + toString(mType));
 		}
     }
     //-----------------------------------------------------------------------

+ 10 - 6
CamelotGLRenderer/Source/GLSL/src/CmGLSLProgram.cpp

@@ -168,7 +168,10 @@ namespace CamelotEngine
 			checkForGLSLError( "GLSLProgram::loadFromSource", "Cannot load GLSL high-level shader source : ", mGLHandle, GLSLOT_PROGRAM, true);
 		}
 
-		mAssemblerProgram = GpuProgramPtr(new GLSLGpuProgram(this, mSource, mEntryPoint, mSyntaxCode, mType, mProfile));
+		mAssemblerProgram = GpuProgramManager::instance().createProgram(mSource, mEntryPoint, mSyntaxCode, mType, mProfile);
+		
+		std::shared_ptr<GLSLGpuProgram> glslGpuProgram = std::static_pointer_cast<GLSLGpuProgram>(mAssemblerProgram);
+		glslGpuProgram->setGLSLProgram(this);
 
 		GLSLParamParser paramParser;
 		paramParser.buildUniformDescriptions(mGLHandle, mParametersDesc);
@@ -179,11 +182,12 @@ namespace CamelotEngine
 	//---------------------------------------------------------------------------
 	void GLSLProgram::destroy_internal()
 	{   
-		// We didn't create mAssemblerProgram through a manager, so override this
-		// implementation so that we don't try to remove it from one. Since getCreator()
-		// is used, it might target a different matching handle!
-		mAssemblerProgram = nullptr;
-
+		if(mAssemblerProgram != nullptr)
+		{
+			mAssemblerProgram->destroy();
+			mAssemblerProgram = nullptr;
+		}
+		
 		if (isSupported())
 			glDeleteShader(mGLHandle);
 

+ 5 - 0
CamelotRenderer.sln

@@ -11,6 +11,7 @@ EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CamelotD3D9RenderSystem", "CamelotD3D9Renderer\CamelotD3D9Renderer.vcxproj", "{796B6DFF-BA04-42B7-A43A-2B14D707A33A}"
 	ProjectSection(ProjectDependencies) = postProject
 		{9B21D41C-516B-43BF-9B10-E99B599C7589} = {9B21D41C-516B-43BF-9B10-E99B599C7589}
+		{CC7F9445-71C9-4559-9976-FF0A64DCB582} = {CC7F9445-71C9-4559-9976-FF0A64DCB582}
 	EndProjectSection
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CamelotClient", "CamelotClient\CamelotClient.vcxproj", "{67137A0D-7A67-4D0C-9FBF-AF904FABEF05}"
@@ -28,6 +29,7 @@ EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CamelotGLRenderSystem", "CamelotGLRenderer\CamelotGLRenderer.vcxproj", "{F58FF869-2EA6-4FFF-AB84-328C531BA9D9}"
 	ProjectSection(ProjectDependencies) = postProject
 		{9B21D41C-516B-43BF-9B10-E99B599C7589} = {9B21D41C-516B-43BF-9B10-E99B599C7589}
+		{CC7F9445-71C9-4559-9976-FF0A64DCB582} = {CC7F9445-71C9-4559-9976-FF0A64DCB582}
 	EndProjectSection
 EndProject
 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{1D081E5A-615A-4C06-B2DF-0D8D9390DE02}"
@@ -38,6 +40,7 @@ EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CamelotFreeImgImporter", "CamelotFreeImgImporter\CamelotFreeImgImporter.vcxproj", "{122B7A22-0C62-4B35-B661-EBF3F394EA79}"
 	ProjectSection(ProjectDependencies) = postProject
 		{9B21D41C-516B-43BF-9B10-E99B599C7589} = {9B21D41C-516B-43BF-9B10-E99B599C7589}
+		{CC7F9445-71C9-4559-9976-FF0A64DCB582} = {CC7F9445-71C9-4559-9976-FF0A64DCB582}
 	EndProjectSection
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CamelotFBXImporter", "CamelotFBXImporter\CamelotFBXImporter.vcxproj", "{7F449698-73DF-4203-9F31-0877DBF01695}"
@@ -49,6 +52,7 @@ EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CamelotOISInput", "CamelotOISInput\CamelotOISInput.vcxproj", "{BFEBBAF8-8A84-4899-8899-D0D7196AF9A1}"
 	ProjectSection(ProjectDependencies) = postProject
 		{9B21D41C-516B-43BF-9B10-E99B599C7589} = {9B21D41C-516B-43BF-9B10-E99B599C7589}
+		{CC7F9445-71C9-4559-9976-FF0A64DCB582} = {CC7F9445-71C9-4559-9976-FF0A64DCB582}
 	EndProjectSection
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CamelotForwardRenderer", "CamelotForwardRenderer\CamelotForwardRenderer.vcxproj", "{08975177-4A13-4EE7-BB21-3BB92FB3F3CC}"
@@ -60,6 +64,7 @@ EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CamelotD3D11RenderSystem", "CamelotD3D11RenderSystem\CamelotD3D11RenderSystem.vcxproj", "{1437BB4E-DDB3-4307-AA41-8C035DA3014B}"
 	ProjectSection(ProjectDependencies) = postProject
 		{9B21D41C-516B-43BF-9B10-E99B599C7589} = {9B21D41C-516B-43BF-9B10-E99B599C7589}
+		{CC7F9445-71C9-4559-9976-FF0A64DCB582} = {CC7F9445-71C9-4559-9976-FF0A64DCB582}
 	EndProjectSection
 EndProject
 Global

+ 1 - 1
CamelotRenderer/Include/CmCoreGpuObject.h

@@ -20,7 +20,7 @@ namespace CamelotEngine
 
 		/**
 		 * @brief	Destroys this object. Make sure to call this before deleting the object.
-		 * 			
+o		 * 			
 		 * @note	Destruction is not done immediately, and is instead just scheduled on the
 		 * 			render thread. Unless called from render thread in which case it is executed right away.
 		 */

+ 1 - 1
CamelotRenderer/Include/CmImporter.h

@@ -23,7 +23,7 @@ namespace CamelotEngine
 		 *
 		 * @param	inputFilePath 	Pathname of the input file.
 		 */
-		BaseResourceHandle import(const String& inputFilePath);
+		ResourcePtr import(const String& inputFilePath);
 
 
 		/**

+ 7 - 1
CamelotRenderer/Include/CmMeshDataRTTI.h

@@ -103,7 +103,13 @@ namespace CamelotEngine
 		/************************************************************************/
 
 		VertexDeclarationPtr getVertexDecl(MeshData* obj) { return obj->declaration; }
-		void setVertexDecl(MeshData* obj, VertexDeclarationPtr vertexDecl) { obj->declaration = vertexDecl; }
+		void setVertexDecl(MeshData* obj, VertexDeclarationPtr vertexDecl) 
+		{ 
+			if(obj->declaration)
+				obj->declaration->destroy();
+
+			obj->declaration = vertexDecl; 
+		}
 
 		/************************************************************************/
 		/* 								vertexData                      		*/

+ 2 - 0
CamelotRenderer/Include/CmRenderStateManager.h

@@ -8,6 +8,8 @@ namespace CamelotEngine
 	class CM_EXPORT RenderStateManager : public Module<RenderStateManager>
 	{
 	public:
+		virtual ~RenderStateManager();
+
 		/**
 		 * @brief	Creates and initializes a new SamplerState.
 		 */

+ 24 - 21
CamelotRenderer/Include/CmResourceHandle.h

@@ -102,18 +102,6 @@ namespace CamelotEngine
 			:ResourceHandleBase()
 		{	}
 
-		explicit ResourceHandle(T* ptr)
-			:ResourceHandleBase()
-		{
-			init(ptr);
-		}
-
-		ResourceHandle(std::shared_ptr<T> ptr)
-			:ResourceHandleBase()
-		{
-			init(ptr);
-		}
-
 		template <typename T1>
 		ResourceHandle(const ResourceHandle<T1>& ptr)
 			:ResourceHandleBase()
@@ -136,15 +124,6 @@ namespace CamelotEngine
 		T* operator->() const { return get(); }
 		T& operator*() const { return *get(); }
 
-		/**
-		 * @brief	Releases the reference held by this handle.
-		 */
-		void reset()
-		{
-			mData->mPtr = nullptr;
-			mData->mIsCreated = false;
-		}
-
 		std::shared_ptr<T> getInternalPtr() 
 		{ 
 			throwIfNotLoaded();
@@ -164,6 +143,30 @@ namespace CamelotEngine
 		{
 			return (((mData->mPtr != nullptr)) ? &CM_Bool_struct<T>::_Member : 0);
 		}
+
+	private:
+		friend class Resources;
+
+		explicit ResourceHandle(T* ptr)
+			:ResourceHandleBase()
+		{
+			init(ptr);
+		}
+
+		ResourceHandle(std::shared_ptr<T> ptr)
+			:ResourceHandleBase()
+		{
+			init(ptr);
+		}
+
+		/**
+		 * @brief	Releases the reference held by this handle.
+		 */
+		void reset()
+		{
+			mData->mPtr = nullptr;
+			mData->mIsCreated = false;
+		}
 	};
 
 	template<class _Ty1, class _Ty2>

+ 8 - 14
CamelotRenderer/Include/CmResources.h

@@ -122,15 +122,17 @@ namespace CamelotEngine
 		void save(BaseResourceHandle resource);
 
 		/**
-		 * @brief	Creates a new resource at the specified location. Throws an exception if resource already exists.
-		 * 			Automatically calls Resources::save.
+		 * @brief	Creates a new resource at the specified location. Throws an exception if resource
+		 * 			already exists. Automatically calls Resources::save.
 		 *
-		 * @param	resource 	The resource.
+		 * @param	resource 	Pointer to the resource.
 		 * @param	filePath 	Full pathname of the file.
-		 * @param	overwrite	(optional) If true, any existing resource at the specified location
-		 * 						will be overwritten.
+		 * @param	overwrite	(optional) If true, any existing resource at the specified location will
+		 * 						be overwritten.
+		 *
+		 * @return	Handle to the resource. 
 		 */
-		void create(BaseResourceHandle resource, const String& filePath, bool overwrite = false);
+		BaseResourceHandle create(ResourcePtr resource, const String& filePath, bool overwrite = false);
 
 	public:
 		struct ResourceMetaData : public IReflectable
@@ -179,14 +181,6 @@ namespace CamelotEngine
 		const String& getUUIDFromPath(const String& path) const;
 
 		String mMetaDataFolderPath;
-
-	private:
-		friend class SpecificImporter;
-
-		/**
-		 * @brief	Registers the newly loaded resource in the global Resources library.
-		 */
-		void registerLoadedResource(BaseResourceHandle resource);
 	};
 
 	CM_EXPORT Resources& gResources();

+ 1 - 7
CamelotRenderer/Include/CmSpecificImporter.h

@@ -28,12 +28,6 @@ namespace CamelotEngine
 		 *
 		 * @return	null if it fails, otherwise the loaded object.
 		 */
-		virtual BaseResourceHandle import(const String& filePath) = 0;
-
-	protected:
-		/**
-		 * @brief	Registers the newly loaded resource in the global Resources library.
-		 */
-		void registerLoadedResource(BaseResourceHandle resource);
+		virtual ResourcePtr import(const String& filePath) = 0;
 	};
 }

+ 5 - 2
CamelotRenderer/Include/CmTextureRTTI.h

@@ -44,7 +44,7 @@ namespace CamelotEngine
 
 		UINT32 getPixelDataArraySize(Texture* obj)
 		{
-			return obj->getNumFaces() * obj->getNumMipmaps();
+			return obj->getNumFaces() * (obj->getNumMipmaps() + 1);
 		}
 
 		void setPixelDataArraySize(Texture* obj, UINT32 size)
@@ -100,7 +100,10 @@ namespace CamelotEngine
 				UINT32 face = (size_t)Math::Floor(i / (float)(texture->getNumMipmaps() + 1));
 				UINT32 mipmap = i % (texture->getNumMipmaps() + 1);
 
-				texture->setRawPixels_async(*pixelData->at(i), face, mipmap);
+				PixelData data(*pixelData->at(i));
+				data.ownsData = false;
+
+				texture->setRawPixels(data, face, mipmap);
 			}
 
 			delete pixelData;

+ 2 - 1
CamelotRenderer/Include/CmVertexDeclarationRTTI.h

@@ -3,6 +3,7 @@
 #include "CmPrerequisites.h"
 #include "CmRTTIType.h"
 #include "CmVertexBuffer.h"
+#include "CmHardwareBufferManager.h"
 
 namespace CamelotEngine
 {
@@ -47,7 +48,7 @@ namespace CamelotEngine
 
 		virtual std::shared_ptr<IReflectable> newRTTIObject() 
 		{
-			return std::shared_ptr<VertexDeclaration>(new VertexDeclaration());
+			return HardwareBufferManager::instance().createVertexDeclaration();
 		}
 
 		virtual const String& getRTTIName() 

+ 11 - 6
CamelotRenderer/Source/CmCoreGpuObject.cpp

@@ -18,7 +18,9 @@ namespace CamelotEngine
 	{
 		if(mIsInitialized)
 		{
-			LOGWRN("Destructor called but object is not destroyed. Object will leak.")
+			// Object must be released with destroy() otherwise engine can still try to use it, even if it was destructed
+			// (e.g. if an object has one of its methods queued in a command queue, and is destructed, you will be accessing invalid memory)
+			CM_EXCEPT(InternalErrorException, "Destructor called but object is not destroyed. This will result in nasty issues.");
 		}
 
 #if CM_DEBUG_MODE
@@ -34,17 +36,20 @@ namespace CamelotEngine
 
 	void CoreGpuObject::destroy()
 	{
-#if CM_DEBUG_MODE
-		if(!mIsInitialized)
-			CM_EXCEPT(InternalErrorException, "Trying to destroy an object that is already destroyed (or it never was initialized).");
-#endif
-
 		CoreGpuObjectManager::instance().registerObjectToDestroy(mThis.lock());
 		RenderSystem::instancePtr()->queueCommand(boost::bind(&CoreGpuObject::destroy_internal, this));
 	}
 
 	void CoreGpuObject::destroy_internal()
 	{
+#if CM_DEBUG_MODE
+		if(!mIsInitialized)
+		{
+			CoreGpuObjectManager::instance().unregisterObjectToDestroy(mThis.lock());
+			CM_EXCEPT(InternalErrorException, "Trying to destroy an object that is already destroyed (or it never was initialized).");
+		}
+#endif
+
 		mIsInitialized = false;
 
 		CoreGpuObjectManager::instance().unregisterObjectToDestroy(mThis.lock());

+ 1 - 0
CamelotRenderer/Source/CmHighLevelGpuProgram.cpp

@@ -71,6 +71,7 @@ namespace CamelotEngine
     {   
         if (mAssemblerProgram != nullptr && mAssemblerProgram.get() != this)
         {
+			mAssemblerProgram->destroy();
             mAssemblerProgram = nullptr;
         }
 

+ 2 - 2
CamelotRenderer/Source/CmImporter.cpp

@@ -47,7 +47,7 @@ namespace CamelotEngine
 		return false;
 	}
 
-	BaseResourceHandle Importer::import(const String& inputFilePath)
+	ResourcePtr Importer::import(const String& inputFilePath)
 	{
 		if(!FileSystem::fileExists(inputFilePath))
 		{
@@ -72,7 +72,7 @@ namespace CamelotEngine
 			}
 		}
 
-		BaseResourceHandle importedResource = importer->import(inputFilePath);
+		ResourcePtr importedResource = importer->import(inputFilePath);
 
 		return importedResource;
 	}

+ 40 - 4
CamelotRenderer/Source/CmMesh.cpp

@@ -29,7 +29,7 @@ namespace CamelotEngine
 
 	void Mesh::setMeshData(MeshDataPtr meshData)
 	{
-		RenderSystem::instancePtr()->queueCommand(boost::bind(&Mesh::setMeshData_internal, this, meshData));
+		RenderSystem::instancePtr()->queueCommand(boost::bind(&Mesh::setMeshData_internal, this, meshData), true);
 	}
 
 	void Mesh::setMeshData_internal(MeshDataPtr meshData)
@@ -41,11 +41,28 @@ namespace CamelotEngine
 			CM_EXCEPT(InternalErrorException, "Cannot load mesh. Mesh data is null.");
 		}
 
+		mSubMeshes.clear();
+
 		if(mVertexData != nullptr)
+		{
+			for(UINT32 i = 0; i < mVertexData->getBufferCount(); i++)
+			{
+				VertexBufferPtr buffer = mVertexData->getBuffer(i);
+
+				if(buffer != nullptr)
+					buffer->destroy();
+			}
+
 			delete mVertexData;
+		}
 
 		if(mIndexData != nullptr)
+		{
+			if(mIndexData->indexBuffer != nullptr)
+				mIndexData->indexBuffer->destroy();
+
 			delete mIndexData;
+		}
 
 		// Submeshes
 		for(UINT32 i = 0; i < meshData->subMeshes.size(); i++)
@@ -74,6 +91,9 @@ namespace CamelotEngine
 
 		mVertexData->vertexCount = meshData->vertexCount;
 
+		if(mVertexData->vertexDeclaration != nullptr)
+			mVertexData->vertexDeclaration->destroy();
+
 		mVertexData->vertexDeclaration = meshData->declaration->clone();
 
 		for(auto iter = meshData->vertexBuffers.begin(); iter != meshData->vertexBuffers.end(); ++iter)
@@ -175,6 +195,7 @@ namespace CamelotEngine
 	{
 		MeshDataPtr meshData(new MeshData());
 
+		meshData->declaration->destroy();
 		meshData->declaration = mVertexData->vertexDeclaration->clone();
 		
 		for(UINT32 i = 0; i < mSubMeshes.size(); i++)
@@ -191,7 +212,7 @@ namespace CamelotEngine
 			meshData->indexCount = mIndexData->indexCount - mIndexData->indexStart;
 			meshData->index = new int[meshData->indexCount];
 
-			UINT16* idxData = static_cast<UINT16*>(mIndexData->indexBuffer->lock(GBL_READ_ONLY));
+			UINT32* idxData = static_cast<UINT32*>(mIndexData->indexBuffer->lock(GBL_READ_ONLY));
 
 			for(UINT32 i = 0; i < mIndexData->indexCount; i++)
 				meshData->index[i] = (UINT32)idxData[i];
@@ -317,11 +338,26 @@ namespace CamelotEngine
 	{
 		THROW_IF_NOT_RENDER_THREAD;
 
-		if(mVertexData)
+		if(mVertexData != nullptr)
+		{
+			for(UINT32 i = 0; i < mVertexData->getBufferCount(); i++)
+			{
+				VertexBufferPtr buffer = mVertexData->getBuffer(i);
+
+				if(buffer != nullptr)
+					buffer->destroy();
+			}
+
 			delete mVertexData;
+		}
+
+		if(mIndexData != nullptr)
+		{
+			if(mIndexData->indexBuffer != nullptr)
+				mIndexData->indexBuffer->destroy();
 
-		if(mIndexData)
 			delete mIndexData;
+		}
 
 		Resource::destroy_internal();
 	}

+ 2 - 0
CamelotRenderer/Source/CmMeshData.cpp

@@ -61,6 +61,8 @@ namespace CamelotEngine
 			delete [] index;
 
 		vertexBuffers.clear();
+
+		declaration->destroy();
 	}
 
 	/************************************************************************/

+ 1 - 7
CamelotRenderer/Source/CmMeshRTTI.h

@@ -18,15 +18,9 @@ namespace CamelotEngine
 			addReflectablePtrField("mMeshData", 0, &MeshRTTI::getMeshData, &MeshRTTI::setMeshData);
 		}
 
-		virtual void onDeserializationEnded(IReflectable* obj)
-		{
-			Mesh* mesh = static_cast<Mesh*>(obj);
-			mesh->initialize();
-		}
-
 		virtual std::shared_ptr<IReflectable> newRTTIObject() 
 		{
-			return MeshManager::instance().createEmpty();
+			return MeshManager::instance().create();
 		}
 
 		virtual const String& getRTTIName() 

+ 15 - 0
CamelotRenderer/Source/CmRenderStateManager.cpp

@@ -6,6 +6,21 @@
 
 namespace CamelotEngine
 {
+	RenderStateManager::~RenderStateManager()
+	{
+		if(mDefaultSamplerState != nullptr)
+			mDefaultSamplerState->destroy();
+
+		if(mDefaultBlendState != nullptr)
+			mDefaultBlendState->destroy();
+
+		if(mDefaultRasterizerState != nullptr)
+			mDefaultRasterizerState->destroy();
+
+		if(mDefaultDepthStencilState != nullptr)
+			mDefaultDepthStencilState->destroy();
+	}
+
 	SamplerStatePtr RenderStateManager::createSamplerState(const SAMPLER_STATE_DESC& desc) const
 	{
 		SamplerStatePtr samplerState = SamplerStatePtr(new SamplerState());

+ 7 - 17
CamelotRenderer/Source/CmResources.cpp

@@ -249,13 +249,12 @@ namespace CamelotEngine
 		}
 	}
 
-	void Resources::create(BaseResourceHandle resource, const String& filePath, bool overwrite)
+	BaseResourceHandle Resources::create(ResourcePtr resource, const String& filePath, bool overwrite)
 	{
 		if(resource == nullptr)
 			CM_EXCEPT(InvalidParametersException, "Trying to save an uninitialized resource.");
 
-		if(!resource.isLoaded())
-			resource.waitUntilLoaded();
+		resource->waitUntilInitialized();
 
 		if(metaExists_UUID(resource->getUUID()))
 			CM_EXCEPT(InvalidParametersException, "Specified resource already exists.");
@@ -276,7 +275,11 @@ namespace CamelotEngine
 			removeMetaData(existingUUID);
 
 		addMetaData(resource->getUUID(), filePath);
-		save(resource);
+
+		BaseResourceHandle handle = resource;
+		save(handle);
+
+		return handle;
 	}
 
 	void Resources::save(BaseResourceHandle resource)
@@ -293,19 +296,6 @@ namespace CamelotEngine
 		fs.encode(resource.get(), filePath);
 	}
 
-	void Resources::registerLoadedResource(BaseResourceHandle resource)
-	{
-		auto iterFind = mLoadedResources.find(resource->getUUID());
-		if(iterFind == mLoadedResources.end())
-		{
-			mLoadedResources.insert(std::make_pair(resource->getUUID(), resource));
-		}
-		else
-		{
-			LOGDBG("Resource with the same UUID (" + resource->getUUID() + ") already exists!");
-		}
-	}
-
 	void Resources::loadMetaData()
 	{
 		vector<String>::type allFiles = FileSystem::getFiles(mMetaDataFolderPath);

+ 0 - 4
CamelotRenderer/Source/CmSpecificImporter.cpp

@@ -3,8 +3,4 @@
 
 namespace CamelotEngine
 {
-	void SpecificImporter::registerLoadedResource(BaseResourceHandle resource)
-	{
-		gResources().instance().registerLoadedResource(resource);
-	}
 }

+ 3 - 3
CamelotRenderer/Source/CmTexture.cpp

@@ -123,13 +123,13 @@ namespace CamelotEngine {
 	void Texture::getRawPixels_internal(UINT32 face, UINT32 mip, AsyncOp& op)
 	{
 		UINT32 numMips = getNumMipmaps();
-
-		UINT32 totalSize = 0;
 		UINT32 width = getWidth();
 		UINT32 height = getHeight();
 		UINT32 depth = getDepth();
 
-		for(UINT32 j = 0; j <= mip; j++)
+		UINT32 totalSize = PixelUtil::getMemorySize(width, height, depth, mFormat);
+
+		for(UINT32 j = 0; j < mip; j++)
 		{
 			totalSize = PixelUtil::getMemorySize(width, height, depth, mFormat);
 

+ 12 - 0
CamelotRenderer/TODO.txt

@@ -19,6 +19,17 @@ Pass
 
 GpuParamBlock - Needs to derive from CoreGpuObject and needs to be initialized better
 
+Loading meshes doesn't work
+ - And setMeshData is currently always synced
+creating a resource should add it to mLoaded
+also all unload() after creating a resource, for test purposes
+
+Having ResourceHandle closely tied in with Resources creates a problem when user just wants to create a resource in memory and use it? How to do it without saving it? e.g. material setTexture
+ - create() methods return a ResourceHandle.
+ - However those won't be released using unload() which is confusing.
+   - should create() register the resoruce with Resources right away?
+
+
 RenderTextures and MultiRenderTextures will only work properly if used directly from render thread, as setting each surface calls render methods, so its impossible to set one outside of render thread
  - also they don't have initialize_internal
  - I should probably make these immutable. Once they are set they can't be changed, so everything can be initialized when calling initialize()
@@ -207,6 +218,7 @@ After everything is polished
  - Go to Game Engine Architecture book and make a list of Utility systems we will need (Config files, Parsers, File I/O etc)
  - Go to GEA book and read about resource managers before implementing them
    - Actually I should re-read most of the chapers in the book, or all of it
+ - When building internal GUI make sure to use CEGUI as a reference
 
  - OpenGL non-Win32 window files haven't been properly parsed or tested
    - Since I probably can't compile them, try adding them to VS and see what intellisense says?

+ 7 - 0
CamelotUtility/Include/CmBinarySerializer.h

@@ -85,6 +85,12 @@ namespace CamelotEngine
 			UINT32 typeId;
 		};
 
+		struct PtrFieldToSet
+		{
+			UINT32 objectId;
+			boost::function<void(std::shared_ptr<IReflectable>)> func;
+		};
+
 		std::unordered_map<void*, UINT32> mObjectAddrToId;
 		UINT32 mLastUsedObjectId;
 		std::vector<ObjectToEncode> mObjectsToEncode;
@@ -93,6 +99,7 @@ namespace CamelotEngine
 		std::unordered_map<UINT32, std::shared_ptr<IReflectable>> mObjectMap;
 		std::vector<std::shared_ptr<IReflectable>> mObjectsToDecode;
 		std::vector<std::shared_ptr<IReflectable>> mDecodedObjects;
+		std::vector<PtrFieldToSet> mPtrFieldsToSet;
 
 		UINT32 getObjectSize(IReflectable* object);
 

+ 1 - 1
CamelotUtility/Include/CmMath.h

@@ -575,7 +575,7 @@ namespace CamelotEngine
 		template <typename T>
 		static T Clamp(T val, T minval, T maxval)
 		{
-			assert (minval < maxval && "Invalid clamp range");
+			assert (minval <= maxval && "Invalid clamp range");
 			return std::max(std::min(val, maxval), minval);
 		}
 

+ 5 - 1
CamelotUtility/Include/CmPixelDataRTTI.h

@@ -33,6 +33,9 @@ namespace CamelotEngine
 		UINT32& getSlicePitch(PixelData* obj) { return obj->slicePitch; }
 		void setSlicePitch(PixelData* obj, UINT32& val) { obj->slicePitch = val; }
 
+		PixelFormat& getFormat(PixelData* obj) { return obj->format; }
+		void setFormat(PixelData* obj, PixelFormat& val) { obj->format = val; }
+
 		ManagedDataBlock getData(PixelData* obj) 
 		{ 
 			ManagedDataBlock dataBlock((UINT8*)obj->data, obj->getConsecutiveSize(), false);
@@ -55,8 +58,9 @@ namespace CamelotEngine
 			addPlainField("back", 5, &PixelDataRTTI::getBack, &PixelDataRTTI::setBack);
 			addPlainField("rowPitch", 6, &PixelDataRTTI::getRowPitch, &PixelDataRTTI::setRowPitch);
 			addPlainField("slicePitch", 7, &PixelDataRTTI::getSlicePitch, &PixelDataRTTI::setSlicePitch);
+			addPlainField("format", 8, &PixelDataRTTI::getFormat, &PixelDataRTTI::setFormat);
 
-			addDataBlockField("data", 8, &PixelDataRTTI::getData, &PixelDataRTTI::setData);
+			addDataBlockField("data", 9, &PixelDataRTTI::getData, &PixelDataRTTI::setData);
 		}
 
 		virtual const String& getRTTIName()

+ 26 - 18
CamelotUtility/Source/CmBinarySerializer.cpp

@@ -110,10 +110,12 @@ namespace CamelotEngine
 	{
 		mObjectMap.clear();
 		mDecodedObjects.clear();
+		mPtrFieldsToSet.clear();
 
 		// Create empty instances of all ptr objects
 		UINT32 bytesRead = 0;
 		UINT8* dataIter = nullptr;
+		std::shared_ptr<IReflectable> object = nullptr;
 		std::shared_ptr<IReflectable> rootObject = nullptr;
 		do 
 		{
@@ -141,21 +143,29 @@ namespace CamelotEngine
 					"Base class objects are only supposed to be parts of a larger object.");
 			}
 
-			std::shared_ptr<IReflectable> object = IReflectable::createInstanceFromTypeId(objectTypeId);
+			object = IReflectable::createInstanceFromTypeId(objectTypeId);
 			mObjectMap.insert(std::make_pair(objectId, object));
 			mObjectsToDecode.push_back(object);
 
 			if(rootObject == nullptr)
 				rootObject = object;
 
-		} while (decodeInternal(nullptr, dataIter, dataLength, bytesRead));
+		} while (decodeInternal(object, dataIter, dataLength, bytesRead));
 
-		bytesRead = 0;
-		for(auto objIter = mObjectsToDecode.begin(); objIter != mObjectsToDecode.end(); ++objIter)
+		// Go in reverse, as we want fields with the lowest depth to be set first
+		// (Encoding ensures that first objects in the file will be top level and go down from there)
+		// This makes sure that objects are fully initialized before sending them to objects that have references to them
+		// (e.g. a Mesh and MeshData. Mesh expects to receive fully initialized MeshData in SetMeshData, so we need to ensure
+		// that we fully deserialize MeshData (and any references it might hold) before setting it in Mesh)
+		for(auto iter = mPtrFieldsToSet.rbegin(); iter != mPtrFieldsToSet.rend(); ++iter)
 		{
-			dataIter = data + bytesRead;
+			std::shared_ptr<IReflectable> resolvedObject = nullptr;
+
+			auto iterFind = mObjectMap.find(iter->objectId);
+			if(iterFind != mObjectMap.end())
+				resolvedObject = iterFind->second;
 
-			decodeInternal(*objIter, dataIter, dataLength, bytesRead);
+			iter->func(resolvedObject);
 		}
 
 		// Finish serialization for all objects
@@ -583,13 +593,12 @@ namespace CamelotEngine
 
 							if(curField != nullptr)
 							{
-								std::shared_ptr<IReflectable> resolvedObject = nullptr;
+								// We just record all pointer fields and assign them once we have everything else decoded
+								PtrFieldToSet fieldFunc;
+								fieldFunc.objectId = objectId;
+								fieldFunc.func = boost::bind(&RTTIReflectablePtrFieldBase::setArrayValue, curField, object.get(), i, _1);
 
-								auto findIter = mObjectMap.find(objectId);
-								if(findIter != mObjectMap.end())
-									resolvedObject = findIter->second;
-
-								curField->setArrayValue(object.get(), i, resolvedObject);
+								mPtrFieldsToSet.push_back(fieldFunc);
 							}
 						}
 
@@ -669,13 +678,12 @@ namespace CamelotEngine
 
 						if(curField != nullptr)
 						{
-							std::shared_ptr<IReflectable> resolvedObject = nullptr;
-
-							auto findIter = mObjectMap.find(objectId);
-							if(findIter != mObjectMap.end())
-								resolvedObject = findIter->second;
+							// We just record all pointer fields and assign them once we have everything else decoded
+							PtrFieldToSet fieldFunc;
+							fieldFunc.objectId = objectId;
+							fieldFunc.func = boost::bind(&RTTIReflectablePtrFieldBase::setValue, curField, object.get(), _1);
 
-							curField->setValue(object.get(), resolvedObject);
+							mPtrFieldsToSet.push_back(fieldFunc);
 						}
 
 						break;