瀏覽代碼

Refactored Textures and GpuPrograms so they use destroy() for releasing resources

Marko Pintera 13 年之前
父節點
當前提交
6b1f26b8ff
共有 32 個文件被更改,包括 445 次插入448 次删除
  1. 24 6
      CamelotD3D11RenderSystem/Include/CmD3D11GpuProgram.h
  2. 2 2
      CamelotD3D11RenderSystem/Include/CmD3D11HLSLProgram.h
  3. 2 7
      CamelotD3D11RenderSystem/Include/CmD3D11Texture.h
  4. 25 27
      CamelotD3D11RenderSystem/Source/CmD3D11GpuProgram.cpp
  5. 4 2
      CamelotD3D11RenderSystem/Source/CmD3D11HLSLProgram.cpp
  6. 29 32
      CamelotD3D11RenderSystem/Source/CmD3D11Texture.cpp
  7. 15 6
      CamelotD3D9Renderer/Include/CmD3D9GpuProgram.h
  8. 3 2
      CamelotD3D9Renderer/Include/CmD3D9HLSLProgram.h
  9. 3 5
      CamelotD3D9Renderer/Include/CmD3D9Texture.h
  10. 11 7
      CamelotD3D9Renderer/Source/CmD3D9GpuProgram.cpp
  11. 15 18
      CamelotD3D9Renderer/Source/CmD3D9HLSLProgram.cpp
  12. 40 53
      CamelotD3D9Renderer/Source/CmD3D9Texture.cpp
  13. 1 7
      CamelotGLRenderer/Include/CmGLTexture.h
  14. 91 104
      CamelotGLRenderer/Source/CmGLTexture.cpp
  15. 10 2
      CamelotGLRenderer/Source/GLSL/include/CmGLSLGpuProgram.h
  16. 2 2
      CamelotGLRenderer/Source/GLSL/include/CmGLSLProgram.h
  17. 6 3
      CamelotGLRenderer/Source/GLSL/src/CmGLSLGpuProgram.cpp
  18. 7 7
      CamelotGLRenderer/Source/GLSL/src/CmGLSLProgram.cpp
  19. 39 49
      CamelotRenderer/Include/CmGpuProgram.h
  20. 5 5
      CamelotRenderer/Include/CmHighLevelGpuProgram.h
  21. 18 5
      CamelotRenderer/Include/CmResource.h
  22. 1 41
      CamelotRenderer/Include/CmTexture.h
  23. 3 3
      CamelotRenderer/Source/CmCgProgram.cpp
  24. 8 21
      CamelotRenderer/Source/CmGpuProgram.cpp
  25. 7 9
      CamelotRenderer/Source/CmHighLevelGpuProgram.cpp
  26. 8 0
      CamelotRenderer/Source/CmResource.cpp
  27. 0 23
      CamelotRenderer/Source/CmTexture.cpp
  28. 11 0
      CamelotRenderer/TODO.txt
  29. 2 0
      CamelotUtility/CamelotUtility.vcxproj
  30. 6 0
      CamelotUtility/CamelotUtility.vcxproj.filters
  31. 25 0
      CamelotUtility/Include/CmIDestroyable.h
  32. 22 0
      CamelotUtility/Source/CmIDestroyable.cpp

+ 24 - 6
CamelotD3D11RenderSystem/Include/CmD3D11GpuProgram.h

@@ -36,7 +36,10 @@ namespace CamelotEngine
 		ID3D11VertexShader* getVertexShader(void) const;
 		ID3D11VertexShader* getVertexShader(void) const;
 		void loadFromMicrocode(D3D11Device& device, ID3D10Blob* microcode);
 		void loadFromMicrocode(D3D11Device& device, ID3D10Blob* microcode);
 	protected:
 	protected:
-		void unloadImpl(void);
+		/**
+		 * @copydoc GpuProgram::destroy_internal().
+		 */
+		void destroy_internal();
 	};
 	};
 
 
 	class CM_D3D11_EXPORT D3D11GpuFragmentProgram : public D3D11GpuProgram
 	class CM_D3D11_EXPORT D3D11GpuFragmentProgram : public D3D11GpuProgram
@@ -50,7 +53,10 @@ namespace CamelotEngine
 		ID3D11PixelShader* getPixelShader(void) const;
 		ID3D11PixelShader* getPixelShader(void) const;
 		void loadFromMicrocode(D3D11Device& device, ID3D10Blob* microcode);
 		void loadFromMicrocode(D3D11Device& device, ID3D10Blob* microcode);
 	protected:
 	protected:
-		void unloadImpl(void);
+		/**
+		 * @copydoc GpuProgram::destroy_internal().
+		 */
+		void destroy_internal();
 	};
 	};
 
 
 	class D3D11GpuDomainProgram : public D3D11GpuProgram
 	class D3D11GpuDomainProgram : public D3D11GpuProgram
@@ -64,7 +70,10 @@ namespace CamelotEngine
 		ID3D11DomainShader* getDomainShader(void) const;
 		ID3D11DomainShader* getDomainShader(void) const;
 		void loadFromMicrocode(D3D11Device& device, ID3D10Blob* microcode);
 		void loadFromMicrocode(D3D11Device& device, ID3D10Blob* microcode);
 	protected:
 	protected:
-		void unloadImpl(void);
+		/**
+		 * @copydoc GpuProgram::destroy_internal().
+		 */
+		void destroy_internal();
 	};
 	};
 
 
 	class D3D11GpuHullProgram : public D3D11GpuProgram
 	class D3D11GpuHullProgram : public D3D11GpuProgram
@@ -78,7 +87,10 @@ namespace CamelotEngine
 		ID3D11HullShader* getHullShader() const;
 		ID3D11HullShader* getHullShader() const;
 		void loadFromMicrocode(D3D11Device& device, ID3D10Blob* microcode);
 		void loadFromMicrocode(D3D11Device& device, ID3D10Blob* microcode);
 	protected:
 	protected:
-		void unloadImpl(void);
+		/**
+		 * @copydoc GpuProgram::destroy_internal().
+		 */
+		void destroy_internal();
 	};
 	};
 
 
 	class D3D11GpuGeometryProgram : public D3D11GpuProgram
 	class D3D11GpuGeometryProgram : public D3D11GpuProgram
@@ -92,7 +104,10 @@ namespace CamelotEngine
 		ID3D11GeometryShader* getGeometryShader(void) const;
 		ID3D11GeometryShader* getGeometryShader(void) const;
 		void loadFromMicrocode(D3D11Device& device, ID3D10Blob* microcode);
 		void loadFromMicrocode(D3D11Device& device, ID3D10Blob* microcode);
 	protected:
 	protected:
-		void unloadImpl(void);
+		/**
+		 * @copydoc GpuProgram::destroy_internal().
+		 */
+		void destroy_internal();
 	};
 	};
 
 
 	class D3D11GpuComputeProgram : public D3D11GpuProgram
 	class D3D11GpuComputeProgram : public D3D11GpuProgram
@@ -106,6 +121,9 @@ namespace CamelotEngine
 		ID3D11ComputeShader* getComputeShader(void) const;
 		ID3D11ComputeShader* getComputeShader(void) const;
 		void loadFromMicrocode(D3D11Device& device, ID3D10Blob* microcode);
 		void loadFromMicrocode(D3D11Device& device, ID3D10Blob* microcode);
 	protected:
 	protected:
-		void unloadImpl(void);
+		/**
+		 * @copydoc GpuProgram::destroy_internal().
+		 */
+		void destroy_internal();
 	};
 	};
 }
 }

+ 2 - 2
CamelotD3D11RenderSystem/Include/CmD3D11HLSLProgram.h

@@ -43,9 +43,9 @@ namespace CamelotEngine
         void loadFromSource();
         void loadFromSource();
 
 
         /**
         /**
-         * @copydoc GpuProgram::unload_internal()
+         * @copydoc HighLevelGpuProgram::destroy_internal()
          */
          */
-        void unload_internal();
+        void destroy_internal();
 
 
 	private:
 	private:
 		bool mColumnMajorMatrices;
 		bool mColumnMajorMatrices;

+ 2 - 7
CamelotD3D11RenderSystem/Include/CmD3D11Texture.h

@@ -74,14 +74,9 @@ namespace CamelotEngine
 		void initialize_internal();
 		void initialize_internal();
 
 
 		/**
 		/**
-		 * @copydoc Texture::createInternalResourcesImpl
+		 * @brief	Resource::destroy_internal
 		 */
 		 */
-		void createInternalResourcesImpl();
-		
-		/**
-		 * @copydoc Texture::freeInternalResourcesImpl
-		 */
-		void freeInternalResourcesImpl();
+		void destroy_internal();
 
 
 		TextureView* createView();
 		TextureView* createView();
 		void destroyView(TextureView* view);
 		void destroyView(TextureView* view);

+ 25 - 27
CamelotD3D11RenderSystem/Source/CmD3D11GpuProgram.cpp

@@ -19,7 +19,7 @@ namespace CamelotEngine
 
 
 	void D3D11GpuProgram::loadFromSource(void)
 	void D3D11GpuProgram::loadFromSource(void)
 	{
 	{
-		CM_EXCEPT(RenderingAPIException, "DirectX 11 doesn't support assembly shaders.");
+
 	}
 	}
 
 
 	D3D11GpuVertexProgram::D3D11GpuVertexProgram(const String& profile) 
 	D3D11GpuVertexProgram::D3D11GpuVertexProgram(const String& profile) 
@@ -28,11 +28,7 @@ namespace CamelotEngine
 	{ }
 	{ }
 
 
 	D3D11GpuVertexProgram::~D3D11GpuVertexProgram()
 	D3D11GpuVertexProgram::~D3D11GpuVertexProgram()
-	{
-		// have to call this here reather than in Resource destructor
-		// since calling virtual methods in base destructors causes crash
-		unload_internal(); 
-	}
+	{ }
 
 
 	void D3D11GpuVertexProgram::loadFromMicrocode(D3D11Device& device, ID3D10Blob*  microcode)
 	void D3D11GpuVertexProgram::loadFromMicrocode(D3D11Device& device, ID3D10Blob*  microcode)
 	{
 	{
@@ -59,9 +55,11 @@ namespace CamelotEngine
 		}
 		}
 	}
 	}
 
 
-	void D3D11GpuVertexProgram::unloadImpl(void)
+	void D3D11GpuVertexProgram::destroy_internal()
 	{
 	{
 		SAFE_RELEASE(mVertexShader);
 		SAFE_RELEASE(mVertexShader);
+
+		D3D11GpuProgram::destroy_internal();
 	}
 	}
 
 
 	ID3D11VertexShader * D3D11GpuVertexProgram::getVertexShader( void ) const
 	ID3D11VertexShader * D3D11GpuVertexProgram::getVertexShader( void ) const
@@ -75,9 +73,7 @@ namespace CamelotEngine
 	{ }
 	{ }
 
 
 	D3D11GpuFragmentProgram::~D3D11GpuFragmentProgram()
 	D3D11GpuFragmentProgram::~D3D11GpuFragmentProgram()
-	{
-		unload_internal(); 
-	}
+	{ }
 
 
 	void D3D11GpuFragmentProgram::loadFromMicrocode(D3D11Device& device, ID3D10Blob* microcode)
 	void D3D11GpuFragmentProgram::loadFromMicrocode(D3D11Device& device, ID3D10Blob* microcode)
 	{
 	{
@@ -103,9 +99,11 @@ namespace CamelotEngine
 		}
 		}
 	}
 	}
 
 
