Browse Source

Finished up adding MultiRenderTextures

Marko Pintera 13 years ago
parent
commit
978cea27c4
35 changed files with 630 additions and 102 deletions
  1. 2 0
      CamelotD3D11RenderSystem/CamelotD3D11RenderSystem.vcxproj
  2. 6 0
      CamelotD3D11RenderSystem/CamelotD3D11RenderSystem.vcxproj.filters
  3. 1 0
      CamelotD3D11RenderSystem/Include/CmD3D11DepthStencilBuffer.h
  4. 26 0
      CamelotD3D11RenderSystem/Include/CmD3D11MultiRenderTexture.h
  5. 6 1
      CamelotD3D11RenderSystem/Include/CmD3D11RenderTexture.h
  6. 5 0
      CamelotD3D11RenderSystem/Include/CmD3D11TextureManager.h
  7. 58 0
      CamelotD3D11RenderSystem/Source/CmD3D11MultiRenderTexture.cpp
  8. 50 23
      CamelotD3D11RenderSystem/Source/CmD3D11RenderTexture.cpp
  9. 9 0
      CamelotD3D11RenderSystem/Source/CmD3D11TextureManager.cpp
  10. 2 0
      CamelotD3D9Renderer/CamelotD3D9Renderer.vcxproj
  11. 6 0
      CamelotD3D9Renderer/CamelotD3D9Renderer.vcxproj.filters
  12. 28 0
      CamelotD3D9Renderer/Include/CmD3D9MultiRenderTexture.h
  13. 4 1
      CamelotD3D9Renderer/Include/CmD3D9RenderTexture.h
  14. 5 0
      CamelotD3D9Renderer/Include/CmD3D9TextureManager.h
  15. 75 0
      CamelotD3D9Renderer/Source/CmD3D9MultiRenderTexture.cpp
  16. 2 2
      CamelotD3D9Renderer/Source/CmD3D9RenderTexture.cpp
  17. 9 0
      CamelotD3D9Renderer/Source/CmD3D9TextureManager.cpp
  18. 2 0
      CamelotGLRenderer/CamelotGLRenderer.vcxproj
  19. 6 0
      CamelotGLRenderer/CamelotGLRenderer.vcxproj.filters
  20. 27 0
      CamelotGLRenderer/Include/CmGLMultiRenderTexture.h
  21. 3 1
      CamelotGLRenderer/Include/CmGLRenderTexture.h
  22. 5 0
      CamelotGLRenderer/Include/CmGLTextureManager.h
  23. 73 0
      CamelotGLRenderer/Source/CmGLMultiRenderTexture.cpp
  24. 2 2
      CamelotGLRenderer/Source/CmGLRenderTexture.cpp
  25. 9 0
      CamelotGLRenderer/Source/CmGLTextureManager.cpp
  26. 2 1
      CamelotRenderer/CamelotRenderer.vcxproj
  27. 5 2
      CamelotRenderer/CamelotRenderer.vcxproj.filters
  28. 0 32
      CamelotRenderer/Include/CmMultiRenderTexture.cpp
  29. 35 0
      CamelotRenderer/Include/CmMultiRenderTexture.h
  30. 2 1
      CamelotRenderer/Include/CmPrerequisites.h
  31. 9 0
      CamelotRenderer/Include/CmRenderTarget.h
  32. 2 9
      CamelotRenderer/Include/CmRenderTexture.h
  33. 6 1
      CamelotRenderer/Include/CmTextureManager.h
  34. 122 0
      CamelotRenderer/Source/CmMultiRenderTexture.cpp
  35. 26 26
      CamelotRenderer/Source/CmRenderTexture.cpp

+ 2 - 0
CamelotD3D11RenderSystem/CamelotD3D11RenderSystem.vcxproj

@@ -162,6 +162,7 @@
     <ClInclude Include="Include\CmD3D11HLSLProgramFactory.h" />
     <ClInclude Include="Include\CmD3D11HLSLProgramRTTI.h" />
     <ClInclude Include="Include\CmD3D11Mappings.h" />
+    <ClInclude Include="Include\CmD3D11MultiRenderTexture.h" />
     <ClInclude Include="Include\CmD3D11Prerequisites.h" />
     <ClInclude Include="Include\CmD3D11HardwareVertexBuffer.h" />
     <ClInclude Include="Include\CmD3D11RasterizerState.h" />
@@ -194,6 +195,7 @@
     <ClCompile Include="Source\CmD3D11HLSLProgramFactory.cpp" />
     <ClCompile Include="Source\CmD3D11Mappings.cpp" />
     <ClCompile Include="Source\CmD3D11HardwareVertexBuffer.cpp" />
+    <ClCompile Include="Source\CmD3D11MultiRenderTexture.cpp" />
     <ClCompile Include="Source\CmD3D11RasterizerState.cpp" />
     <ClCompile Include="Source\CmD3D11RenderStateManager.cpp" />
     <ClCompile Include="Source\CmD3D11RenderSystem.cpp" />

+ 6 - 0
CamelotD3D11RenderSystem/CamelotD3D11RenderSystem.vcxproj.filters

@@ -108,6 +108,9 @@
     <ClInclude Include="Include\CmD3D11BlendState.h">
       <Filter>Header Files</Filter>
     </ClInclude>
+    <ClInclude Include="Include\CmD3D11MultiRenderTexture.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="Source\CmD3D11GpuProgram.cpp">
@@ -194,5 +197,8 @@
     <ClCompile Include="Source\CmD3D11DepthStencilState.cpp">
       <Filter>Source Files</Filter>
     </ClCompile>
+    <ClCompile Include="Source\CmD3D11MultiRenderTexture.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
   </ItemGroup>
 </Project>

+ 1 - 0
CamelotD3D11RenderSystem/Include/CmD3D11DepthStencilBuffer.h

@@ -12,6 +12,7 @@ namespace CamelotEngine
 		~D3D11DepthStencilBuffer();
 
 		bool isCompatible(RenderTarget* renderTarget) const;
+		ID3D11DepthStencilView* getDepthStencilView() const { return mDepthStencilView; }
 
 	protected:
 		ID3D11Texture2D* mDepthStencil;

+ 26 - 0
CamelotD3D11RenderSystem/Include/CmD3D11MultiRenderTexture.h

@@ -0,0 +1,26 @@
+#pragma once
+
+#include "CmD3D11Prerequisites.h"
+#include "CmMultiRenderTexture.h"
+
+namespace CamelotEngine
+{
+	class CM_D3D11_EXPORT D3D11MultiRenderTexture : public MultiRenderTexture
+	{
+	public:
+		virtual ~D3D11MultiRenderTexture();
+
+		bool requiresTextureFlipping() const { return false; }
+		void getCustomAttribute(const String& name, void* pData);
+	protected:
+		friend class D3D11TextureManager;
+
+		D3D11MultiRenderTexture();
+		void initialize();
+
+		void setColorSurfaceImpl(UINT32 surfaceIdx, TexturePtr texture, UINT32 face = 0, UINT32 numFaces = 0, UINT32 mipLevel = 0);
+		void setDepthStencilImpl(DepthStencilBufferPtr depthStencilbuffer);
+
+		vector<ID3D11RenderTargetView*>::type mRenderTargetViews;
+	};
+}

+ 6 - 1
CamelotD3D11RenderSystem/Include/CmD3D11RenderTexture.h

@@ -9,14 +9,19 @@ namespace CamelotEngine
 	class D3D11RenderTexture : public RenderTexture
 	{
 	public:
-		D3D11RenderTexture();
 		virtual ~D3D11RenderTexture();
 
 		bool requiresTextureFlipping() const { return false; }
+		void getCustomAttribute(const String& name, void* pData);
+
+		static ID3D11RenderTargetView* createRenderTargetView(const SurfaceDesc& surfaceDesc);
 
 	protected:
+		friend class D3D11TextureManager;
+
 		ID3D11RenderTargetView* mRenderTargetView;
 
+		D3D11RenderTexture();
 		void createInternalResourcesImpl();
 	};
 }

+ 5 - 0
CamelotD3D11RenderSystem/Include/CmD3D11TextureManager.h

@@ -24,6 +24,11 @@ namespace CamelotEngine
 		DepthStencilBufferPtr createDepthStencilBuffer(DepthStencilFormat format, UINT32 width, 
 			UINT32 height, UINT32 fsaa, const String& fsaaHint);
 
+		/**
+		 * @copydoc TextureManager::createMultiRenderTexture()
+		 */
+		MultiRenderTexturePtr createMultiRenderTexture();
+
 	protected:		
 		Texture* createTextureImpl();
 		RenderTexture* createRenderTextureImpl();

+ 58 - 0
CamelotD3D11RenderSystem/Source/CmD3D11MultiRenderTexture.cpp

@@ -0,0 +1,58 @@
+#include "CmD3D11MultiRenderTexture.h"
+#include "CmD3D11DepthStencilBuffer.h"
+#include "CmD3D11Texture.h"
+#include "CmD3D11RenderTexture.h"
+
+namespace CamelotEngine
+{
+	D3D11MultiRenderTexture::D3D11MultiRenderTexture()
+		:MultiRenderTexture()
+	{
+
+	}
+
+	D3D11MultiRenderTexture::~D3D11MultiRenderTexture()
+	{
+
+	}
+
+	void D3D11MultiRenderTexture::setColorSurfaceImpl(UINT32 surfaceIdx, TexturePtr texture, UINT32 face, UINT32 numFaces, UINT32 mipLevel)
+	{
+		SAFE_RELEASE(mRenderTargetViews[surfaceIdx]);
+
+		if(texture != nullptr)
+		{
+			mRenderTargetViews[surfaceIdx] = D3D11RenderTexture::createRenderTargetView(mSurfaces[surfaceIdx]);
+		}
+	}
+
+	void D3D11MultiRenderTexture::setDepthStencilImpl(DepthStencilBufferPtr depthStencilBuffer)
+	{
+
+	}
+
+	void D3D11MultiRenderTexture::getCustomAttribute(const String& name, void* pData)
+	{
+		if(name == "RTV")
+		{
+			ID3D11RenderTargetView** pRTVs = (ID3D11RenderTargetView **)pData;
+			for(size_t x = 0; x < mRenderTargetViews.size(); ++x)							
+				pRTVs[x] = mRenderTargetViews[x];			
+
+			return;
+		}
+		else if(name == "DSV")
+		{
+			ID3D11DepthStencilView** pDSV = (ID3D11DepthStencilView **)pData;
+			D3D11DepthStencilBuffer* d3d11depthStencilBuffer = static_cast<D3D11DepthStencilBuffer*>(mDepthStencilBuffer.get());
+
+			*pDSV = d3d11depthStencilBuffer->getDepthStencilView();
+			return;
+		}
+	}
+
+	void D3D11MultiRenderTexture::initialize()
+	{
+		mRenderTargetViews.resize(CM_MAX_MULTIPLE_RENDER_TARGETS);
+	}
+}

+ 50 - 23
CamelotD3D11RenderSystem/Source/CmD3D11RenderTexture.cpp

@@ -1,5 +1,5 @@
 #include "CmD3D11RenderTexture.h"
-#include "CmDepthStencilBuffer.h"
+#include "CmD3D11DepthStencilBuffer.h"
 #include "CmD3D11RenderSystem.h"
 #include "CmD3D11Device.h"
 #include "CmD3D11Texture.h"
@@ -20,14 +20,12 @@ namespace CamelotEngine
 		SAFE_RELEASE(mRenderTargetView);
 	}
 