-	void D3D11GpuFragmentProgram::unloadImpl(void)
+	void D3D11GpuFragmentProgram::destroy_internal()
 	{
 	{
 		SAFE_RELEASE(mPixelShader);
 		SAFE_RELEASE(mPixelShader);
+
+		D3D11GpuProgram::destroy_internal();
 	}
 	}
 
 
 	ID3D11PixelShader * D3D11GpuFragmentProgram::getPixelShader( void ) const
 	ID3D11PixelShader * D3D11GpuFragmentProgram::getPixelShader( void ) const
@@ -119,9 +117,7 @@ namespace CamelotEngine
 	{ }
 	{ }
 
 
 	D3D11GpuGeometryProgram::~D3D11GpuGeometryProgram()
 	D3D11GpuGeometryProgram::~D3D11GpuGeometryProgram()
-	{
-		unload_internal(); 
-	}
+	{ }
 
 
 	void D3D11GpuGeometryProgram::loadFromMicrocode(D3D11Device& device, ID3D10Blob* microcode)
 	void D3D11GpuGeometryProgram::loadFromMicrocode(D3D11Device& device, ID3D10Blob* microcode)
 	{
 	{
@@ -147,9 +143,11 @@ namespace CamelotEngine
 		}
 		}
 	}
 	}
 
 
-	void D3D11GpuGeometryProgram::unloadImpl(void)
+	void D3D11GpuGeometryProgram::destroy_internal()
 	{
 	{
 		SAFE_RELEASE(mGeometryShader);
 		SAFE_RELEASE(mGeometryShader);
+
+		D3D11GpuProgram::destroy_internal();
 	}
 	}
 
 
 	ID3D11GeometryShader * D3D11GpuGeometryProgram::getGeometryShader(void) const
 	ID3D11GeometryShader * D3D11GpuGeometryProgram::getGeometryShader(void) const
@@ -163,9 +161,7 @@ namespace CamelotEngine
 	{ }
 	{ }
 
 
 	D3D11GpuDomainProgram::~D3D11GpuDomainProgram()
 	D3D11GpuDomainProgram::~D3D11GpuDomainProgram()
-	{
-		unload_internal(); 
-	}
+	{ }
 
 
 	void D3D11GpuDomainProgram::loadFromMicrocode(D3D11Device& device, ID3D10Blob* microcode)
 	void D3D11GpuDomainProgram::loadFromMicrocode(D3D11Device& device, ID3D10Blob* microcode)
 	{
 	{
@@ -191,9 +187,11 @@ namespace CamelotEngine
 		}
 		}
 	}
 	}
 
 
-	void D3D11GpuDomainProgram::unloadImpl(void)
+	void D3D11GpuDomainProgram::destroy_internal()
 	{
 	{
 		SAFE_RELEASE(mDomainShader);
 		SAFE_RELEASE(mDomainShader);
+
+		D3D11GpuProgram::destroy_internal();
 	}
 	}
 
 
 	ID3D11DomainShader * D3D11GpuDomainProgram::getDomainShader(void) const
 	ID3D11DomainShader * D3D11GpuDomainProgram::getDomainShader(void) const
@@ -207,9 +205,7 @@ namespace CamelotEngine
 	{ }
 	{ }
 
 
 	D3D11GpuHullProgram::~D3D11GpuHullProgram()
 	D3D11GpuHullProgram::~D3D11GpuHullProgram()
-	{
-		unload_internal(); 
-	}
+	{ }
 
 
 	void D3D11GpuHullProgram::loadFromMicrocode(D3D11Device& device, ID3D10Blob* microcode)
 	void D3D11GpuHullProgram::loadFromMicrocode(D3D11Device& device, ID3D10Blob* microcode)
 	{
 	{
@@ -235,9 +231,11 @@ namespace CamelotEngine
 		}
 		}
 	}
 	}
 
 
-	void D3D11GpuHullProgram::unloadImpl(void)
+	void D3D11GpuHullProgram::destroy_internal()
 	{
 	{
 		SAFE_RELEASE(mHullShader);
 		SAFE_RELEASE(mHullShader);
+
+		D3D11GpuProgram::destroy_internal();
 	}
 	}
 
 
 	ID3D11HullShader* D3D11GpuHullProgram::getHullShader(void) const
 	ID3D11HullShader* D3D11GpuHullProgram::getHullShader(void) const
@@ -251,9 +249,7 @@ namespace CamelotEngine
 	{ }
 	{ }
 
 
 	D3D11GpuComputeProgram::~D3D11GpuComputeProgram()
 	D3D11GpuComputeProgram::~D3D11GpuComputeProgram()
-	{
-		unload_internal(); 
-	}
+	{ }
 
 
 	void D3D11GpuComputeProgram::loadFromMicrocode(D3D11Device& device, ID3D10Blob* microcode)
 	void D3D11GpuComputeProgram::loadFromMicrocode(D3D11Device& device, ID3D10Blob* microcode)
 	{
 	{
@@ -279,9 +275,11 @@ namespace CamelotEngine
 		}
 		}
 	}
 	}
 
 
-	void D3D11GpuComputeProgram::unloadImpl(void)
+	void D3D11GpuComputeProgram::destroy_internal()
 	{
 	{
 		SAFE_RELEASE(mComputeShader);
 		SAFE_RELEASE(mComputeShader);
+
+		D3D11GpuProgram::destroy_internal();
 	}
 	}
 
 
 	ID3D11ComputeShader* D3D11GpuComputeProgram::getComputeShader(void) const
 	ID3D11ComputeShader* D3D11GpuComputeProgram::getComputeShader(void) const

+ 4 - 2
CamelotD3D11RenderSystem/Source/CmD3D11HLSLProgram.cpp

@@ -24,7 +24,7 @@ namespace CamelotEngine
 
 
 	D3D11HLSLProgram::~D3D11HLSLProgram()
 	D3D11HLSLProgram::~D3D11HLSLProgram()
 	{
 	{
-		unload_internal();
+
 	}
 	}
 
 
     void D3D11HLSLProgram::loadFromSource()
     void D3D11HLSLProgram::loadFromSource()
@@ -80,10 +80,12 @@ namespace CamelotEngine
 		SAFE_RELEASE(microcode);
 		SAFE_RELEASE(microcode);
 	}
 	}
 
 
-    void D3D11HLSLProgram::unload_internal()
+    void D3D11HLSLProgram::destroy_internal()
 	{
 	{
 		mAssemblerProgram = nullptr;
 		mAssemblerProgram = nullptr;
 		mMicrocode.clear();
 		mMicrocode.clear();
+
+		HighLevelGpuProgram::destroy_internal();
 	}
 	}
 
 
 	const String& D3D11HLSLProgram::getLanguage() const
 	const String& D3D11HLSLProgram::getLanguage() const

+ 29 - 32
CamelotD3D11RenderSystem/Source/CmD3D11Texture.cpp

@@ -31,9 +31,7 @@ namespace CamelotEngine
 
 
 	D3D11Texture::~D3D11Texture()
 	D3D11Texture::~D3D11Texture()
 	{
 	{
-		THROW_IF_NOT_RENDER_THREAD;
-
-		freeInternalResources();			
+			
 	}
 	}
 
 
 	void D3D11Texture::copyImpl(TexturePtr& target)
 	void D3D11Texture::copyImpl(TexturePtr& target)
@@ -96,33 +94,28 @@ namespace CamelotEngine
 	{
 	{
 		THROW_IF_NOT_RENDER_THREAD
 		THROW_IF_NOT_RENDER_THREAD
 
 
-		createInternalResources();
-
-		Resource::initialize_internal();
-	}
-
-	void D3D11Texture::createInternalResourcesImpl()
-	{
-		// load based on tex.type
-		switch (getTextureType())
+			// load based on tex.type
+			switch (getTextureType())
 		{
 		{
-		case TEX_TYPE_1D:
-			_create1DTex();
-			break;
-		case TEX_TYPE_2D:
-		case TEX_TYPE_CUBE_MAP:
-			_create2DTex();
-			break;
-		case TEX_TYPE_3D:
-			_create3DTex();
-			break;
-		default:
-			freeInternalResources();
-			CM_EXCEPT(RenderingAPIException, "Unknown texture type");
+			case TEX_TYPE_1D:
+				_create1DTex();
+				break;
+			case TEX_TYPE_2D:
+			case TEX_TYPE_CUBE_MAP:
+				_create2DTex();
+				break;
+			case TEX_TYPE_3D:
+				_create3DTex();
+				break;
+			default:
+				destroy_internal();
+				CM_EXCEPT(RenderingAPIException, "Unknown texture type");
 		}
 		}
+
+		Resource::initialize_internal();
 	}
 	}
 
 
-	void D3D11Texture::freeInternalResourcesImpl()
+	void D3D11Texture::destroy_internal()
 	{
 	{
 		SAFE_RELEASE(mTex);
 		SAFE_RELEASE(mTex);
 		SAFE_RELEASE(mShaderResourceView);
 		SAFE_RELEASE(mShaderResourceView);
@@ -130,6 +123,10 @@ namespace CamelotEngine
 		SAFE_RELEASE(m2DTex);
 		SAFE_RELEASE(m2DTex);
 		SAFE_RELEASE(m3DTex);
 		SAFE_RELEASE(m3DTex);
 		SAFE_RELEASE(mStagingBuffer);
 		SAFE_RELEASE(mStagingBuffer);
+
+		clearBufferViews();
+
+		IDestroyable::destroy();
 	}
 	}
 
 
 	void D3D11Texture::_create1DTex()
 	void D3D11Texture::_create1DTex()
@@ -180,7 +177,7 @@ namespace CamelotEngine
 		// Check result and except if failed
 		// Check result and except if failed
 		if (FAILED(hr) || device.hasError())
 		if (FAILED(hr) || device.hasError())
 		{
 		{
-			freeInternalResources();
+			destroy_internal();
 			String errorDescription = device.getErrorDescription();
 			String errorDescription = device.getErrorDescription();
 			CM_EXCEPT(RenderingAPIException, "Error creating texture\nError Description:" + errorDescription);
 			CM_EXCEPT(RenderingAPIException, "Error creating texture\nError Description:" + errorDescription);
 		}
 		}
@@ -189,7 +186,7 @@ namespace CamelotEngine
 
 
 		if(FAILED(hr) || device.hasError())
 		if(FAILED(hr) || device.hasError())
 		{
 		{
-			freeInternalResources();
+			destroy_internal();
 			String errorDescription = device.getErrorDescription();
 			String errorDescription = device.getErrorDescription();
 			CM_EXCEPT(RenderingAPIException, "Can't get base texture\nError Description:" + errorDescription);
 			CM_EXCEPT(RenderingAPIException, "Can't get base texture\nError Description:" + errorDescription);
 		}
 		}
@@ -295,7 +292,7 @@ namespace CamelotEngine
 		// Check result and except if failed
 		// Check result and except if failed
 		if (FAILED(hr) || device.hasError())
 		if (FAILED(hr) || device.hasError())
 		{
 		{
-			freeInternalResources();
+			destroy_internal();
 			String errorDescription = device.getErrorDescription();
 			String errorDescription = device.getErrorDescription();
 			CM_EXCEPT(RenderingAPIException, "Error creating texture\nError Description:" + errorDescription);
 			CM_EXCEPT(RenderingAPIException, "Error creating texture\nError Description:" + errorDescription);
 		}
 		}
@@ -304,7 +301,7 @@ namespace CamelotEngine
 
 
 		if(FAILED(hr) || device.hasError())
 		if(FAILED(hr) || device.hasError())
 		{
 		{
-			freeInternalResources();
+			destroy_internal();
 			String errorDescription = device.getErrorDescription();
 			String errorDescription = device.getErrorDescription();
 			CM_EXCEPT(RenderingAPIException, "Can't get base texture\nError Description:" + errorDescription);
 			CM_EXCEPT(RenderingAPIException, "Can't get base texture\nError Description:" + errorDescription);
 		}
 		}
@@ -420,7 +417,7 @@ namespace CamelotEngine
 		// Check result and except if failed
 		// Check result and except if failed
 		if (FAILED(hr) || device.hasError())
 		if (FAILED(hr) || device.hasError())
 		{
 		{
-			freeInternalResources();
+			destroy_internal();
 			String errorDescription = device.getErrorDescription();
 			String errorDescription = device.getErrorDescription();
 			CM_EXCEPT(RenderingAPIException, "Error creating texture\nError Description:" + errorDescription);
 			CM_EXCEPT(RenderingAPIException, "Error creating texture\nError Description:" + errorDescription);
 		}
 		}
@@ -429,7 +426,7 @@ namespace CamelotEngine
 
 
 		if(FAILED(hr) || device.hasError())
 		if(FAILED(hr) || device.hasError())
 		{
 		{
-			freeInternalResources();
+			destroy_internal();
 			String errorDescription = device.getErrorDescription();
 			String errorDescription = device.getErrorDescription();
 			CM_EXCEPT(RenderingAPIException, "Can't get base texture\nError Description:" + errorDescription);
 			CM_EXCEPT(RenderingAPIException, "Can't get base texture\nError Description:" + errorDescription);
 		}
 		}

+ 15 - 6
CamelotD3D9Renderer/Include/CmD3D9GpuProgram.h

@@ -44,8 +44,6 @@ namespace CamelotEngine {
 		virtual void initialize_internal(void);
 		virtual void initialize_internal(void);
 		/** Loads this program to specified device */
 		/** Loads this program to specified device */
 		virtual void initialize_internal(IDirect3DDevice9* d3d9Device);
 		virtual void initialize_internal(IDirect3DDevice9* d3d9Device);
-		/** Overridden from GpuProgram */
-		virtual void unload(void);
 
 
         /** Sets whether matrix packing in column-major order. */ 
         /** Sets whether matrix packing in column-major order. */ 
         void setColumnMajorMatrices(bool columnMajor) { mColumnMajorMatrices = columnMajor; }
         void setColumnMajorMatrices(bool columnMajor) { mColumnMajorMatrices = columnMajor; }
@@ -67,6 +65,11 @@ namespace CamelotEngine {
 
 
 		D3D9GpuProgram(const String& source, const String& entryPoint, const String& language, GpuProgramType gptype, GpuProgramProfile profile);
 		D3D9GpuProgram(const String& source, const String& entryPoint, const String& language, GpuProgramType gptype, GpuProgramProfile profile);
 
 
+		/**
+		 * @copydoc GpuProgram::destroy_internal.
+		 */
+		void destroy_internal();
+
         /** Overridden from GpuProgram */
         /** Overridden from GpuProgram */
         void loadFromSource(void);
         void loadFromSource(void);
 		/** Loads this program from source to specified device */
 		/** Loads this program from source to specified device */
@@ -94,8 +97,6 @@ namespace CamelotEngine {
     public:
     public:
 		~D3D9GpuVertexProgram();
 		~D3D9GpuVertexProgram();
         
         
-		void unload(void);
-
 		/// Gets the vertex shader
 		/// Gets the vertex shader
         IDirect3DVertexShader9* getVertexShader(void);
         IDirect3DVertexShader9* getVertexShader(void);
 
 
@@ -110,6 +111,11 @@ namespace CamelotEngine {
 
 
 		D3D9GpuVertexProgram(const String& source, const String& entryPoint, const String& language, GpuProgramType gptype, GpuProgramProfile profile);
 		D3D9GpuVertexProgram(const String& source, const String& entryPoint, const String& language, GpuProgramType gptype, GpuProgramProfile profile);
 
 
+		/**
+		 * @copydoc D3D9GpuProgram::destroy_internal.
+		 */
+		void destroy_internal();
+
         void loadFromMicrocode(IDirect3DDevice9* d3d9Device, ID3DXBuffer* microcode);
         void loadFromMicrocode(IDirect3DDevice9* d3d9Device, ID3DXBuffer* microcode);
 
 
 	protected:
 	protected:
@@ -125,8 +131,6 @@ namespace CamelotEngine {
     public:
     public:
 		~D3D9GpuFragmentProgram();
 		~D3D9GpuFragmentProgram();
 
 
-		void unload(void);
-
         /// Gets the pixel shader
         /// Gets the pixel shader
         IDirect3DPixelShader9* getPixelShader(void);
         IDirect3DPixelShader9* getPixelShader(void);
 
 
@@ -141,6 +145,11 @@ namespace CamelotEngine {
 
 
 		D3D9GpuFragmentProgram(const String& source, const String& entryPoint, const String& language, GpuProgramType gptype, GpuProgramProfile profile);
 		D3D9GpuFragmentProgram(const String& source, const String& entryPoint, const String& language, GpuProgramType gptype, GpuProgramProfile profile);
 
 
+		/**
+		 * @copydoc D3D9GpuProgram::destroy_internal.
+		 */
+		void destroy_internal();
+
         void loadFromMicrocode(IDirect3DDevice9* d3d9Device, ID3DXBuffer* microcode);
         void loadFromMicrocode(IDirect3DDevice9* d3d9Device, ID3DXBuffer* microcode);
 
 
 	protected:
 	protected:

+ 3 - 2
CamelotD3D9Renderer/Include/CmD3D9HLSLProgram.h

@@ -94,10 +94,11 @@ namespace CamelotEngine {
         /** Internal load implementation, must be implemented by subclasses.
         /** Internal load implementation, must be implemented by subclasses.
         */
         */
         void loadFromSource(void);
         void loadFromSource(void);
+
 		/**
 		/**
-		 * @copydoc GpuProgram::unload_internal()
+		 * @copydoc HighLevelGpuProgram::destroy_internal.
 		 */
 		 */
-        void unload_internal(void);
+        void destroy_internal();
 
 
         String mPreprocessorDefines;
         String mPreprocessorDefines;
         bool mColumnMajorMatrices;
         bool mColumnMajorMatrices;

+ 3 - 5
CamelotD3D9Renderer/Include/CmD3D9Texture.h

@@ -137,6 +137,8 @@ namespace CamelotEngine {
 		/// overriden from Resource
 		/// overriden from Resource
 		void initialize_internal();	
 		void initialize_internal();	
 
 
+		void destroy_internal();
+
 		/// overridden from Texture
 		/// overridden from Texture
 		void copyImpl(TexturePtr& target);
 		void copyImpl(TexturePtr& target);
 
 
@@ -155,12 +157,8 @@ namespace CamelotEngine {
 
 
 		/// @copydoc Resource::calculateSize
 		/// @copydoc Resource::calculateSize
 		UINT32 calculateSize(void) const;
 		UINT32 calculateSize(void) const;
-		/// @copydoc Texture::createInternalResourcesImpl
-		void createInternalResourcesImpl(void);
 		/// Creates this texture resources on the specified device.
 		/// Creates this texture resources on the specified device.
-		void createInternalResourcesImpl(IDirect3DDevice9* d3d9Device);
-		/// free internal resources
-		void freeInternalResourcesImpl(void);
+		void createInternalResources(IDirect3DDevice9* d3d9Device);
 		/// internal method, set Texture class final texture protected attributes
 		/// internal method, set Texture class final texture protected attributes
 		void _setFinalAttributes(IDirect3DDevice9* d3d9Device, TextureResources* textureResources, 
 		void _setFinalAttributes(IDirect3DDevice9* d3d9Device, TextureResources* textureResources, 
 			unsigned long width, unsigned long height, unsigned long depth, PixelFormat format);
 			unsigned long width, unsigned long height, unsigned long depth, PixelFormat format);

+ 11 - 7
CamelotD3D9Renderer/Source/CmD3D9GpuProgram.cpp

@@ -104,10 +104,12 @@ namespace CamelotEngine {
 			loadFromSource(d3d9Device);
 			loadFromSource(d3d9Device);
 		}
 		}
 	}
 	}
-	//-----------------------------------------------------------------------------
-	void D3D9GpuProgram::unload(void)
+	//----------------------------------------------------------------------------
+	void D3D9GpuProgram::destroy_internal()
 	{
 	{
 		SAFE_RELEASE(mpExternalMicrocode);
 		SAFE_RELEASE(mpExternalMicrocode);
+
+		GpuProgram::destroy_internal();
 	}
 	}
 	//-----------------------------------------------------------------------------
 	//-----------------------------------------------------------------------------
     void D3D9GpuProgram::loadFromSource(void)
     void D3D9GpuProgram::loadFromSource(void)
@@ -213,7 +215,7 @@ namespace CamelotEngine {
 		}
 		}
     }
     }
 	//-----------------------------------------------------------------------------
 	//-----------------------------------------------------------------------------
-    void D3D9GpuVertexProgram::unload(void)
+    void D3D9GpuVertexProgram::destroy_internal(void)
     {
     {
 		D3D9_DEVICE_ACCESS_CRITICAL_SECTION
 		D3D9_DEVICE_ACCESS_CRITICAL_SECTION
 
 
@@ -224,8 +226,9 @@ namespace CamelotEngine {
 			SAFE_RELEASE(it->second);
 			SAFE_RELEASE(it->second);
 			++it;
 			++it;
 		}
 		}
-		mMapDeviceToVertexShader.clear();		
-		D3D9GpuProgram::unload();
+		mMapDeviceToVertexShader.clear();	
+
+		D3D9GpuProgram::destroy_internal();
     }
     }
 
 
 	//-----------------------------------------------------------------------------
 	//-----------------------------------------------------------------------------
@@ -317,7 +320,7 @@ namespace CamelotEngine {
 		}
 		}
     }
     }
 	//-----------------------------------------------------------------------------
 	//-----------------------------------------------------------------------------
-    void D3D9GpuFragmentProgram::unload(void)
+    void D3D9GpuFragmentProgram::destroy_internal()
     {
     {
 		D3D9_DEVICE_ACCESS_CRITICAL_SECTION
 		D3D9_DEVICE_ACCESS_CRITICAL_SECTION
 
 
@@ -329,7 +332,8 @@ namespace CamelotEngine {
 			++it;
 			++it;
 		}
 		}
 		mMapDeviceToPixelShader.clear();	
 		mMapDeviceToPixelShader.clear();	
-		D3D9GpuProgram::unload();
+
+		D3D9GpuProgram::destroy_internal();
     }
     }
 	//-----------------------------------------------------------------------------
 	//-----------------------------------------------------------------------------
 	void D3D9GpuFragmentProgram::notifyOnDeviceCreate(IDirect3DDevice9* d3d9Device)
 	void D3D9GpuFragmentProgram::notifyOnDeviceCreate(IDirect3DDevice9* d3d9Device)

+ 15 - 18
CamelotD3D9Renderer/Source/CmD3D9HLSLProgram.cpp

@@ -500,20 +500,17 @@ namespace CamelotEngine {
             CM_EXCEPT(RenderingAPIException, message);
             CM_EXCEPT(RenderingAPIException, message);
         }
         }
 
 
-		if (!mCompileError)
-		{
-			String hlslProfile = GpuProgramManager::instance().gpuProgProfileToRSSpecificProfile(mProfile);
-
-			// Create a low-level program, give it the same name as us
-			mAssemblerProgram = 
-				GpuProgramManager::instance().createProgram(
-				"",// dummy source, since we'll be using microcode
-				"",
-				hlslProfile,
-				mType, 
-				GPP_NONE);
-			static_cast<D3D9GpuProgram*>(mAssemblerProgram.get())->setExternalMicrocode(mpMicroCode);
-		}
+		hlslProfile = GpuProgramManager::instance().gpuProgProfileToRSSpecificProfile(mProfile);
+
+		// Create a low-level program, give it the same name as us
+		mAssemblerProgram = 
+			GpuProgramManager::instance().createProgram(
+			"",// dummy source, since we'll be using microcode
+			"",
+			hlslProfile,
+			mType, 
+			GPP_NONE);
+		static_cast<D3D9GpuProgram*>(mAssemblerProgram.get())->setExternalMicrocode(mpMicroCode);
 
 
 		D3D9HLSLParamParser paramParser(constTable);
 		D3D9HLSLParamParser paramParser(constTable);
 		mParametersDesc = paramParser.buildParameterDescriptions();
 		mParametersDesc = paramParser.buildParameterDescriptions();