-	void D3D11RenderTexture::createInternalResourcesImpl()
-	{
-		SAFE_RELEASE(mRenderTargetView);
-
+	ID3D11RenderTargetView* D3D11RenderTexture::createRenderTargetView(const SurfaceDesc& surfaceDesc)
+	{
 		D3D11_RENDER_TARGET_VIEW_DESC RTVDesc;
 		ZeroMemory(&RTVDesc, sizeof(RTVDesc));
 
-		D3D11Texture* d3d11Texture = static_cast<D3D11Texture*>(mTexture.get());
+		D3D11Texture* d3d11Texture = static_cast<D3D11Texture*>(surfaceDesc.texture.get());
 
 		D3D11_SHADER_RESOURCE_VIEW_DESC SRVDesc = d3d11Texture->getSRVDesc();
 		RTVDesc.Format = SRVDesc.Format;
@@ -39,55 +37,84 @@ namespace CamelotEngine
 			break;
 		case D3D11_SRV_DIMENSION_TEXTURE1D:
 			RTVDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE1D;
-			RTVDesc.Texture1D.MipSlice = mMipLevel;
+			RTVDesc.Texture1D.MipSlice = surfaceDesc.mipLevel;
 			break;
 		case D3D11_SRV_DIMENSION_TEXTURE1DARRAY:
 			RTVDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE1DARRAY;
-			RTVDesc.Texture1DArray.FirstArraySlice = mFace;
-			RTVDesc.Texture1DArray.ArraySize = mNumFaces;
-			RTVDesc.Texture1DArray.MipSlice = mMipLevel;
+			RTVDesc.Texture1DArray.FirstArraySlice = surfaceDesc.face;
+			RTVDesc.Texture1DArray.ArraySize = surfaceDesc.numFaces;
+			RTVDesc.Texture1DArray.MipSlice = surfaceDesc.mipLevel;
 			break;
 		case D3D11_SRV_DIMENSION_TEXTURECUBE:
 			RTVDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY;
-			RTVDesc.Texture2DArray.FirstArraySlice = mFace;
-			RTVDesc.Texture2DArray.ArraySize = mNumFaces;
-			RTVDesc.Texture2DArray.MipSlice = mMipLevel;
+			RTVDesc.Texture2DArray.FirstArraySlice = surfaceDesc.face;
+			RTVDesc.Texture2DArray.ArraySize = surfaceDesc.numFaces;
+			RTVDesc.Texture2DArray.MipSlice = surfaceDesc.mipLevel;
 			break;
 		case D3D11_SRV_DIMENSION_TEXTURE2D:
 			RTVDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
-			RTVDesc.Texture2D.MipSlice = mMipLevel;
+			RTVDesc.Texture2D.MipSlice = surfaceDesc.mipLevel;
 			break;
 		case D3D11_SRV_DIMENSION_TEXTURE2DARRAY:
 			RTVDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY;
-			RTVDesc.Texture2DArray.FirstArraySlice = mFace;
-			RTVDesc.Texture2DArray.ArraySize = mNumFaces;
-			RTVDesc.Texture2DArray.MipSlice = mMipLevel;
+			RTVDesc.Texture2DArray.FirstArraySlice = surfaceDesc.face;
+			RTVDesc.Texture2DArray.ArraySize = surfaceDesc.numFaces;
+			RTVDesc.Texture2DArray.MipSlice = surfaceDesc.mipLevel;
 			break;
 		case D3D11_SRV_DIMENSION_TEXTURE2DMS:
 			RTVDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DMS;
 			break;
 		case D3D11_SRV_DIMENSION_TEXTURE2DMSARRAY:
 			RTVDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DMSARRAY;
-			RTVDesc.Texture2DMSArray.FirstArraySlice = mFace;
-			RTVDesc.Texture2DMSArray.ArraySize = mNumFaces;
+			RTVDesc.Texture2DMSArray.FirstArraySlice = surfaceDesc.face;
+			RTVDesc.Texture2DMSArray.ArraySize = surfaceDesc.numFaces;
 			break;
 		case D3D11_SRV_DIMENSION_TEXTURE3D:
 			RTVDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE3D;
-			RTVDesc.Texture3D.MipSlice = mMipLevel;
-			RTVDesc.Texture3D.FirstWSlice = mFace;
-			RTVDesc.Texture3D.WSize = mNumFaces;
+			RTVDesc.Texture3D.MipSlice = surfaceDesc.mipLevel;
+			RTVDesc.Texture3D.FirstWSlice = surfaceDesc.face;
+			RTVDesc.Texture3D.WSize = surfaceDesc.numFaces;
 			break;
 		default:
 			assert(false);
 		}
 
+		ID3D11RenderTargetView* rtv;
 		D3D11Device& device = D3D11RenderSystem::getPrimaryDevice();
-		HRESULT hr = device.getD3D11Device()->CreateRenderTargetView(d3d11Texture->getDX11Resource(), &RTVDesc, &mRenderTargetView);
+		HRESULT hr = device.getD3D11Device()->CreateRenderTargetView(d3d11Texture->getDX11Resource(), &RTVDesc, &rtv);
 
 		if (FAILED(hr) || device.hasError())
 		{
 			String errorDescription = device.getErrorDescription();
 			CM_EXCEPT(RenderingAPIException, "Error creating Render Target View\nError Description:" + errorDescription);
 		}
+
+		return rtv;
+	}
+
+	void D3D11RenderTexture::createInternalResourcesImpl()
+	{
+		SAFE_RELEASE(mRenderTargetView);
+
+		mRenderTargetView = createRenderTargetView(mSurface);
+	}
+
+	void D3D11RenderTexture::getCustomAttribute(const String& name, void* pData)
+	{
+		if(name == "RTV")
+		{
+			ID3D11RenderTargetView** pRTVs = (ID3D11RenderTargetView **)pData;						
+			*pRTVs = mRenderTargetView;		
+
+			return;
+		}
+		else if(name == "DSV")
+		{
+			ID3D11DepthStencilView** pDSV = (ID3D11DepthStencilView **)pData;
+			D3D11DepthStencilBuffer* d3d11depthStencilBuffer = static_cast<D3D11DepthStencilBuffer*>(mDepthStencilBuffer.get());
+
+			*pDSV = d3d11depthStencilBuffer->getDepthStencilView();
+			return;
+		}
 	}
 }

+ 9 - 0
CamelotD3D11RenderSystem/Source/CmD3D11TextureManager.cpp

@@ -4,6 +4,7 @@
 #include "CmD3D11Mappings.h"
 #include "CmD3D11RenderSystem.h"
 #include "CmD3D11DepthStencilBuffer.h"
+#include "CmD3D11MultiRenderTexture.h"
 
 namespace CamelotEngine
 {
@@ -30,6 +31,14 @@ namespace CamelotEngine
 		return DepthStencilBufferPtr(new D3D11DepthStencilBuffer(format, width, height, fsaa, fsaaHint));
 	}
 