@@ -521,11 +518,11 @@ namespace CamelotEngine {
 		SAFE_RELEASE(constTable);
 		SAFE_RELEASE(constTable);
     }
     }
     //-----------------------------------------------------------------------
     //-----------------------------------------------------------------------
-    void D3D9HLSLProgram::unload_internal(void)
+    void D3D9HLSLProgram::destroy_internal()
     {
     {
         SAFE_RELEASE(mpMicroCode);
         SAFE_RELEASE(mpMicroCode);
         
         
-		HighLevelGpuProgram::unload_internal();
+		HighLevelGpuProgram::destroy_internal();
     }
     }
 	//-----------------------------------------------------------------------
 	//-----------------------------------------------------------------------
 	LPD3DXBUFFER D3D9HLSLProgram::getMicroCode()
 	LPD3DXBUFFER D3D9HLSLProgram::getMicroCode()
@@ -545,12 +542,12 @@ namespace CamelotEngine {
     //-----------------------------------------------------------------------
     //-----------------------------------------------------------------------
     D3D9HLSLProgram::~D3D9HLSLProgram()
     D3D9HLSLProgram::~D3D9HLSLProgram()
     {
     {
-        unload_internal();
+
     }
     }
     //-----------------------------------------------------------------------
     //-----------------------------------------------------------------------
     bool D3D9HLSLProgram::isSupported(void) const
     bool D3D9HLSLProgram::isSupported(void) const
     {
     {
-        if (mCompileError || !isRequiredCapabilitiesSupported())
+        if (!isRequiredCapabilitiesSupported())
             return false;
             return false;
 
 
 		String hlslProfile = GpuProgramManager::instance().gpuProgProfileToRSSpecificProfile(mProfile);
 		String hlslProfile = GpuProgramManager::instance().gpuProgProfileToRSSpecificProfile(mProfile);

+ 40 - 53
CamelotD3D9Renderer/Source/CmD3D9Texture.cpp

@@ -59,25 +59,6 @@ namespace CamelotEngine
 	/****************************************************************************************/
 	/****************************************************************************************/
 	D3D9Texture::~D3D9Texture()
 	D3D9Texture::~D3D9Texture()
 	{	
 	{	
-		THROW_IF_NOT_RENDER_THREAD;
-
-		D3D9_DEVICE_ACCESS_CRITICAL_SECTION
-		
-        // have to call this here reather than in Resource destructor
-        // since calling virtual methods in base destructors causes crash
-		freeInternalResources();			
-
-		// Free memory allocated per device.
-		DeviceToTextureResourcesIterator it = mMapDeviceToTextureResources.begin();
-		while (it != mMapDeviceToTextureResources.end())
-		{
-			TextureResources* textureResource = it->second;
-			
-			SAFE_DELETE(textureResource);
-			++it;
-		}		
-		mMapDeviceToTextureResources.clear();
-		mSurfaceList.clear();		
 	}
 	}
 	/****************************************************************************************/
 	/****************************************************************************************/
 	PixelData D3D9Texture::lockImpl(GpuLockOptions options, UINT32 mipLevel, UINT32 face)
 	PixelData D3D9Texture::lockImpl(GpuLockOptions options, UINT32 mipLevel, UINT32 face)
@@ -220,28 +201,47 @@ namespace CamelotEngine
 	/****************************************************************************************/
 	/****************************************************************************************/
 	void D3D9Texture::initialize_internal()
 	void D3D9Texture::initialize_internal()
 	{ 
 	{ 
-		THROW_IF_NOT_RENDER_THREAD
+		THROW_IF_NOT_RENDER_THREAD;
 
 
-		createInternalResources();
+		for (UINT32 i = 0; i < D3D9RenderSystem::getResourceCreationDeviceCount(); ++i)
+		{
+			IDirect3DDevice9* d3d9Device = D3D9RenderSystem::getResourceCreationDevice(i);
+
+			createInternalResources(d3d9Device);
+		}
 
 
 		Resource::initialize_internal();
 		Resource::initialize_internal();
 	}
 	}
 	/****************************************************************************************/
 	/****************************************************************************************/
-	void D3D9Texture::freeInternalResourcesImpl()
-	{
-		D3D9_DEVICE_ACCESS_CRITICAL_SECTION
+	void D3D9Texture::destroy_internal()
+	{ 
+		THROW_IF_NOT_RENDER_THREAD;
 
 
 		DeviceToTextureResourcesIterator it = mMapDeviceToTextureResources.begin();
 		DeviceToTextureResourcesIterator it = mMapDeviceToTextureResources.begin();
-
 		while (it != mMapDeviceToTextureResources.end())
 		while (it != mMapDeviceToTextureResources.end())
 		{
 		{
 			TextureResources* textureResource = it->second;
 			TextureResources* textureResource = it->second;
 
 
 			freeTextureResources(it->first, textureResource);			
 			freeTextureResources(it->first, textureResource);			
 			++it;
 			++it;
-		}						
-	}
+		}
+
+		it = mMapDeviceToTextureResources.begin();
+		while (it != mMapDeviceToTextureResources.end())
+		{
+			TextureResources* textureResource = it->second;
+
+			SAFE_DELETE(textureResource);
+			++it;
+		}		
+
+		mMapDeviceToTextureResources.clear();
+		mSurfaceList.clear();	
+		
+		clearBufferViews();
 
 
+		IDestroyable::destroy();
+	}
 	/****************************************************************************************/
 	/****************************************************************************************/
 	D3D9Texture::TextureResources* D3D9Texture::getTextureResources(IDirect3DDevice9* d3d9Device)
 	D3D9Texture::TextureResources* D3D9Texture::getTextureResources(IDirect3DDevice9* d3d9Device)
 	{		
 	{		
@@ -326,20 +326,7 @@ namespace CamelotEngine
 
 
 	}
 	}
 	/****************************************************************************************/
 	/****************************************************************************************/
-    void D3D9Texture::createInternalResourcesImpl(void)
-	{
-		D3D9_DEVICE_ACCESS_CRITICAL_SECTION
-
-		for (UINT32 i = 0; i < D3D9RenderSystem::getResourceCreationDeviceCount(); ++i)
-		{
-			IDirect3DDevice9* d3d9Device = D3D9RenderSystem::getResourceCreationDevice(i);
-
-			createInternalResourcesImpl(d3d9Device);
-		}
-	}
-
-	/****************************************************************************************/
-	void D3D9Texture::createInternalResourcesImpl(IDirect3DDevice9* d3d9Device)
+	void D3D9Texture::createInternalResources(IDirect3DDevice9* d3d9Device)
 	{		
 	{		
 		TextureResources* textureResources;			
 		TextureResources* textureResources;			
 
 
@@ -362,7 +349,7 @@ namespace CamelotEngine
 			_createVolumeTex(d3d9Device);
 			_createVolumeTex(d3d9Device);
 			break;
 			break;
 		default:
 		default:
-			freeInternalResources();
+			destroy_internal();
 			CM_EXCEPT(InternalErrorException, "Unknown texture type");
 			CM_EXCEPT(InternalErrorException, "Unknown texture type");
 		}
 		}
 	}
 	}
@@ -464,7 +451,7 @@ namespace CamelotEngine
 			hr = textureResources->pFSAASurface->GetDesc(&desc);
 			hr = textureResources->pFSAASurface->GetDesc(&desc);
 			if (FAILED(hr))
 			if (FAILED(hr))
 			{
 			{
-				freeInternalResources();
+				destroy_internal();
 				CM_EXCEPT(RenderingAPIException, "Can't get texture description: " + String(DXGetErrorDescription(hr)));
 				CM_EXCEPT(RenderingAPIException, "Can't get texture description: " + String(DXGetErrorDescription(hr)));
 			}
 			}
 
 
@@ -487,7 +474,7 @@ namespace CamelotEngine
 			hr = textureResources->pDepthStencilSurface->GetDesc(&desc);
 			hr = textureResources->pDepthStencilSurface->GetDesc(&desc);
 			if (FAILED(hr))
 			if (FAILED(hr))
 			{
 			{
-				freeInternalResources();
+				destroy_internal();
 				CM_EXCEPT(RenderingAPIException, "Can't get texture description: " + String(DXGetErrorDescription(hr)));
 				CM_EXCEPT(RenderingAPIException, "Can't get texture description: " + String(DXGetErrorDescription(hr)));
 			}
 			}
 
 
@@ -509,7 +496,7 @@ namespace CamelotEngine
 			// check result and except if failed
 			// check result and except if failed
 			if (FAILED(hr))
 			if (FAILED(hr))
 			{
 			{
-				freeInternalResources();
+				destroy_internal();
 				CM_EXCEPT(RenderingAPIException, "Error creating texture: " + String(DXGetErrorDescription(hr)));
 				CM_EXCEPT(RenderingAPIException, "Error creating texture: " + String(DXGetErrorDescription(hr)));
 			}
 			}
 
 
@@ -517,7 +504,7 @@ namespace CamelotEngine
 			hr = textureResources->pNormTex->QueryInterface(IID_IDirect3DBaseTexture9, (void **)&textureResources->pBaseTex);
 			hr = textureResources->pNormTex->QueryInterface(IID_IDirect3DBaseTexture9, (void **)&textureResources->pBaseTex);
 			if (FAILED(hr))
 			if (FAILED(hr))
 			{
 			{
-				freeInternalResources();
+				destroy_internal();
 				CM_EXCEPT(RenderingAPIException, "Can't get base texture: " + String(DXGetErrorDescription(hr)));
 				CM_EXCEPT(RenderingAPIException, "Can't get base texture: " + String(DXGetErrorDescription(hr)));
 			}
 			}
 
 
@@ -527,7 +514,7 @@ namespace CamelotEngine
 			hr = textureResources->pNormTex->GetLevelDesc(0, &desc);
 			hr = textureResources->pNormTex->GetLevelDesc(0, &desc);
 			if (FAILED(hr))
 			if (FAILED(hr))
 			{
 			{
-				freeInternalResources();
+				destroy_internal();
 				CM_EXCEPT(RenderingAPIException, "Can't get texture description: " + String(DXGetErrorDescription(hr)));
 				CM_EXCEPT(RenderingAPIException, "Can't get texture description: " + String(DXGetErrorDescription(hr)));
 			}
 			}
 
 
@@ -616,7 +603,7 @@ namespace CamelotEngine
 		// check result and except if failed
 		// check result and except if failed
 		if (FAILED(hr))
 		if (FAILED(hr))
 		{
 		{
-			freeInternalResources();
+			destroy_internal();
 			CM_EXCEPT(RenderingAPIException, "Error creating texture: " + String(DXGetErrorDescription(hr)));
 			CM_EXCEPT(RenderingAPIException, "Error creating texture: " + String(DXGetErrorDescription(hr)));
 		}
 		}
 
 
@@ -624,7 +611,7 @@ namespace CamelotEngine
 		hr = textureResources->pCubeTex->QueryInterface(IID_IDirect3DBaseTexture9, (void **)&textureResources->pBaseTex);
 		hr = textureResources->pCubeTex->QueryInterface(IID_IDirect3DBaseTexture9, (void **)&textureResources->pBaseTex);
 		if (FAILED(hr))
 		if (FAILED(hr))
 		{
 		{
-			freeInternalResources();
+			destroy_internal();
 			CM_EXCEPT(RenderingAPIException, "Can't get base texture: " + String(DXGetErrorDescription(hr)));
 			CM_EXCEPT(RenderingAPIException, "Can't get base texture: " + String(DXGetErrorDescription(hr)));
 		}
 		}
 		
 		
@@ -634,7 +621,7 @@ namespace CamelotEngine
 		hr = textureResources->pCubeTex->GetLevelDesc(0, &desc);
 		hr = textureResources->pCubeTex->GetLevelDesc(0, &desc);
 		if (FAILED(hr))
 		if (FAILED(hr))
 		{
 		{
-			freeInternalResources();
+			destroy_internal();
 			CM_EXCEPT(RenderingAPIException, "Can't get texture description: " + String(DXGetErrorDescription(hr)));
 			CM_EXCEPT(RenderingAPIException, "Can't get texture description: " + String(DXGetErrorDescription(hr)));
 		}
 		}
 
 
@@ -721,7 +708,7 @@ namespace CamelotEngine
 		// check result and except if failed
 		// check result and except if failed
 		if (FAILED(hr))
 		if (FAILED(hr))
 		{
 		{
-			freeInternalResources();
+			destroy_internal();
 			CM_EXCEPT(RenderingAPIException, "Error creating texture: " + String(DXGetErrorDescription(hr)));
 			CM_EXCEPT(RenderingAPIException, "Error creating texture: " + String(DXGetErrorDescription(hr)));
 		}
 		}
 
 
@@ -729,7 +716,7 @@ namespace CamelotEngine
 		hr = textureResources->pVolumeTex->QueryInterface(IID_IDirect3DBaseTexture9, (void **)&textureResources->pBaseTex);
 		hr = textureResources->pVolumeTex->QueryInterface(IID_IDirect3DBaseTexture9, (void **)&textureResources->pBaseTex);
 		if (FAILED(hr))
 		if (FAILED(hr))
 		{
 		{
-			freeInternalResources();
+			destroy_internal();
 			CM_EXCEPT(RenderingAPIException, "Can't get base texture: " + String(DXGetErrorDescription(hr)));
 			CM_EXCEPT(RenderingAPIException, "Can't get base texture: " + String(DXGetErrorDescription(hr)));
 		}
 		}
 		
 		
@@ -739,7 +726,7 @@ namespace CamelotEngine
 		hr = textureResources->pVolumeTex->GetLevelDesc(0, &desc);
 		hr = textureResources->pVolumeTex->GetLevelDesc(0, &desc);
 		if (FAILED(hr))
 		if (FAILED(hr))
 		{
 		{
-			freeInternalResources();
+			destroy_internal();
 			CM_EXCEPT(RenderingAPIException, "Can't get texture description: " + String(DXGetErrorDescription(hr)));
 			CM_EXCEPT(RenderingAPIException, "Can't get texture description: " + String(DXGetErrorDescription(hr)));
 		}
 		}
 		_setFinalAttributes(d3d9Device, textureResources,
 		_setFinalAttributes(d3d9Device, textureResources,

+ 1 - 7
CamelotGLRenderer/Include/CmGLTexture.h

@@ -47,8 +47,6 @@ namespace CamelotEngine {
 
 
         GLuint getGLID() const;
         GLuint getGLID() const;
 		
 		
-		void getCustomAttribute(const String& name, void* pData);
-
 		/** Return hardware pixel buffer for a surface. This buffer can then
 		/** Return hardware pixel buffer for a surface. This buffer can then
 			be used to copy data from and to a particular level of the texture.
 			be used to copy data from and to a particular level of the texture.
 			@param face 	Face number, in case of a cubemap texture. Must be 0
 			@param face 	Face number, in case of a cubemap texture. Must be 0
@@ -70,17 +68,13 @@ namespace CamelotEngine {
 		GLTexture(GLSupport& support);
 		GLTexture(GLSupport& support);
 
 
 		void initialize_internal();
 		void initialize_internal();
+		void destroy_internal();
 
 
 		PixelData lockImpl(GpuLockOptions options, UINT32 mipLevel, UINT32 face);
 		PixelData lockImpl(GpuLockOptions options, UINT32 mipLevel, UINT32 face);
 		void unlockImpl();
 		void unlockImpl();
 
 
 		void copyImpl(TexturePtr& target);
 		void copyImpl(TexturePtr& target);
 
 
-		/// @copydoc Texture::createInternalResourcesImpl
-		void createInternalResourcesImpl(void);
-        /// @copydoc Resource::freeInternalResourcesImpl
-        void freeInternalResourcesImpl(void);
-
 		/** internal method, create GLHardwarePixelBuffers for every face and
 		/** internal method, create GLHardwarePixelBuffers for every face and
 			 mipmap level. This method must be called after the GL texture object was created,
 			 mipmap level. This method must be called after the GL texture object was created,
 			the number of mipmaps was set (GL_TEXTURE_MAX_LEVEL) and glTexImageXD was called to
 			the number of mipmaps was set (GL_TEXTURE_MAX_LEVEL) and glTexImageXD was called to

+ 91 - 104
CamelotGLRenderer/Source/CmGLTexture.cpp

@@ -65,101 +65,23 @@ namespace CamelotEngine {
 
 
     GLTexture::~GLTexture()
     GLTexture::~GLTexture()
     {
     {
-		THROW_IF_NOT_RENDER_THREAD;
-
-		freeInternalResources();
     }
     }
 
 
 	void GLTexture::initialize_internal()
 	void GLTexture::initialize_internal()
 	{
 	{
-		createInternalResources();
-
-		Resource::initialize_internal();
-	}
-
-    GLenum GLTexture::getGLTextureTarget(void) const
-    {
-        switch(mTextureType)
-        {
-            case TEX_TYPE_1D:
-                return GL_TEXTURE_1D;
-            case TEX_TYPE_2D:
-				if(mFSAA > 0)
-					return GL_TEXTURE_2D_MULTISAMPLE;
-				else
-					return GL_TEXTURE_2D;
-            case TEX_TYPE_3D:
-                return GL_TEXTURE_3D;
-            case TEX_TYPE_CUBE_MAP:
-                return GL_TEXTURE_CUBE_MAP;
-            default:
-                return 0;
-        };
-    }
-
-	GLuint GLTexture::getGLID() const
-	{
-		THROW_IF_NOT_RENDER_THREAD;
-
-		return mTextureID;
-	}
-
-	//* Creation / loading methods ********************************************
-	PixelData GLTexture::lockImpl(GpuLockOptions options, UINT32 mipLevel, UINT32 face)
-	{
-		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;
-
-		PixelData lockedArea(mipWidth, mipHeight, mipDepth, mFormat);
-
-		mLockedBuffer = getBuffer(face, mipLevel);
-		lockedArea.data = mLockedBuffer->lock(options);
-
-		return lockedArea;
-	}
-	/****************************************************************************************/
-	void GLTexture::unlockImpl()
-	{
-		if(mLockedBuffer == nullptr)
-			CM_EXCEPT(InternalErrorException, "Trying to unlock a buffer that's not locked.");
-
-		mLockedBuffer->unlock();
-		mLockedBuffer = nullptr;
-	}
-	/****************************************************************************************/ 
-	void GLTexture::copyImpl(TexturePtr& target)
-	{
-		size_t numMips = std::min(getNumMipmaps(), target->getNumMipmaps());
-
-		GLTexture* glTexture = static_cast<GLTexture*>(target.get());
-		for(unsigned int face=0; face<getNumFaces(); face++)
-		{
-			for(unsigned int mip=0; mip<=numMips; mip++)
-			{
-				glTexture->getBuffer(face, mip)->blit(getBuffer(face, mip));
-			}
-		}
-	}
-	/****************************************************************************************/
-	void GLTexture::createInternalResourcesImpl(void)
-    {
 		// Convert to nearest power-of-two size if required
 		// Convert to nearest power-of-two size if required
-        mWidth = GLPixelUtil::optionalPO2(mWidth);      
-        mHeight = GLPixelUtil::optionalPO2(mHeight);
-        mDepth = GLPixelUtil::optionalPO2(mDepth);
+		mWidth = GLPixelUtil::optionalPO2(mWidth);      
+		mHeight = GLPixelUtil::optionalPO2(mHeight);
+		mDepth = GLPixelUtil::optionalPO2(mDepth);
 
 
 		// Adjust format if required
 		// Adjust format if required
 		mFormat = TextureManager::instance().getNativeFormat(mTextureType, mFormat, mUsage);
 		mFormat = TextureManager::instance().getNativeFormat(mTextureType, mFormat, mUsage);
-		
+
 		// Check requested number of mipmaps
 		// Check requested number of mipmaps
 		UINT32 maxMips = GLPixelUtil::getMaxMipmaps(mWidth, mHeight, mDepth, mFormat);
 		UINT32 maxMips = GLPixelUtil::getMaxMipmaps(mWidth, mHeight, mDepth, mFormat);
 		if(mNumMipmaps>maxMips)
 		if(mNumMipmaps>maxMips)
 			mNumMipmaps = maxMips;
 			mNumMipmaps = maxMips;
-		
+
 		if((mUsage & TU_RENDERTARGET) != 0)
 		if((mUsage & TU_RENDERTARGET) != 0)
 		{
 		{
 			mNumMipmaps = 1;
 			mNumMipmaps = 1;
@@ -180,23 +102,23 @@ namespace CamelotEngine {
 		}
 		}
 
 
 		// Generate texture name
 		// Generate texture name
-        glGenTextures( 1, &mTextureID );
-		
+		glGenTextures( 1, &mTextureID );
+
 		// Set texture type
 		// Set texture type
 		glBindTexture( getGLTextureTarget(), mTextureID );
 		glBindTexture( getGLTextureTarget(), mTextureID );
-        
+
 		// This needs to be set otherwise the texture doesn't get rendered
 		// This needs to be set otherwise the texture doesn't get rendered
 		glTexParameteri( getGLTextureTarget(), GL_TEXTURE_MAX_LEVEL, mNumMipmaps );
 		glTexParameteri( getGLTextureTarget(), GL_TEXTURE_MAX_LEVEL, mNumMipmaps );
-        
-        // Set some misc default parameters so NVidia won't complain, these can of course be changed later
-        glTexParameteri(getGLTextureTarget(), GL_TEXTURE_MIN_FILTER, GL_NEAREST);
-        glTexParameteri(getGLTextureTarget(), GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+
+		// Set some misc default parameters so NVidia won't complain, these can of course be changed later
+		glTexParameteri(getGLTextureTarget(), GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+		glTexParameteri(getGLTextureTarget(), GL_TEXTURE_MAG_FILTER, GL_NEAREST);
 		if (GLEW_VERSION_1_2)
 		if (GLEW_VERSION_1_2)
 		{
 		{
 			glTexParameteri(getGLTextureTarget(), GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
 			glTexParameteri(getGLTextureTarget(), GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
 			glTexParameteri(getGLTextureTarget(), GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
 			glTexParameteri(getGLTextureTarget(), GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
 		}
 		}
-		
+
 		// Allocate internal buffer so that glTexSubImageXD can be used
 		// Allocate internal buffer so that glTexSubImageXD can be used
 		// Internal format
 		// Internal format
 		GLenum format = GLPixelUtil::getClosestGLInternalFormat(mFormat, mHwGamma);
 		GLenum format = GLPixelUtil::getClosestGLInternalFormat(mFormat, mHwGamma);
@@ -274,13 +196,87 @@ namespace CamelotEngine {
 		createSurfaceList();
 		createSurfaceList();
 		// Get final internal format
 		// Get final internal format
 		mFormat = getBuffer(0,0)->getFormat();
 		mFormat = getBuffer(0,0)->getFormat();
+
+		Resource::initialize_internal();
 	}
 	}
-	//--------------------------------------------------------------------------------------------
-    void GLTexture::freeInternalResourcesImpl()
-    {
+
+	void GLTexture::destroy_internal()
+	{
 		mSurfaceList.clear();
 		mSurfaceList.clear();
-        glDeleteTextures( 1, &mTextureID );
+		glDeleteTextures( 1, &mTextureID );
+
+		clearBufferViews();
+
+		IDestroyable::destroy();
+	}
+
+    GLenum GLTexture::getGLTextureTarget(void) const
+    {
+        switch(mTextureType)
+        {
+            case TEX_TYPE_1D:
+                return GL_TEXTURE_1D;
+            case TEX_TYPE_2D:
+				if(mFSAA > 0)
+					return GL_TEXTURE_2D_MULTISAMPLE;
+				else
+					return GL_TEXTURE_2D;
+            case TEX_TYPE_3D:
+                return GL_TEXTURE_3D;
+            case TEX_TYPE_CUBE_MAP:
+                return GL_TEXTURE_CUBE_MAP;
+            default:
+                return 0;
+        };
     }
     }
+
+	GLuint GLTexture::getGLID() const
+	{
+		THROW_IF_NOT_RENDER_THREAD;
+
+		return mTextureID;
+	}
+
+	//* Creation / loading methods ********************************************
+	PixelData GLTexture::lockImpl(GpuLockOptions options, UINT32 mipLevel, UINT32 face)
+	{
+		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;
+
+		PixelData lockedArea(mipWidth, mipHeight, mipDepth, mFormat);
+
+		mLockedBuffer = getBuffer(face, mipLevel);
+		lockedArea.data = mLockedBuffer->lock(options);
+
+		return lockedArea;
+	}
+	/****************************************************************************************/
+	void GLTexture::unlockImpl()
+	{
+		if(mLockedBuffer == nullptr)
+			CM_EXCEPT(InternalErrorException, "Trying to unlock a buffer that's not locked.");
+
+		mLockedBuffer->unlock();
+		mLockedBuffer = nullptr;
+	}
+	/****************************************************************************************/ 
+	void GLTexture::copyImpl(TexturePtr& target)
+	{
+		size_t numMips = std::min(getNumMipmaps(), target->getNumMipmaps());
+
+		GLTexture* glTexture = static_cast<GLTexture*>(target.get());
+		for(unsigned int face=0; face<getNumFaces(); face++)
+		{
+			for(unsigned int mip=0; mip<=numMips; mip++)
+			{
+				glTexture->getBuffer(face, mip)->blit(getBuffer(face, mip));
+			}
+		}
+	}
 	//---------------------------------------------------------------------------------------------
 	//---------------------------------------------------------------------------------------------
 	void GLTexture::createSurfaceList()
 	void GLTexture::createSurfaceList()
 	{
 	{
@@ -320,15 +316,6 @@ namespace CamelotEngine {
 		assert(idx < mSurfaceList.size());
 		assert(idx < mSurfaceList.size());
 		return mSurfaceList[idx];
 		return mSurfaceList[idx];
 	}
 	}
-	//---------------------------------------------------------------------------------------------
-	void GLTexture::getCustomAttribute(const String& name, void* pData)
-	{
-		THROW_IF_NOT_RENDER_THREAD;
-
-		if (name == "GLID")
-			*static_cast<GLuint*>(pData) = mTextureID;
-	}
-	
 }
 }
 
 
 #undef THROW_IF_NOT_RENDER_THREAD
 #undef THROW_IF_NOT_RENDER_THREAD

+ 10 - 2
CamelotGLRenderer/Source/GLSL/include/CmGLSLGpuProgram.h

@@ -79,8 +79,16 @@ namespace CamelotEngine {
 
 
         /// Overridden from GpuProgram
         /// Overridden from GpuProgram
         void loadFromSource(void);
         void loadFromSource(void);
-		/// @copydoc Resource::loadImpl
-		void initialize_internal(void);
+
+		/**
+		 * @copydoc GpuProgram::initialize_internal
+		 */
+		void initialize_internal();
+
+		/**
+		 * @copydoc GpuProgram::destroy_internal
+		 */
+		void destroy_internal();
     };
     };
 }
 }
 
 

+ 2 - 2
CamelotGLRenderer/Source/GLSL/include/CmGLSLProgram.h

@@ -109,9 +109,9 @@ namespace CamelotEngine {
         void loadFromSource(void);
         void loadFromSource(void);
 
 
 		/**
 		/**
-		 * @copydoc GpuProgram::unload_internal()
+		 * @copydoc GpuProgram::destroy_internal()
 		 */
 		 */
-		void unload_internal();
+		void destroy_internal();
 
 
 	private:
 	private:
 		/// GL handle for shader object
 		/// GL handle for shader object

+ 6 - 3
CamelotGLRenderer/Source/GLSL/src/CmGLSLGpuProgram.cpp

@@ -70,9 +70,6 @@ namespace CamelotEngine {
     //-----------------------------------------------------------------------
     //-----------------------------------------------------------------------
     GLSLGpuProgram::~GLSLGpuProgram()
     GLSLGpuProgram::~GLSLGpuProgram()
     {
     {
-        // have to call this here reather than in Resource destructor
-        // since calling virtual methods in base destructors causes crash
-        unload_internal(); 
     }
     }
 	//-----------------------------------------------------------------------------
 	//-----------------------------------------------------------------------------
     void GLSLGpuProgram::initialize_internal(void)
     void GLSLGpuProgram::initialize_internal(void)
@@ -85,5 +82,11 @@ namespace CamelotEngine {
     {
     {
 		// nothing to load
 		// nothing to load
 	}
 	}
+	//-----------------------------------------------------------------------------
+	void GLSLGpuProgram::destroy_internal()
+	{
+		// Nothing to destroy
+		GpuProgram::destroy();
+	}
 }
 }
 
 

+ 7 - 7
CamelotGLRenderer/Source/GLSL/src/CmGLSLProgram.cpp

@@ -44,11 +44,6 @@ THE SOFTWARE.
 
 
 namespace CamelotEngine 
 namespace CamelotEngine 
 {
 {
-    //---------------------------------------------------------------------------
-    GLSLProgram::~GLSLProgram()
-    {
-        unload_internal();
-    }
 	//-----------------------------------------------------------------------
 	//-----------------------------------------------------------------------
 	GLSLProgram::GLSLProgram(const String& source, const String& entryPoint, const String& language, 
 	GLSLProgram::GLSLProgram(const String& source, const String& entryPoint, const String& language, 
 		GpuProgramType gptype, GpuProgramProfile profile, bool isAdjacencyInfoRequired)
 		GpuProgramType gptype, GpuProgramProfile profile, bool isAdjacencyInfoRequired)
@@ -59,6 +54,11 @@ namespace CamelotEngine
 		// Manually assign language now since we use it immediately
 		// Manually assign language now since we use it immediately
 		mSyntaxCode = "glsl";
 		mSyntaxCode = "glsl";
 
 
+	}
+	//---------------------------------------------------------------------------
+	GLSLProgram::~GLSLProgram()
+	{
+
 	}
 	}
     //-----------------------------------------------------------------------
     //-----------------------------------------------------------------------
 	void GLSLProgram::loadFromSource(void)
 	void GLSLProgram::loadFromSource(void)
@@ -172,7 +172,7 @@ namespace CamelotEngine
 		paramParser.buildVertexDeclaration(mGLHandle, mVertexDeclaration);
 		paramParser.buildVertexDeclaration(mGLHandle, mVertexDeclaration);
 	}
 	}
 	//---------------------------------------------------------------------------
 	//---------------------------------------------------------------------------
-	void GLSLProgram::unload_internal()
+	void GLSLProgram::destroy_internal()
 	{   
 	{   
 		// We didn't create mAssemblerProgram through a manager, so override this
 		// 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()
 		// implementation so that we don't try to remove it from one. Since getCreator()
@@ -182,7 +182,7 @@ namespace CamelotEngine
 		if (isSupported())
 		if (isSupported())
 			glDeleteShader(mGLHandle);
 			glDeleteShader(mGLHandle);
 
 
-		HighLevelGpuProgram::unload_internal();
+		HighLevelGpuProgram::destroy_internal();
 	}
 	}
     //-----------------------------------------------------------------------
     //-----------------------------------------------------------------------
     const String& GLSLProgram::getLanguage(void) const
     const String& GLSLProgram::getLanguage(void) const

+ 39 - 49
CamelotRenderer/Include/CmGpuProgram.h

@@ -97,57 +97,14 @@ namespace CamelotEngine {
 	*/
 	*/
 	class CM_EXPORT GpuProgram : public Resource
 	class CM_EXPORT GpuProgram : public Resource
 	{
 	{
-	protected:
-		/// The type of the program
-		GpuProgramType mType;
-		/// Does this (geometry) program require adjacency information?
-		bool mNeedsAdjacencyInfo;
-		/// Name of the shader entry method
-		String mEntryPoint;
-		/// Shader profiler that we are targeting (e.g. vs_1_1, etc.). Make sure profile matches the type.
-		GpuProgramProfile mProfile;
-        /// The assembler source of the program (may be blank until file loaded)
-        String mSource;
-        /// Syntax code e.g. arbvp1, vs_2_0 etc
-        String mSyntaxCode;
-		/// Did we encounter a compilation error?
-		bool mCompileError;
-
-		/**
-		 * @brief	Contains information about all parameters in a shader.
-		 */
-		GpuParamDesc mParametersDesc;
-
-        /** Internal method returns whether required capabilities for this program is supported.
-        */
-        bool isRequiredCapabilitiesSupported(void) const;
-
-		/// @copydoc Resource::calculateSize
-		size_t calculateSize(void) const { return 0; } // TODO 
-
-		void throwIfNotRenderThread() const;
-
 	public:
 	public:
 		virtual ~GpuProgram();
 		virtual ~GpuProgram();
 
 
-		/**
-		 * @brief	Initializes the gpu program. This must be called right after the program is constructed. 
-		 * 			Called by GpuProgramManager upon creation, so usually you don't want to call this manually. 
-		 * 			
-		 * @note	Initialization is not done immediately, and is instead just scheduled on the render thread.
-		 */
-		void initialize();
-
 		/**
 		/**
 		 * @brief	Performs GpuProgram initialization. Only callable from the render thread.
 		 * @brief	Performs GpuProgram initialization. Only callable from the render thread.
 		 */
 		 */
 		virtual void initialize_internal();
 		virtual void initialize_internal();
 
 
-		/**
-		 * @brief	Unloads the GpuProgram. Only callable from the render thread.
-		 */
-		virtual void unload_internal();
-
         /** Gets the syntax code for this program e.g. arbvp1, fp20, vs_1_1 etc */
         /** Gets the syntax code for this program e.g. arbvp1, fp20, vs_1_1 etc */
         virtual const String& getSyntaxCode(void) const { return mSyntaxCode; }
         virtual const String& getSyntaxCode(void) const { return mSyntaxCode; }
 
 
@@ -190,13 +147,46 @@ namespace CamelotEngine {
         */
         */
         virtual const String& getLanguage(void) const;
         virtual const String& getLanguage(void) const;
 
 
-		/** Did this program encounter a compile error when loading?
-		*/
-		virtual bool hasCompileError(void) const { return mCompileError; }
+	protected:
+		/// The type of the program
+		GpuProgramType mType;
+		/// Does this (geometry) program require adjacency information?
+		bool mNeedsAdjacencyInfo;
+		/// Name of the shader entry method
+		String mEntryPoint;
+		/// Shader profiler that we are targeting (e.g. vs_1_1, etc.). Make sure profile matches the type.
+		GpuProgramProfile mProfile;
+        /// The assembler source of the program (may be blank until file loaded)
+        String mSource;
+        /// Syntax code e.g. arbvp1, vs_2_0 etc
+        String mSyntaxCode;
 
 
-		/** Reset a compile error if it occurred, allowing the load to be retried
-		*/
-		virtual void resetCompileError(void) { mCompileError = false; }
+		/**
+		 * @brief	Contains information about all parameters in a shader.
+		 */
+		GpuParamDesc mParametersDesc;
+
+		/**
+		 * @brief	Initializes the gpu program. This must be called right after the program is constructed. 
+		 * 			Called by GpuProgramManager upon creation, so usually you don't want to call this manually. 
+		 * 			
+		 * @note	Initialization is not done immediately, and is instead just scheduled on the render thread.
+		 */
+		void initialize();
+
+		/**
+		 * @copydoc Resource::destroy_internal.
+		 */
+		virtual void destroy_internal();
+
+        /** Internal method returns whether required capabilities for this program is supported.
+        */
+        bool isRequiredCapabilitiesSupported(void) const;
+
+		/// @copydoc Resource::calculateSize
+		size_t calculateSize(void) const { return 0; } // TODO 
+
+		void throwIfNotRenderThread() const;
 
 
     protected:
     protected:
 		friend class GpuProgramManager;
 		friend class GpuProgramManager;

+ 5 - 5
CamelotRenderer/Include/CmHighLevelGpuProgram.h

@@ -84,11 +84,6 @@ namespace CamelotEngine {
 		 */
 		 */
 		virtual void initialize_internal();
 		virtual void initialize_internal();
 
 
-		/**
-		 * @copydoc GpuProgram::unload_internal()
-		 */
-		virtual void unload_internal();
-
         /** @copydoc GpuProgram::getBindingDelegate */
         /** @copydoc GpuProgram::getBindingDelegate */
         virtual GpuProgram* getBindingDelegate(void) { return mAssemblerProgram.get(); }
         virtual GpuProgram* getBindingDelegate(void) { return mAssemblerProgram.get(); }
 
 
@@ -97,6 +92,11 @@ namespace CamelotEngine {
 		HighLevelGpuProgram(const String& source, const String& entryPoint, const String& language, 
 		HighLevelGpuProgram(const String& source, const String& entryPoint, const String& language, 
 			GpuProgramType gptype, GpuProgramProfile profile, bool isAdjacencyInfoRequired = false);
 			GpuProgramType gptype, GpuProgramProfile profile, bool isAdjacencyInfoRequired = false);
 
 
+		/**
+		 * @copydoc GpuProgram::unload_internal()
+		 */
+		virtual void destroy_internal();
+
         /// The underlying assembler program
         /// The underlying assembler program
         GpuProgramPtr mAssemblerProgram;
         GpuProgramPtr mAssemblerProgram;
 
 

+ 18 - 5
CamelotRenderer/Include/CmResource.h

@@ -2,18 +2,21 @@
 
 
 #include "CmPrerequisites.h"
 #include "CmPrerequisites.h"
 #include "CmIReflectable.h"
 #include "CmIReflectable.h"
+#include "CmIDestroyable.h"
 
 
 namespace CamelotEngine
 namespace CamelotEngine
 {
 {
 	/**
 	/**
 	 * @brief	Base class for all resources used in the engine.
 	 * @brief	Base class for all resources used in the engine.
 	 */
 	 */
-	class CM_EXPORT Resource : public IReflectable
+	class CM_EXPORT Resource : public IReflectable, public IDestroyable
 	{
 	{
 	public:
 	public:
 		Resource();
 		Resource();
 		virtual ~Resource() {};
 		virtual ~Resource() {};
 
 
+
+
 		const String& getUUID() const { return mUUID; }
 		const String& getUUID() const { return mUUID; }
 
 
 		/**
 		/**
@@ -27,12 +30,17 @@ namespace CamelotEngine
 		 */
 		 */
 		void waitUntilInitialized();
 		void waitUntilInitialized();
 
 
+		/**
+		 * @copydoc	IDestroyable::destroy()
+		 * 			
+		 * 	@note	Destruction is not done immediately, and is instead just scheduled on the
+		 * 			render thread. Unless internalCall is specified, in which case it is destroyed
+		 * 			right away. But you should only do this when calling from the render thread.
+		 */
+		void destroy(bool internalCall = false);
+
 	protected:
 	protected:
 		friend class Resources;
 		friend class Resources;
-		//virtual void unload() = 0;
-
-		//virtual void calculateSize() = 0;
-		//virtual void reload();
 		
 		
 		/**
 		/**
 		 * @brief	Finishes up resource initialization. Usually called right after the resource is created.
 		 * @brief	Finishes up resource initialization. Usually called right after the resource is created.
@@ -41,6 +49,11 @@ namespace CamelotEngine
 		 */
 		 */
 		virtual void initialize_internal();
 		virtual void initialize_internal();
 
 
+		/**
+		 * @brief	Destroys all texture resources, but doesn't actually delete the object.
+		 */
+		virtual void destroy_internal() {} // TODO - This is temporarily non-abstract
+
 		/**
 		/**
 		 * @brief	Marks the resource as initialized.
 		 * @brief	Marks the resource as initialized.
 		 */
 		 */

+ 1 - 41
CamelotRenderer/Include/CmTexture.h

@@ -137,13 +137,6 @@ namespace CamelotEngine {
         */
         */
         virtual UINT32 getNumFaces() const;
         virtual UINT32 getNumFaces() const;
 
 
-		/** Retrieve a platform or API-specific piece of information from this texture.
-		 This method of retrieving information should only be used if you know what you're doing.
-		 @param name The name of the attribute to retrieve
-		 @param pData Pointer to memory matching the type of data you want to retrieve.
-		*/
-		virtual void getCustomAttribute(const String& name, void* pData);
-
 		/**
 		/**
 		 * @brief	Sets raw texture pixels for the specified mip level and texture face. Pixel format
 		 * @brief	Sets raw texture pixels for the specified mip level and texture face. Pixel format
 		 * 			must match the format of the texture.
 		 * 			must match the format of the texture.
@@ -258,15 +251,10 @@ namespace CamelotEngine {
 		 * 							
 		 * 							
 		 * @note	Initialization is not done immediately, and is instead just scheduled on the
 		 * @note	Initialization is not done immediately, and is instead just scheduled on the
 		 * 			render thread. Unless internalCall is specified, in which case it is initialized
 		 * 			render thread. Unless internalCall is specified, in which case it is initialized
-		 * 			right away.
+		 * 			right away. But you should only do this when calling from the render thread.
 		 */
 		 */
 		void initialize(TextureType textureType, UINT32 width, UINT32 height, UINT32 depth, UINT32 numMipmaps, 
 		void initialize(TextureType textureType, UINT32 width, UINT32 height, UINT32 depth, UINT32 numMipmaps, 
 			PixelFormat format, int usage, bool hwGamma, UINT32 fsaa, const String& fsaaHint, bool internalCall = false);
 			PixelFormat format, int usage, bool hwGamma, UINT32 fsaa, const String& fsaaHint, bool internalCall = false);
-		
-		/**
-		 * @brief	Performs GpuProgram initialization. Only callable from the render thread.
-		 */
-		virtual void initialize_internal() = 0;
 
 
 		virtual PixelData lockImpl(GpuLockOptions options, UINT32 mipLevel = 0, UINT32 face = 0) = 0;
 		virtual PixelData lockImpl(GpuLockOptions options, UINT32 mipLevel = 0, UINT32 face = 0) = 0;
 		virtual void unlockImpl() = 0;
 		virtual void unlockImpl() = 0;
@@ -276,34 +264,6 @@ namespace CamelotEngine {
 		/// @copydoc Resource::calculateSize
 		/// @copydoc Resource::calculateSize
 		UINT32 calculateSize(void) const;
 		UINT32 calculateSize(void) const;
 
 
-        /** Creates the internal texture resources for this texture. 
-        @remarks
-            This method creates the internal texture resources (pixel buffers, 
-            texture surfaces etc) required to begin using this texture. You do
-            not need to call this method directly unless you are manually creating
-            a texture, in which case something must call it, after having set the
-            size and format of the texture (e.g. the ManualResourceLoader might
-            be the best one to call it). If you are not defining a manual texture,
-            or if you use one of the self-contained load...() methods, then it will be
-            called for you.
-        */
-        virtual void createInternalResources(void);
-
-        /** Frees internal texture resources for this texture. 
-        */
-        virtual void freeInternalResources(void);
-
-		/** Implementation of creating internal texture resources 
-		*/
-		virtual void createInternalResourcesImpl(void) = 0;
-
-		/** Implementation of freeing internal texture resources 
-		*/
-		virtual void freeInternalResourcesImpl(void) = 0;
-
-		/** Default implementation of unload which calls freeInternalResources */
-		void unloadImpl(void);
-
 		void throwIfNotRenderThread() const;
 		void throwIfNotRenderThread() const;
 
 
 		/************************************************************************/
 		/************************************************************************/

+ 3 - 3
CamelotRenderer/Source/CmCgProgram.cpp

@@ -95,7 +95,7 @@ namespace CamelotEngine {
             "Unable to compile Cg program", mCgContext);
             "Unable to compile Cg program", mCgContext);
 
 
 		// ignore any previous error
 		// ignore any previous error
-		if (mSelectedCgProfile != CG_PROFILE_UNKNOWN && !mCompileError)
+		if (mSelectedCgProfile != CG_PROFILE_UNKNOWN)
 		{
 		{
 			String sourceFromCg = cgGetProgramString(mCgProgram, CG_COMPILED_PROGRAM);
 			String sourceFromCg = cgGetProgramString(mCgProgram, CG_COMPILED_PROGRAM);
 
 
@@ -115,7 +115,7 @@ namespace CamelotEngine {
 
 
     void CgProgram::unload_internal(void)
     void CgProgram::unload_internal(void)
     {
     {
-		HighLevelGpuProgram::unload_internal();
+		HighLevelGpuProgram::destroy_internal();
     }
     }
 
 
 	GpuParamsPtr CgProgram::createParameters()
 	GpuParamsPtr CgProgram::createParameters()
@@ -154,7 +154,7 @@ namespace CamelotEngine {
 
 
     bool CgProgram::isSupported(void) const
     bool CgProgram::isSupported(void) const
     {
     {
-        if (mCompileError || !isRequiredCapabilitiesSupported())
+        if (!isRequiredCapabilitiesSupported())
             return false;
             return false;
 
 
 		String selectedProfile = GpuProgramManager::instance().gpuProgProfileToRSSpecificProfile(mProfile);
 		String selectedProfile = GpuProgramManager::instance().gpuProgProfileToRSSpecificProfile(mProfile);

+ 8 - 21
CamelotRenderer/Source/CmGpuProgram.cpp

@@ -48,14 +48,13 @@ namespace CamelotEngine
     GpuProgram::GpuProgram(const String& source, const String& entryPoint, const String& language, 
     GpuProgram::GpuProgram(const String& source, const String& entryPoint, const String& language, 
 		GpuProgramType gptype, GpuProgramProfile profile, bool isAdjacencyInfoRequired) 
 		GpuProgramType gptype, GpuProgramProfile profile, bool isAdjacencyInfoRequired) 
         :mSource(source), mEntryPoint(entryPoint), mSyntaxCode(language), mType(gptype),
         :mSource(source), mEntryPoint(entryPoint), mSyntaxCode(language), mType(gptype),
-		mProfile(profile), mNeedsAdjacencyInfo(isAdjacencyInfoRequired), mCompileError(false)
+		mProfile(profile), mNeedsAdjacencyInfo(isAdjacencyInfoRequired)
     {
     {
 
 
     }
     }
 	//----------------------------------------------------------------------------
 	//----------------------------------------------------------------------------
 	GpuProgram::~GpuProgram()
 	GpuProgram::~GpuProgram()
 	{
 	{
-		THROW_IF_NOT_RENDER_THREAD;
 	}
 	}
 	//-----------------------------------------------------------------------------
 	//-----------------------------------------------------------------------------
 	void GpuProgram::initialize()
 	void GpuProgram::initialize()
@@ -65,32 +64,20 @@ namespace CamelotEngine
     //-----------------------------------------------------------------------------
     //-----------------------------------------------------------------------------
     void GpuProgram::initialize_internal(void)
     void GpuProgram::initialize_internal(void)
     {
     {
-        // Call polymorphic load
-		try 
-		{
-			loadFromSource();
+		loadFromSource();
 
 
-			Resource::initialize_internal();
-		}
-		catch (const Exception&)
-		{
-			// will already have been logged
-			//LogManager::getSingleton().stream()
-			//	<< "Gpu program " << mName << " encountered an error "
-			//	<< "during loading and is thus not supported.";
-
-			mCompileError = true;
-		}
+		Resource::initialize_internal();
     }
     }
-	//-----------------------------------------------------------------------------
-	void GpuProgram::unload_internal()
+	//---------------------------------------------------------------------------
+	void GpuProgram::destroy_internal()
 	{
 	{
-		THROW_IF_NOT_RENDER_THREAD;
+		// Nothing to destroy
+		IDestroyable::destroy();
 	}
 	}
     //-----------------------------------------------------------------------------
     //-----------------------------------------------------------------------------
     bool GpuProgram::isSupported(void) const
     bool GpuProgram::isSupported(void) const
     {
     {
-        if (mCompileError || !isRequiredCapabilitiesSupported())
+        if (!isRequiredCapabilitiesSupported())
             return false;
             return false;
 
 
 		RenderSystem* rs = CamelotEngine::RenderSystem::instancePtr();
 		RenderSystem* rs = CamelotEngine::RenderSystem::instancePtr();

+ 7 - 9
CamelotRenderer/Source/CmHighLevelGpuProgram.cpp

@@ -47,6 +47,11 @@ namespace CamelotEngine
         mAssemblerProgram(0)
         mAssemblerProgram(0)
     {
     {
     }
     }
+	//---------------------------------------------------------------------------
+	HighLevelGpuProgram::~HighLevelGpuProgram()
+	{
+
+	}
 	//---------------------------------------------------------------------------
 	//---------------------------------------------------------------------------
 	void HighLevelGpuProgram::initialize(bool internalCall)
 	void HighLevelGpuProgram::initialize(bool internalCall)
 	{
 	{
@@ -73,21 +78,14 @@ namespace CamelotEngine
 		Resource::initialize_internal();
 		Resource::initialize_internal();
     }
     }
     //---------------------------------------------------------------------------
     //---------------------------------------------------------------------------
-    void HighLevelGpuProgram::unload_internal()
+    void HighLevelGpuProgram::destroy_internal()
     {   
     {   
         if (mAssemblerProgram != nullptr && mAssemblerProgram.get() != this)
         if (mAssemblerProgram != nullptr && mAssemblerProgram.get() != this)
         {
         {
             mAssemblerProgram = nullptr;
             mAssemblerProgram = nullptr;
         }
         }
 
 
-		resetCompileError();
-
-		GpuProgram::unload_internal();
-    }
-    //---------------------------------------------------------------------------
-    HighLevelGpuProgram::~HighLevelGpuProgram()
-    {
-        // superclasses will trigger unload
+		GpuProgram::destroy_internal();
     }
     }
 	//---------------------------------------------------------------------
 	//---------------------------------------------------------------------
 	HighLevelGpuProgramPtr HighLevelGpuProgram::create(const String& source, const String& entryPoint, 
 	HighLevelGpuProgramPtr HighLevelGpuProgram::create(const String& source, const String& entryPoint, 

+ 8 - 0
CamelotRenderer/Source/CmResource.cpp

@@ -26,6 +26,14 @@ namespace CamelotEngine
 		CM_THREAD_NOTIFY_ALL(mResourceLoadedCondition);
 		CM_THREAD_NOTIFY_ALL(mResourceLoadedCondition);
 	}
 	}
 
 
+	void Resource::destroy(bool internalCall)
+	{
+		if(internalCall)
+			destroy_internal();
+		else
+			RenderSystem::instancePtr()->queueCommand(boost::bind(&Texture::destroy_internal, this));
+	}
+
 	void Resource::waitUntilInitialized()
 	void Resource::waitUntilInitialized()
 	{
 	{
 #if CM_DEBUG_MODE
 #if CM_DEBUG_MODE

+ 0 - 23
CamelotRenderer/Source/CmTexture.cpp

@@ -93,22 +93,6 @@ namespace CamelotEngine {
 	{
 	{
 		return getTextureType() == TEX_TYPE_CUBE_MAP ? 6 : 1;
 		return getTextureType() == TEX_TYPE_CUBE_MAP ? 6 : 1;
 	}
 	}
-	//-------------------------------------------------------------------------
-	void Texture::getCustomAttribute(const String& name, void* pData)
-	{
-		THROW_IF_NOT_RENDER_THREAD;
-	}
-	//-----------------------------------------------------------------------------
-	void Texture::createInternalResources(void)
-	{
-		createInternalResourcesImpl();
-	}
-	//-----------------------------------------------------------------------------
-	void Texture::freeInternalResources(void)
-	{
-		freeInternalResourcesImpl();
-		clearBufferViews();
-	}
 
 
 	void Texture::setRawPixels(const PixelData& data, UINT32 face, UINT32 mip)
 	void Texture::setRawPixels(const PixelData& data, UINT32 face, UINT32 mip)
 	{
 	{
@@ -224,13 +208,6 @@ namespace CamelotEngine {
 
 
 		copyImpl(target);
 		copyImpl(target);
 	}
 	}
-	//-----------------------------------------------------------------------------
-	void Texture::unloadImpl(void)
-	{
-		THROW_IF_NOT_RENDER_THREAD;
-
-		freeInternalResources();
-	}
 	//----------------------------------------------------------------------------- 
 	//----------------------------------------------------------------------------- 
 	void Texture::throwIfNotRenderThread() const
 	void Texture::throwIfNotRenderThread() const
 	{
 	{

+ 11 - 0
CamelotRenderer/TODO.txt

@@ -20,6 +20,17 @@ Pass
  - Fix MaterialRTTI saving (Save params per gpuprogram is simplest and cleanest) (Maybe wait until I have the Parser sorted out?)
  - Fix MaterialRTTI saving (Save params per gpuprogram is simplest and cleanest) (Maybe wait until I have the Parser sorted out?)
  - Fix how and when is GpuParamBlock created/destroyed. Needs to happen on the render thread
  - Fix how and when is GpuParamBlock created/destroyed. Needs to happen on the render thread
 
 
+Resource destruction:
+Resources keep a permanent reference to each resource so they are never freed
+ - Keep just a weak ptr?
+
+OR
+
+Keep a strong ptr, when Resource::destroy() internally calls Resources to remove the reference?
+And Resources.DestroyUnusedAssets destroys all with just 1 reference?
+
+Resource::destroy_internal is not abstract temporarily so I can test
+
 Shader parser (possible leave for later? But it might require Resource changes)
 Shader parser (possible leave for later? But it might require Resource changes)
  - Static/Dynamic usage for GpuParamBlocks
  - Static/Dynamic usage for GpuParamBlocks
  - Ability to mark param blocks as "Shared". Those would not get created with every pass instance and would require user to actually create and assign them
  - Ability to mark param blocks as "Shared". Those would not get created with every pass instance and would require user to actually create and assign them

+ 2 - 0
CamelotUtility/CamelotUtility.vcxproj

@@ -157,6 +157,7 @@
   </ItemDefinitionGroup>
   </ItemDefinitionGroup>
   <ItemGroup>
   <ItemGroup>
     <ClCompile Include="..\CamelotRenderer\Source\CmManagedDataBlock.cpp" />
     <ClCompile Include="..\CamelotRenderer\Source\CmManagedDataBlock.cpp" />
+    <ClCompile Include="Source\CmIDestroyable.cpp" />
     <ClCompile Include="Source\CmInt2.cpp" />
     <ClCompile Include="Source\CmInt2.cpp" />
     <ClCompile Include="Source\CmPixelData.cpp" />
     <ClCompile Include="Source\CmPixelData.cpp" />
     <ClCompile Include="Source\CmUUID.cpp" />
     <ClCompile Include="Source\CmUUID.cpp" />
@@ -172,6 +173,7 @@
     <ClInclude Include="Include\CmException.h" />
     <ClInclude Include="Include\CmException.h" />
     <ClInclude Include="Include\CmFileSerializer.h" />
     <ClInclude Include="Include\CmFileSerializer.h" />
     <ClInclude Include="Include\CmFileSystem.h" />
     <ClInclude Include="Include\CmFileSystem.h" />
+    <ClInclude Include="Include\CmIDestroyable.h" />
     <ClInclude Include="Include\CmInt2.h" />
     <ClInclude Include="Include\CmInt2.h" />
     <ClInclude Include="Include\CmIReflectable.h" />
     <ClInclude Include="Include\CmIReflectable.h" />
     <ClInclude Include="Include\CmKeyValuePair.h" />
     <ClInclude Include="Include\CmKeyValuePair.h" />

+ 6 - 0
CamelotUtility/CamelotUtility.vcxproj.filters

@@ -207,6 +207,9 @@
     <ClInclude Include="Include\CmUtil.h">
     <ClInclude Include="Include\CmUtil.h">
       <Filter>Header Files</Filter>
       <Filter>Header Files</Filter>
     </ClInclude>
     </ClInclude>
+    <ClInclude Include="Include\CmIDestroyable.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
   </ItemGroup>
   </ItemGroup>
   <ItemGroup>
   <ItemGroup>
     <ClCompile Include="Include\CmAxisAlignedBox.cpp">
     <ClCompile Include="Include\CmAxisAlignedBox.cpp">
@@ -302,5 +305,8 @@
     <ClCompile Include="Source\CmPixelData.cpp">
     <ClCompile Include="Source\CmPixelData.cpp">
       <Filter>Source Files</Filter>
       <Filter>Source Files</Filter>
     </ClCompile>
     </ClCompile>
+    <ClCompile Include="Source\CmIDestroyable.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
   </ItemGroup>
   </ItemGroup>
 </Project>
 </Project>

+ 25 - 0
CamelotUtility/Include/CmIDestroyable.h

@@ -0,0 +1,25 @@
+#pragma once
+
+#include "CmPrerequisitesUtil.h"
+
+namespace CamelotEngine
+{
+	/**
+	 * @brief	Classes deriving from this interface need to be destroyed with the help of a destroy() method,
+	 * 			before their actual destructor is called.
+	 */
+	class CM_UTILITY_EXPORT IDestroyable
+	{
+	public:
+		IDestroyable();
+		virtual ~IDestroyable();
+
+		/**
+		 * @brief	Destroys this object. Make sure to call this before deleting the object.
+		 */
+		virtual void destroy();
+
+	private:
+		bool mDestroyed;
+	};
+}

+ 22 - 0
CamelotUtility/Source/CmIDestroyable.cpp

@@ -0,0 +1,22 @@
+#include "CmIDestroyable.h"
+#include "CmDebug.h"
+
+namespace CamelotEngine
+{
+	IDestroyable::IDestroyable()
+		:mDestroyed(false)
+	{ }
+
+	IDestroyable::~IDestroyable() 
+	{
+		if(!mDestroyed)
+		{
+			LOGWRN("Destructor called but object is not destroyed. Object will leak.")
+		}
+	}
+
+	void IDestroyable::destroy()
+	{
+		mDestroyed = true;
+	}
+}