+	MultiRenderTexturePtr D3D11TextureManager::createMultiRenderTexture()
+	{
+		D3D11MultiRenderTexture* newMRT = new D3D11MultiRenderTexture();
+		newMRT->initialize();
+
+		return MultiRenderTexturePtr(newMRT);
+	}
+
 	PixelFormat D3D11TextureManager::getNativeFormat(TextureType ttype, PixelFormat format, int usage)
 	{
 		// Basic filtering

+ 2 - 0
CamelotD3D9Renderer/CamelotD3D9Renderer.vcxproj

@@ -163,6 +163,7 @@
     <ClInclude Include="Include\CmD3D9HLSLProgramFactory.h" />
     <ClInclude Include="Include\CmD3D9HLSLProgramRTTI.h" />
     <ClInclude Include="Include\CmD3D9Mappings.h" />
+    <ClInclude Include="Include\CmD3D9MultiRenderTexture.h" />
     <ClInclude Include="Include\CmD3D9Prerequisites.h" />
     <ClInclude Include="Include\CmD3D9RenderSystem.h" />
     <ClInclude Include="Include\CmD3D9RenderSystemFactory.h" />
@@ -194,6 +195,7 @@
     <ClCompile Include="Source\CmD3D9HLSLProgram.cpp" />
     <ClCompile Include="Source\CmD3D9HLSLProgramFactory.cpp" />
     <ClCompile Include="Source\CmD3D9Mappings.cpp" />
+    <ClCompile Include="Source\CmD3D9MultiRenderTexture.cpp" />
     <ClCompile Include="Source\CmD3D9RenderSystem.cpp" />
     <ClCompile Include="Source\CmD3D9RenderSystemFactory.cpp" />
     <ClCompile Include="Source\CmD3D9RenderTexture.cpp" />

+ 6 - 0
CamelotD3D9Renderer/CamelotD3D9Renderer.vcxproj.filters

@@ -105,6 +105,9 @@
     <ClInclude Include="Include\CmD3D9RenderTexture.h">
       <Filter>Header Files</Filter>
     </ClInclude>
+    <ClInclude Include="Include\CmD3D9MultiRenderTexture.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="Source\CmD3D9Device.cpp">
@@ -191,5 +194,8 @@
     <ClCompile Include="Source\CmD3D9RenderTexture.cpp">
       <Filter>Source Files</Filter>
     </ClCompile>
+    <ClCompile Include="Source\CmD3D9MultiRenderTexture.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
   </ItemGroup>
 </Project>

+ 28 - 0
CamelotD3D9Renderer/Include/CmD3D9MultiRenderTexture.h

@@ -0,0 +1,28 @@
+#pragma once
+
+#include "CmD3D9Prerequisites.h"
+#include "CmMultiRenderTexture.h"
+
+namespace CamelotEngine
+{
+	class CM_D3D9_EXPORT D3D9MultiRenderTexture : public MultiRenderTexture
+	{
+	public:
+		virtual ~D3D9MultiRenderTexture();
+
+		bool requiresTextureFlipping() const { return false; }
+		void getCustomAttribute(const String& name, void* pData);
+
+	protected:
+		friend class D3D9TextureManager;
+
+		D3D9MultiRenderTexture();
+		void initialize();
+
+		void setColorSurfaceImpl(UINT32 surfaceIdx, TexturePtr texture, UINT32 face = 0, UINT32 numFaces = 0, UINT32 mipLevel = 0);
+		void setDepthStencilImpl(DepthStencilBufferPtr depthStencilbuffer);
+
+		vector<IDirect3DSurface9*>::type mColorSurfaces;
+		IDirect3DSurface9* mDepthStencilSurface;
+	};
+}

+ 4 - 1
CamelotD3D9Renderer/Include/CmD3D9RenderTexture.h

@@ -9,13 +9,16 @@ namespace CamelotEngine
 	class CM_D3D9_EXPORT D3D9RenderTexture : public RenderTexture
 	{
 	public:
-		D3D9RenderTexture();
 		virtual ~D3D9RenderTexture();
 
 		bool requiresTextureFlipping() const { return false; }
 		virtual void getCustomAttribute(const String& name, void* pData);
 
 	protected:
+		friend class D3D9TextureManager;
+
+		D3D9RenderTexture();
+
 		IDirect3DSurface9* mColorSurface;
 		IDirect3DSurface9* mDepthStencilSurface;
 

+ 5 - 0
CamelotD3D9Renderer/Include/CmD3D9TextureManager.h

@@ -53,6 +53,11 @@ namespace CamelotEngine
 		DepthStencilBufferPtr createDepthStencilBuffer(DepthStencilFormat format, UINT32 width, 
 			UINT32 height, UINT32 fsaa, const String& fsaaHint);
 
+		/**
+		 * @copydoc TextureManager::createMultiRenderTexture()
+		 */
+		MultiRenderTexturePtr createMultiRenderTexture();
+
 	protected:		
 		Texture* createTextureImpl();
 		RenderTexture* createRenderTextureImpl();

+ 75 - 0
CamelotD3D9Renderer/Source/CmD3D9MultiRenderTexture.cpp

@@ -0,0 +1,75 @@
+#include "CmD3D9MultiRenderTexture.h"
+#include "CmD3D9DepthStencilBuffer.h"
+#include "CmD3D9Texture.h"
+#include "CmD3D9RenderSystem.h"
+
+namespace CamelotEngine
+{
+	D3D9MultiRenderTexture::D3D9MultiRenderTexture()
+		:MultiRenderTexture(), mDepthStencilSurface(nullptr)
+	{
+
+	}
+
+	D3D9MultiRenderTexture::~D3D9MultiRenderTexture()
+	{
+
+	}
+
+	void D3D9MultiRenderTexture::setColorSurfaceImpl(UINT32 surfaceIdx, TexturePtr texture, UINT32 face, UINT32 numFaces, UINT32 mipLevel)
+	{
+		if(texture != nullptr)
+		{
+			D3D9Texture* d3d9texture = static_cast<D3D9Texture*>(texture.get());
+			D3D9HardwarePixelBuffer* pixelBuffer = static_cast<D3D9HardwarePixelBuffer*>(d3d9texture->getBuffer(face, mipLevel).get());
+			mColorSurfaces[surfaceIdx] = pixelBuffer->getSurface(D3D9RenderSystem::getActiveD3D9Device());
+		}
+		else
+		{
+			mColorSurfaces[surfaceIdx] = nullptr;
+		}
+	}
+
+	void D3D9MultiRenderTexture::setDepthStencilImpl(DepthStencilBufferPtr depthStencilBuffer)
+	{
+		if(depthStencilBuffer != nullptr)
+		{
+			D3D9DepthStencilBuffer* d3d9DepthStencil = static_cast<D3D9DepthStencilBuffer*>(mDepthStencilBuffer.get());
+			mDepthStencilSurface = d3d9DepthStencil->getSurface();
+		}
+		else
+		{
+			mDepthStencilSurface = nullptr;
+		}
+	}
+
+	void D3D9MultiRenderTexture::getCustomAttribute(const String& name, void* pData)
+	{
+		if(name == "DDBACKBUFFER")
+		{
+			IDirect3DSurface9 ** pSurf = (IDirect3DSurface9 **)pData;
+
+			for(size_t x = 0; x < mColorSurfaces.size(); ++x)							
+				pSurf[x] = mColorSurfaces[x];			
+
+			return;
+		}
+		else if(name == "D3DZBUFFER")
+		{
+			IDirect3DSurface9 ** pSurf = (IDirect3DSurface9 **)pData;
+			*pSurf = mDepthStencilSurface;
+			return;
+		}
+		else if(name == "HWND")
+		{
+			HWND *pHwnd = (HWND*)pData;
+			*pHwnd = NULL;
+			return;
+		}
+	}
+
+	void D3D9MultiRenderTexture::initialize()
+	{
+		mColorSurfaces.resize(CM_MAX_MULTIPLE_RENDER_TARGETS);
+	}
+}

+ 2 - 2
CamelotD3D9Renderer/Source/CmD3D9RenderTexture.cpp

@@ -41,8 +41,8 @@ namespace CamelotEngine
 
 	void D3D9RenderTexture::createInternalResourcesImpl()
 	{
-		D3D9Texture* d3d9texture = static_cast<D3D9Texture*>(mTexture.get());
-		D3D9HardwarePixelBuffer* pixelBuffer = static_cast<D3D9HardwarePixelBuffer*>(d3d9texture->getBuffer(mFace, mMipLevel).get());
+		D3D9Texture* d3d9texture = static_cast<D3D9Texture*>(mSurface.texture.get());
+		D3D9HardwarePixelBuffer* pixelBuffer = static_cast<D3D9HardwarePixelBuffer*>(d3d9texture->getBuffer(mSurface.face, mSurface.mipLevel).get());
 		mColorSurface = pixelBuffer->getSurface(D3D9RenderSystem::getActiveD3D9Device());
 
 		D3D9DepthStencilBuffer* d3d9DepthStencil = static_cast<D3D9DepthStencilBuffer*>(mDepthStencilBuffer.get());

+ 9 - 0
CamelotD3D9Renderer/Source/CmD3D9TextureManager.cpp

@@ -32,6 +32,7 @@ THE SOFTWARE.
 #include "CmD3D9Mappings.h"
 #include "CmD3D9RenderSystem.h"
 #include "CmD3D9DepthStencilBuffer.h"
+#include "CmD3D9MultiRenderTexture.h"
 
 namespace CamelotEngine 
 {
@@ -61,6 +62,14 @@ namespace CamelotEngine
 		return DepthStencilBufferPtr(new D3D9DepthStencilBuffer(format, width, height, fsaa, fsaaHint));
 	}
 
+	MultiRenderTexturePtr D3D9TextureManager::createMultiRenderTexture()
+	{
+		D3D9MultiRenderTexture* newMRT = new D3D9MultiRenderTexture();
+		newMRT->initialize();
+
+		return MultiRenderTexturePtr(newMRT);
+	}
+
 	PixelFormat D3D9TextureManager::getNativeFormat(TextureType ttype, PixelFormat format, int usage)
 	{
 		// Basic filtering

+ 2 - 0
CamelotGLRenderer/CamelotGLRenderer.vcxproj

@@ -159,6 +159,7 @@
     <ClInclude Include="Include\CmGLHardwareOcclusionQuery.h" />
     <ClInclude Include="Include\CmGLHardwarePixelBuffer.h" />
     <ClInclude Include="Include\CmGLHardwareVertexBuffer.h" />
+    <ClInclude Include="Include\CmGLMultiRenderTexture.h" />
     <ClInclude Include="Include\CmGLPixelFormat.h" />
     <ClInclude Include="Include\CmGLPrerequisites.h" />
     <ClInclude Include="Include\CmGLRenderSystem.h" />
@@ -202,6 +203,7 @@
     <ClCompile Include="Source\CmGLHardwareOcclusionQuery.cpp" />
     <ClCompile Include="Source\CmGLHardwarePixelBuffer.cpp" />
     <ClCompile Include="Source\CmGLHardwareVertexBuffer.cpp" />
+    <ClCompile Include="Source\CmGLMultiRenderTexture.cpp" />
     <ClCompile Include="Source\CmGLPixelFormat.cpp" />
     <ClCompile Include="Source\CmGLRenderSystem.cpp" />
     <ClCompile Include="Source\CmGLRenderSystemFactory.cpp" />

+ 6 - 0
CamelotGLRenderer/CamelotGLRenderer.vcxproj.filters

@@ -138,6 +138,9 @@
     <ClInclude Include="Include\CmGLDepthStencilBuffer.h">
       <Filter>Header Files</Filter>
     </ClInclude>
+    <ClInclude Include="Include\CmGLMultiRenderTexture.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="Source\atifs\src\ATI_FS_GLGpuProgram.cpp">
@@ -245,5 +248,8 @@
     <ClCompile Include="Source\CmGLDepthStencilBuffer.cpp">
       <Filter>Source Files</Filter>
     </ClCompile>
+    <ClCompile Include="Source\CmGLMultiRenderTexture.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
   </ItemGroup>
 </Project>

+ 27 - 0
CamelotGLRenderer/Include/CmGLMultiRenderTexture.h

@@ -0,0 +1,27 @@
+#pragma once
+
+#include "CmGLPrerequisites.h"
+#include "CmMultiRenderTexture.h"
+#include "CmGLFrameBufferObject.h"
+
+namespace CamelotEngine
+{
+	class CM_RSGL_EXPORT GLMultiRenderTexture : public MultiRenderTexture
+	{
+	public:
+		virtual ~GLMultiRenderTexture();
+
+		bool requiresTextureFlipping() const { return true; }
+		void getCustomAttribute(const String& name, void* pData);
+	protected:
+		friend class GLTextureManager;
+
+		GLMultiRenderTexture();
+		void initialize();
+
+		void setColorSurfaceImpl(UINT32 surfaceIdx, TexturePtr texture, UINT32 face = 0, UINT32 numFaces = 0, UINT32 mipLevel = 0);
+		void setDepthStencilImpl(DepthStencilBufferPtr depthStencilbuffer);
+	private:
+		GLFrameBufferObject* mFB;
+	};
+}

+ 3 - 1
CamelotGLRenderer/Include/CmGLRenderTexture.h

@@ -44,13 +44,15 @@ namespace CamelotEngine
     class CM_RSGL_EXPORT GLRenderTexture: public RenderTexture
     {
 	public:
-		GLRenderTexture();
 		virtual ~GLRenderTexture();
 
 		bool requiresTextureFlipping() const { return true; }
 		virtual void getCustomAttribute(const String& name, void* pData);
 
 	protected:
+		friend class GLTextureManager;
+
+		GLRenderTexture();
 		GLFrameBufferObject* mFB;
 
 		void createInternalResourcesImpl();

+ 5 - 0
CamelotGLRenderer/Include/CmGLTextureManager.h

@@ -57,6 +57,11 @@ namespace CamelotEngine {
 		DepthStencilBufferPtr createDepthStencilBuffer(DepthStencilFormat format, UINT32 width, 
 			UINT32 height, UINT32 fsaa, const String& fsaaHint);
 
+		/**
+		 * @copydoc TextureManager::createMultiRenderTexture()
+		 */
+		MultiRenderTexturePtr createMultiRenderTexture();
+
     protected:
         /**
          * @copydoc ResourceManager::createTextureImpl

+ 73 - 0
CamelotGLRenderer/Source/CmGLMultiRenderTexture.cpp

@@ -0,0 +1,73 @@
+#include "CmGLMultiRenderTexture.h"
+#include "CmGLDepthStencilBuffer.h"
+#include "CmGLTexture.h"
+
+namespace CamelotEngine
+{
+	GLMultiRenderTexture::GLMultiRenderTexture()
+		:MultiRenderTexture(), mFB(nullptr)
+	{
+
+	}
+
+	GLMultiRenderTexture::~GLMultiRenderTexture()
+	{
+		if(mFB != nullptr)
+			delete mFB;
+	}
+
+	void GLMultiRenderTexture::setColorSurfaceImpl(UINT32 surfaceIdx, TexturePtr texture, UINT32 face, UINT32 numFaces, UINT32 mipLevel)
+	{
+		if(texture != nullptr)
+		{
+			GLSurfaceDesc surfaceDesc;
+			surfaceDesc.numSamples = mFSAA;
+			surfaceDesc.zoffset = 0;
+
+			GLTexture* glTexture = static_cast<GLTexture*>(texture.get());
+			surfaceDesc.buffer = std::static_pointer_cast<GLHardwarePixelBuffer>(glTexture->getBuffer(face, mipLevel));
+
+			mFB->bindSurface(surfaceIdx, surfaceDesc);
+		}
+		else
+		{
+			mFB->unbindSurface(surfaceIdx);
+		}
+	}
+
+	void GLMultiRenderTexture::setDepthStencilImpl(DepthStencilBufferPtr depthStencilBuffer)
+	{
+		if(depthStencilBuffer != nullptr)
+		{
+			GLDepthStencilBuffer* glDepthStencilBuffer = static_cast<GLDepthStencilBuffer*>(mDepthStencilBuffer.get());
+
+			mFB->bindDepthStencil(glDepthStencilBuffer->getGLRenderBuffer());
+		}
+		else
+		{
+			mFB->unbindDepthStencil();
+		}
+	}
+
+	void GLMultiRenderTexture::getCustomAttribute(const String& name, void* pData)
+	{
+		if(name=="FBO")
+		{
+			*static_cast<GLFrameBufferObject **>(pData) = mFB;
+		}
+		else if (name == "GL_FBOID" || name == "GL_MULTISAMPLEFBOID")
+		{
+			*static_cast<GLuint*>(pData) = mFB->getGLFBOID();
+		}
+	}
+
+	void GLMultiRenderTexture::initialize()
+	{
+		if(mFB != nullptr)
+			delete mFB;
+
+		mFB = new GLFrameBufferObject(mFSAA);
+
+		MultiRenderTexture::initialize();
+	}
+}

+ 2 - 2
CamelotGLRenderer/Source/CmGLRenderTexture.cpp

@@ -54,8 +54,8 @@ namespace CamelotEngine
 		surfaceDesc.numSamples = mFSAA;
 		surfaceDesc.zoffset = 0;
 
-		GLTexture* glTexture = static_cast<GLTexture*>(mTexture.get());
-		surfaceDesc.buffer = std::static_pointer_cast<GLHardwarePixelBuffer>(glTexture->getBuffer(mFace, mMipLevel));
+		GLTexture* glTexture = static_cast<GLTexture*>(mSurface.texture.get());
+		surfaceDesc.buffer = std::static_pointer_cast<GLHardwarePixelBuffer>(glTexture->getBuffer(mSurface.face, mSurface.mipLevel));
 
 		mFB->bindSurface(0, surfaceDesc);
 

+ 9 - 0
CamelotGLRenderer/Source/CmGLTextureManager.cpp

@@ -30,6 +30,7 @@ THE SOFTWARE.
 #include "CmRenderSystem.h"
 #include "CmGLRenderTexture.h"
 #include "CmGLDepthStencilBuffer.h"
+#include "CmGLMultiRenderTexture.h"
 
 namespace CamelotEngine {
     //-----------------------------------------------------------------------------
@@ -60,6 +61,14 @@ namespace CamelotEngine {
 	{
 		return DepthStencilBufferPtr(new GLDepthStencilBuffer(format, width, height, fsaa, fsaaHint));
 	}
+	//----------------------------------------------------------------------------
+	MultiRenderTexturePtr GLTextureManager::createMultiRenderTexture()
+	{
+		GLMultiRenderTexture* newMRT = new GLMultiRenderTexture();
+		newMRT->initialize();
+
+		return MultiRenderTexturePtr(newMRT);
+	}
 	//-----------------------------------------------------------------------------
 	void GLTextureManager::createWarningTexture()
 	{

+ 2 - 1
CamelotRenderer/CamelotRenderer.vcxproj

@@ -213,6 +213,7 @@
     <ClInclude Include="Include\CmMesh.h" />
     <ClInclude Include="Include\CmMeshData.h" />
     <ClInclude Include="Include\CmMeshDataRTTI.h" />
+    <ClInclude Include="Include\CmMultiRenderTexture.h" />
     <ClInclude Include="Include\CmOSCursor.h" />
     <ClInclude Include="Include\CmPass.h" />
     <ClInclude Include="Include\CmPassRTTI.h" />
@@ -264,7 +265,6 @@
     <ClInclude Include="Source\CmMeshRTTI.h" />
   </ItemGroup>
   <ItemGroup>
-    <ClCompile Include="Include\CmMultiRenderTexture.cpp" />
     <ClCompile Include="Source\CamelotRenderer.cpp" />
     <ClCompile Include="Source\CmApplication.cpp" />
     <ClCompile Include="Source\CmBlendState.cpp" />
@@ -293,6 +293,7 @@
     <ClCompile Include="Source\CmMaterialRTTI.cpp" />
     <ClCompile Include="Source\CmMesh.cpp" />
     <ClCompile Include="Source\CmMeshData.cpp" />
+    <ClCompile Include="Source\CmMultiRenderTexture.cpp" />
     <ClCompile Include="Source\CmPass.cpp" />
     <ClCompile Include="Source\CmRasterizerState.cpp" />
     <ClCompile Include="Source\CmRenderable.cpp" />

+ 5 - 2
CamelotRenderer/CamelotRenderer.vcxproj.filters

@@ -347,6 +347,9 @@
     <ClInclude Include="Include\CmDepthStencilBuffer.h">
       <Filter>Header Files\RenderSystem</Filter>
     </ClInclude>
+    <ClInclude Include="Include\CmMultiRenderTexture.h">
+      <Filter>Header Files\RenderSystem</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="Source\CamelotRenderer.cpp">
@@ -520,8 +523,8 @@
     <ClCompile Include="Source\CmDepthStencilBuffer.cpp">
       <Filter>Source Files\RenderSystem</Filter>
     </ClCompile>
-    <ClCompile Include="Include\CmMultiRenderTexture.cpp">
-      <Filter>Header Files\RenderSystem</Filter>
+    <ClCompile Include="Source\CmMultiRenderTexture.cpp">
+      <Filter>Source Files\RenderSystem</Filter>
     </ClCompile>
   </ItemGroup>
 </Project>

+ 0 - 32
CamelotRenderer/Include/CmMultiRenderTexture.cpp

@@ -1,32 +0,0 @@
-#pragma once
-
-#include "CmPrerequisites.h"
-#include "CmRenderTarget.h"
-
-namespace CamelotEngine
-{
-	class CM_EXPORT MultiRenderTexture : public RenderTarget
-	{
-	public:
-		virtual ~MultiRenderTexture() {}
-
-		void setColorSurface(UINT32 surfaceIndex, TexturePtr texture, UINT32 face = 0, UINT32 numFaces = 0, UINT32 mipLevel = 0);
-		void setDepthStencil(DepthStencilBufferPtr depthStencilbuffer);
-
-		TexturePtr getTexture(UINT32 index) const { return mTextures.at(index); }
-		DepthStencilBufferPtr getDepthStencilBuffer() const { return mDepthStencilBuffer; }
-
-		bool requiresTextureFlipping() const { return false; }
-
-	protected:
-		vector<TexturePtr>::type mTextures;
-		DepthStencilBufferPtr mDepthStencilBuffer;
-
-		MultiRenderTexture();
-
-		void initialize();
-
-		void createInternalResources();
-		virtual void createInternalResourcesImpl() = 0;
-	};
-}

+ 35 - 0
CamelotRenderer/Include/CmMultiRenderTexture.h

@@ -0,0 +1,35 @@
+#pragma once
+
+#include "CmPrerequisites.h"
+#include "CmRenderTarget.h"
+
+namespace CamelotEngine
+{
+	class CM_EXPORT MultiRenderTexture : public RenderTarget
+	{
+	public:
+		virtual ~MultiRenderTexture() {}
+
+		void setColorSurface(UINT32 surfaceIdx, TexturePtr texture, UINT32 face = 0, UINT32 numFaces = 0, UINT32 mipLevel = 0);
+		void setDepthStencil(DepthStencilBufferPtr depthStencilbuffer);
+
+		SurfaceDesc getSurfaceDesc(UINT32 surfaceIdx) const { return mSurfaces.at(surfaceIdx); }
+		DepthStencilBufferPtr getDepthStencilBuffer() const { return mDepthStencilBuffer; }
+
+		bool requiresTextureFlipping() const { return false; }
+
+	protected:
+		vector<SurfaceDesc>::type mSurfaces;
+		DepthStencilBufferPtr mDepthStencilBuffer;
+
+		MultiRenderTexture();
+		virtual void initialize() {}
+
+		virtual void setColorSurfaceImpl(UINT32 surfaceIdx, TexturePtr texture, UINT32 face = 0, UINT32 numFaces = 0, UINT32 mipLevel = 0) = 0;
+		virtual void setDepthStencilImpl(DepthStencilBufferPtr depthStencilbuffer) = 0;
+	private:
+		void throwIfBuffersDontMatch() const;
+
+		virtual void copyContentsToMemory(const PixelData &dst, FrameBuffer buffer = FB_AUTO);
+	};
+}

+ 2 - 1
CamelotRenderer/Include/CmPrerequisites.h

@@ -87,7 +87,7 @@ namespace CamelotEngine {
     class RenderSystemCapabilities;
     class RenderTarget;
     class RenderTexture;
-	class MultiRenderTarget;
+	class MultiRenderTexture;
     class RenderWindow;
 	class DepthStencilBuffer;
     class RenderOperation;
@@ -170,6 +170,7 @@ namespace CamelotEngine
 	typedef std::shared_ptr<RenderTarget> RenderTargetPtr;
 	typedef std::shared_ptr<RenderTexture> RenderTexturePtr;
 	typedef std::shared_ptr<DepthStencilBuffer> DepthStencilBufferPtr;
+	typedef std::shared_ptr<MultiRenderTexture> MultiRenderTexturePtr;
 }
 
 // All type IDs used for RTTI

+ 9 - 0
CamelotRenderer/Include/CmRenderTarget.h

@@ -43,6 +43,15 @@ THE SOFTWARE.
 
 namespace CamelotEngine {
 
+	struct SurfaceDesc
+	{
+		TexturePtr texture;
+		UINT32 face;
+		UINT32 numFaces;
+		UINT32 mipLevel;
+		PixelFormat format;
+	};
+
 	/** \addtogroup Core
 	*  @{
 	*/

+ 2 - 9
CamelotRenderer/Include/CmRenderTexture.h

@@ -54,20 +54,13 @@ namespace CamelotEngine
 		void setColorSurface(TexturePtr texture, UINT32 face = 0, UINT32 numFaces = 0, UINT32 mipLevel = 0);
 		void setDepthStencil(DepthStencilBufferPtr depthStencilbuffer);
 
-		TexturePtr getTexture() const { return mTexture; }
+		SurfaceDesc getSurfaceDesc() const { return mSurface; }
 		DepthStencilBufferPtr getDepthStencilBuffer() const { return mDepthStencilBuffer; }
 
 		bool requiresTextureFlipping() const { return false; }
 
 	protected:
-		TextureType mType;
-		PixelFormat mFormat;
-		DepthStencilFormat mDepthStencilFormat;
-		UINT32 mFace;
-		UINT32 mNumFaces;
-		UINT32 mMipLevel;
-
-		TexturePtr mTexture;
+		SurfaceDesc mSurface;
 		DepthStencilBufferPtr mDepthStencilBuffer;
 
 		RenderTexture();

+ 6 - 1
CamelotRenderer/Include/CmTextureManager.h

@@ -28,7 +28,6 @@ THE SOFTWARE.
 #ifndef _TextureManager_H__
 #define _TextureManager_H__
 
-
 #include "CmPrerequisites.h"
 
 #include "CmTexture.h"
@@ -193,6 +192,12 @@ namespace CamelotEngine {
 		 */
 		virtual RenderTexturePtr createEmptyRenderTexture();
 
+		/**
+		 * @brief	Creates a new multi render texture. You may use this type of texture
+		 * 			to render to multiple output textures at once.
+		 */
+		virtual MultiRenderTexturePtr createMultiRenderTexture() = 0;
+
 		/** Returns whether this render system can natively support the precise texture 
 			format requested with the given usage options.
 		@remarks

+ 122 - 0
CamelotRenderer/Source/CmMultiRenderTexture.cpp

@@ -0,0 +1,122 @@
+#include "CmMultiRenderTexture.h"
+#include "CmTexture.h"
+#include "CmDepthStencilBuffer.h"
+#include "CmException.h"
+
+namespace CamelotEngine
+{
+	MultiRenderTexture::MultiRenderTexture()
+	{
+		mSurfaces.resize(CM_MAX_MULTIPLE_RENDER_TARGETS);
+	}
+
+	void MultiRenderTexture::setColorSurface(UINT32 surfaceIdx, TexturePtr texture, UINT32 face, UINT32 numFaces, UINT32 mipLevel)
+	{
+		if(surfaceIdx < 0 || surfaceIdx >= CM_MAX_MULTIPLE_RENDER_TARGETS)
+			CM_EXCEPT(InvalidParametersException, "Invalid surface index. 0 <= " + toString(surfaceIdx) + " < CM_MAX_MULTIPLE_RENDER_TARGETS");
+
+		mSurfaces[surfaceIdx].texture = texture;
+
+		if(texture == nullptr)
+		{
+			setColorSurfaceImpl(surfaceIdx, texture, face, numFaces, mipLevel);
+			return;
+		}
+			
+		mPriority = CM_REND_TO_TEX_RT_GROUP;
+		mWidth = texture->getWidth();
+		mHeight = texture->getWidth();
+		mColorDepth = CamelotEngine::PixelUtil::getNumElemBits(texture->getFormat());
+		mActive = true;
+		mHwGamma = texture->isHardwareGammaEnabled();
+		mFSAA = texture->getFSAA();
+		mFSAAHint = texture->getFSAAHint();
+
+		mSurfaces[surfaceIdx].format = texture->getFormat();
+
+		mSurfaces[surfaceIdx].face = face;
+		mSurfaces[surfaceIdx].numFaces = numFaces;
+		mSurfaces[surfaceIdx].mipLevel = mipLevel;
+
+		throwIfBuffersDontMatch();
+
+		setColorSurfaceImpl(surfaceIdx, texture, face, numFaces, mipLevel);
+	}
+
+	void MultiRenderTexture::setDepthStencil(DepthStencilBufferPtr depthStencilBuffer)
+	{
+		mDepthStencilBuffer = depthStencilBuffer;
+
+		throwIfBuffersDontMatch();
+
+		setDepthStencilImpl(depthStencilBuffer);
+	}
+
+	void MultiRenderTexture::throwIfBuffersDontMatch() const
+	{
+		const SurfaceDesc* firstSurfaceDesc = nullptr;
+		for(size_t i = 0; i < mSurfaces.size(); i++)
+		{
+			if(mSurfaces[i].texture == nullptr)
+				continue;
+
+			if(firstSurfaceDesc == nullptr)
+			{
+				firstSurfaceDesc = &mSurfaces[i];
+				continue;
+			}
+
+			if(mSurfaces[i].texture->getWidth() != firstSurfaceDesc->texture->getWidth() ||
+				mSurfaces[i].texture->getHeight() != firstSurfaceDesc->texture->getHeight() ||
+				mSurfaces[i].texture->getFSAA() != firstSurfaceDesc->texture->getFSAA() ||
+				mSurfaces[i].texture->getFSAAHint() != firstSurfaceDesc->texture->getFSAAHint())
+			{
+				String errorInfo = "\nWidth: " + toString(mSurfaces[i].texture->getWidth()) + "/" + toString(firstSurfaceDesc->texture->getWidth());
+				errorInfo += "\nHeight: " + toString(mSurfaces[i].texture->getHeight()) + "/" + toString(firstSurfaceDesc->texture->getHeight());
+				errorInfo += "\nFSAA: " + toString(mSurfaces[i].texture->getFSAA()) + "/" + toString(firstSurfaceDesc->texture->getFSAA());
+				errorInfo += "\nFSAAHint: " + mSurfaces[i].texture->getFSAAHint() + "/" + firstSurfaceDesc->texture->getFSAAHint();
+
+				CM_EXCEPT(InvalidParametersException, "Provided texture and depth stencil buffer don't match!" + errorInfo);
+			}
+		}
+
+		if(firstSurfaceDesc == nullptr)
+			return;
+
+		if(firstSurfaceDesc->texture->getTextureType() != TEX_TYPE_2D)
+			CM_EXCEPT(NotImplementedException, "Render textures are currently only implemented for 2D surfaces.");
+
+		if((firstSurfaceDesc->face + firstSurfaceDesc->numFaces) >= firstSurfaceDesc->texture->getNumFaces())
+		{
+			CM_EXCEPT(InvalidParametersException, "Provided number of faces is out of range. Face: " + 
+				toString(firstSurfaceDesc->face + firstSurfaceDesc->numFaces) + ". Max num faces: " + toString(firstSurfaceDesc->texture->getNumFaces()));
+		}
+
+		if(firstSurfaceDesc->mipLevel >= firstSurfaceDesc->texture->getNumMipmaps())
+		{
+			CM_EXCEPT(InvalidParametersException, "Provided number of mip maps is out of range. Mip level: " + 
+				toString(firstSurfaceDesc->mipLevel) + ". Max num mipmaps: " + toString(firstSurfaceDesc->texture->getNumMipmaps()));
+		}
+
+		if(mDepthStencilBuffer == nullptr)
+			return;
+
+		if(mDepthStencilBuffer->getWidth() != firstSurfaceDesc->texture->getWidth() ||
+			mDepthStencilBuffer->getHeight() != firstSurfaceDesc->texture->getHeight() ||
+			mDepthStencilBuffer->getFsaa() != firstSurfaceDesc->texture->getFSAA() ||
+			mDepthStencilBuffer->getFsaaHint() != firstSurfaceDesc->texture->getFSAAHint())
+		{
+			String errorInfo = "\nWidth: " + toString(mDepthStencilBuffer->getWidth()) + "/" + toString(firstSurfaceDesc->texture->getWidth());
+			errorInfo += "\nHeight: " + toString(mDepthStencilBuffer->getHeight()) + "/" + toString(firstSurfaceDesc->texture->getHeight());
+			errorInfo += "\nFSAA: " + toString(mDepthStencilBuffer->getFsaa()) + "/" + toString(firstSurfaceDesc->texture->getFSAA());
+			errorInfo += "\nFSAAHint: " + mDepthStencilBuffer->getFsaaHint() + "/" + firstSurfaceDesc->texture->getFSAAHint();
+
+			CM_EXCEPT(InvalidParametersException, "Provided texture and depth stencil buffer don't match!" + errorInfo);
+		}
+	}
+
+	void MultiRenderTexture::copyContentsToMemory( const PixelData &dst, FrameBuffer buffer /*= FB_AUTO */ )
+	{
+		throw std::exception("The method or operation is not implemented.");
+	}
+}

+ 26 - 26
CamelotRenderer/Source/CmRenderTexture.cpp

@@ -42,19 +42,21 @@ namespace CamelotEngine
 
 	void RenderTexture::createInternalResources()
 	{
-		if(mTexture->getTextureType() != TEX_TYPE_2D)
+		assert(mSurface.texture != nullptr);
+
+		if(mSurface.texture->getTextureType() != TEX_TYPE_2D)
 			CM_EXCEPT(NotImplementedException, "Render textures are currently only implemented for 2D surfaces.");
 
-		if((mFace + mNumFaces) >= mTexture->getNumFaces())
+		if((mSurface.face + mSurface.numFaces) >= mSurface.texture->getNumFaces())
 		{
 			CM_EXCEPT(InvalidParametersException, "Provided number of faces is out of range. Face: " + 
-				toString(mFace + mNumFaces) + ". Max num faces: " + toString(mTexture->getNumFaces()));
+				toString(mSurface.face + mSurface.numFaces) + ". Max num faces: " + toString(mSurface.texture->getNumFaces()));
 		}
 
-		if(mMipLevel >= mTexture->getNumMipmaps())
+		if(mSurface.mipLevel >= mSurface.texture->getNumMipmaps())
 		{
 			CM_EXCEPT(InvalidParametersException, "Provided number of mip maps is out of range. Mip level: " + 
-				toString(mMipLevel) + ". Max num mipmaps: " + toString(mTexture->getNumMipmaps()));
+				toString(mSurface.mipLevel) + ". Max num mipmaps: " + toString(mSurface.texture->getNumMipmaps()));
 		}
 
 		createInternalResourcesImpl();
@@ -62,9 +64,9 @@ namespace CamelotEngine
 
 	void RenderTexture::setColorSurface(TexturePtr texture, UINT32 face, UINT32 numFaces, UINT32 mipLevel)
 	{
-		mTexture = texture;
+		mSurface.texture = texture;
 
-		if(mTexture == nullptr)
+		if(mSurface.texture == nullptr)
 			return;
 
 		mPriority = CM_REND_TO_TEX_RT_GROUP;
@@ -75,16 +77,16 @@ namespace CamelotEngine
 		mHwGamma = texture->isHardwareGammaEnabled();
 		mFSAA = texture->getFSAA();
 		mFSAAHint = texture->getFSAAHint();
-		mType = texture->getTextureType();
-		mFormat = texture->getFormat();
-		
-		mFace = face;
-		mNumFaces = face;
-		mMipLevel = mipLevel;
 
+		mSurface.format = texture->getFormat();
+		
+		mSurface.face = face;
+		mSurface.numFaces = numFaces;
+		mSurface.mipLevel = mipLevel;
+		
 		throwIfBuffersDontMatch();
 
-		if(mDepthStencilBuffer != nullptr && mTexture != nullptr)
+		if(mDepthStencilBuffer != nullptr && mSurface.texture != nullptr)
 			createInternalResourcesImpl();
 	}
 
@@ -95,28 +97,26 @@ namespace CamelotEngine
 		if(mDepthStencilBuffer == nullptr)
 			return;
 
-		mDepthStencilFormat = depthStencilBuffer->getFormat();
-
 		throwIfBuffersDontMatch();
 
-		if(mDepthStencilBuffer != nullptr && mTexture != nullptr)
+		if(mDepthStencilBuffer != nullptr && mSurface.texture != nullptr)
 			createInternalResourcesImpl();
 	}
 
 	void RenderTexture::throwIfBuffersDontMatch() const
 	{
-		if(mTexture == nullptr || mDepthStencilBuffer == nullptr)
+		if(mSurface.texture == nullptr || mDepthStencilBuffer == nullptr)
 			return;
 
-		if(mTexture->getWidth() != mDepthStencilBuffer->getWidth() ||
-			mTexture->getHeight() != mDepthStencilBuffer->getWidth() ||
-			mTexture->getFSAA() != mDepthStencilBuffer->getFsaa() ||
-			mTexture->getFSAAHint() != mDepthStencilBuffer->getFsaaHint())
+		if(mSurface.texture->getWidth() != mDepthStencilBuffer->getWidth() ||
+			mSurface.texture->getHeight() != mDepthStencilBuffer->getHeight() ||
+			mSurface.texture->getFSAA() != mDepthStencilBuffer->getFsaa() ||
+			mSurface.texture->getFSAAHint() != mDepthStencilBuffer->getFsaaHint())
 		{
-			String errorInfo = "\nWidth: " + toString(mTexture->getWidth()) + "/" + toString(mDepthStencilBuffer->getWidth());
-			errorInfo += "\nHeight: " + toString(mTexture->getHeight()) + "/" + toString(mDepthStencilBuffer->getHeight());
-			errorInfo += "\nFSAA: " + toString(mTexture->getFSAA()) + "/" + toString(mDepthStencilBuffer->getFsaa());
-			errorInfo += "\nFSAAHint: " + mTexture->getFSAAHint() + "/" + mDepthStencilBuffer->getFsaaHint();
+			String errorInfo = "\nWidth: " + toString(mSurface.texture->getWidth()) + "/" + toString(mDepthStencilBuffer->getWidth());
+			errorInfo += "\nHeight: " + toString(mSurface.texture->getHeight()) + "/" + toString(mDepthStencilBuffer->getHeight());
+			errorInfo += "\nFSAA: " + toString(mSurface.texture->getFSAA()) + "/" + toString(mDepthStencilBuffer->getFsaa());
+			errorInfo += "\nFSAAHint: " + mSurface.texture->getFSAAHint() + "/" + mDepthStencilBuffer->getFsaaHint();
 
 			CM_EXCEPT(InvalidParametersException, "Provided texture and depth stencil buffer don't match!" + errorInfo);
 		}