浏览代码

Made multirender textures immutable

Marko Pintera 13 年之前
父节点
当前提交
34662227f0

+ 0 - 3
CamelotD3D11RenderSystem/Include/CmD3D11MultiRenderTexture.h

@@ -16,8 +16,5 @@ namespace CamelotEngine
 		friend class D3D11TextureManager;
 
 		D3D11MultiRenderTexture();
-
-		void setColorSurfaceImpl(UINT32 surfaceIdx, TexturePtr texture, UINT32 face = 0, UINT32 numFaces = 1, UINT32 mipLevel = 0);
-		void setDepthStencilImpl(TexturePtr depthStencilSurface, UINT32 face = 0, UINT32 numFaces = 1, UINT32 mipLevel = 0);
 	};
 }

+ 0 - 6
CamelotD3D11RenderSystem/Source/CmD3D11MultiRenderTexture.cpp

@@ -16,12 +16,6 @@ namespace CamelotEngine
 
 	}
 
-	void D3D11MultiRenderTexture::setColorSurfaceImpl(UINT32 surfaceIdx, TexturePtr texture, UINT32 face, UINT32 numFaces, UINT32 mipLevel)
-	{	}
-
-	void D3D11MultiRenderTexture::setDepthStencilImpl(TexturePtr depthStencilSurface, UINT32 face, UINT32 numFaces, UINT32 mipLevel)
-	{	}
-
 	void D3D11MultiRenderTexture::getCustomAttribute(const String& name, void* pData)
 	{
 		if(name == "RTV")

+ 19 - 18
CamelotD3D9Renderer/Source/CmD3D9MultiRenderTexture.cpp

@@ -17,35 +17,36 @@ namespace CamelotEngine
 
 	void D3D9MultiRenderTexture::initialize_internal()
 	{
-		mDX9ColorSurfaces.resize(CM_MAX_MULTIPLE_RENDER_TARGETS);
-	}
+		mDX9ColorSurfaces.resize(mColorSurfaces.size());
 
-	void D3D9MultiRenderTexture::setColorSurfaceImpl(UINT32 surfaceIdx, TexturePtr texture, UINT32 face, UINT32 numFaces, UINT32 mipLevel)
-	{
-		if(texture != nullptr)
-		{
-			D3D9Texture* d3d9texture = static_cast<D3D9Texture*>(texture.get());
-			D3D9PixelBuffer* pixelBuffer = static_cast<D3D9PixelBuffer*>(d3d9texture->getBuffer(face, mipLevel).get());
-			mDX9ColorSurfaces[surfaceIdx] = pixelBuffer->getSurface(D3D9RenderSystem::getActiveD3D9Device());
-		}
-		else
+		for(size_t i = 0; i < mColorSurfaces.size(); i++)
 		{
-			mDX9ColorSurfaces[surfaceIdx] = nullptr;
+			if(mColorSurfaces[i] != nullptr)
+			{
+				D3D9Texture* d3d9texture = static_cast<D3D9Texture*>(mColorSurfaces[i]->getTexture().get());
+				D3D9PixelBuffer* pixelBuffer = static_cast<D3D9PixelBuffer*>(
+					d3d9texture->getBuffer(mColorSurfaces[i]->getDesc().firstArraySlice, mColorSurfaces[i]->getDesc().mostDetailMip).get());
+				mDX9ColorSurfaces[i] = pixelBuffer->getSurface(D3D9RenderSystem::getActiveD3D9Device());
+			}
+			else
+			{
+				mDX9ColorSurfaces[i] = nullptr;
+			}
 		}
-	}
 
-	void D3D9MultiRenderTexture::setDepthStencilImpl(TexturePtr depthStencilSurface, UINT32 face, UINT32 numFaces, UINT32 mipLevel)
-	{
-		if(depthStencilSurface != nullptr)
+		if(mDepthStencilSurface != nullptr)
 		{
-			D3D9Texture* d3d9DepthStencil = static_cast<D3D9Texture*>(depthStencilSurface.get());
-			D3D9PixelBuffer* pixelBuffer = static_cast<D3D9PixelBuffer*>(d3d9DepthStencil->getBuffer(face, mipLevel).get());
+			D3D9Texture* d3d9DepthStencil = static_cast<D3D9Texture*>(mDepthStencilSurface->getTexture().get());
+			D3D9PixelBuffer* pixelBuffer = static_cast<D3D9PixelBuffer*>(
+				d3d9DepthStencil->getBuffer(mDepthStencilSurface->getDesc().firstArraySlice, mDepthStencilSurface->getDesc().mostDetailMip).get());
 			mDX9DepthStencilSurface = pixelBuffer->getSurface(D3D9RenderSystem::getActiveD3D9Device());
 		}
 		else
 		{
 			mDX9DepthStencilSurface = nullptr;
 		}
+
+		MultiRenderTexture::initialize_internal();
 	}
 
 	void D3D9MultiRenderTexture::getCustomAttribute(const String& name, void* pData)

+ 0 - 3
CamelotGLRenderer/Include/CmGLMultiRenderTexture.h

@@ -18,9 +18,6 @@ namespace CamelotEngine
 
 		GLMultiRenderTexture();
 
-		void setColorSurfaceImpl(UINT32 surfaceIdx, TexturePtr texture, UINT32 face = 0, UINT32 numFaces = 0, UINT32 mipLevel = 0);
-		void setDepthStencilImpl(TexturePtr depthStencilSurface, UINT32 face = 0, UINT32 numFaces = 1, UINT32 mipLevel = 0);
-
 		/**
 		 * @copydoc MultiRenderTexture::initialize_internal().
 		 */

+ 30 - 30
CamelotGLRenderer/Source/CmGLMultiRenderTexture.cpp

@@ -21,42 +21,32 @@ namespace CamelotEngine
 
 		mFB = new GLFrameBufferObject(mFSAA);
 
-		MultiRenderTexture::initialize_internal();
-	}
-
-	void GLMultiRenderTexture::destroy_internal()
-	{
-		if(mFB != nullptr)
-			delete mFB;
-
-		MultiRenderTexture::destroy_internal();
-	}
-
-	void GLMultiRenderTexture::setColorSurfaceImpl(UINT32 surfaceIdx, TexturePtr texture, UINT32 face, UINT32 numFaces, UINT32 mipLevel)
-	{
-		if(texture != nullptr)
+		for(size_t i = 0; i < mColorSurfaces.size(); i++)
 		{
-			GLSurfaceDesc surfaceDesc;
-			surfaceDesc.numSamples = mFSAA;
-			surfaceDesc.zoffset = 0;
+			if(mColorSurfaces[i] != nullptr)
+			{
+				GLTexture* glColorSurface = static_cast<GLTexture*>(mColorSurfaces[i]->getTexture().get());
+				GLPixelBufferPtr colorBuffer = std::static_pointer_cast<GLPixelBuffer>(
+					glColorSurface->getBuffer(mColorSurfaces[i]->getDesc().firstArraySlice, mColorSurfaces[i]->getDesc().mostDetailMip));
 
-			GLTexture* glTexture = static_cast<GLTexture*>(texture.get());
-			surfaceDesc.buffer = std::static_pointer_cast<GLPixelBuffer>(glTexture->getBuffer(face, mipLevel));
+				GLSurfaceDesc surfaceDesc;
+				surfaceDesc.numSamples = mFSAA;
+				surfaceDesc.zoffset = 0;
+				surfaceDesc.buffer = colorBuffer;
 
-			mFB->bindSurface(surfaceIdx, surfaceDesc);
+				mFB->bindSurface((UINT32)i, surfaceDesc);
+			}
+			else
+			{
+				mFB->unbindSurface((UINT32)i);
+			}
 		}
-		else
-		{
-			mFB->unbindSurface(surfaceIdx);
-		}
-	}
 
-	void GLMultiRenderTexture::setDepthStencilImpl(TexturePtr depthStencilSurface, UINT32 face, UINT32 numFaces, UINT32 mipLevel)
-	{
-		if(depthStencilSurface != nullptr)
+		if(mDepthStencilSurface != nullptr)
 		{
-			GLTexture* glDepthStencilSurface = static_cast<GLTexture*>(depthStencilSurface.get());
-			GLPixelBufferPtr depthStencilBuffer = std::static_pointer_cast<GLPixelBuffer>(glDepthStencilSurface->getBuffer(face, mipLevel));
+			GLTexture* glDepthStencilSurface = static_cast<GLTexture*>(mDepthStencilSurface->getTexture().get());
+			GLPixelBufferPtr depthStencilBuffer = std::static_pointer_cast<GLPixelBuffer>(
+				glDepthStencilSurface->getBuffer(mDepthStencilSurface->getDesc().firstArraySlice, mDepthStencilSurface->getDesc().mostDetailMip));
 
 			mFB->bindDepthStencil(depthStencilBuffer);
 		}
@@ -64,6 +54,16 @@ namespace CamelotEngine
 		{
 			mFB->unbindDepthStencil();
 		}
+
+		MultiRenderTexture::initialize_internal();
+	}
+
+	void GLMultiRenderTexture::destroy_internal()
+	{
+		if(mFB != nullptr)
+			delete mFB;
+
+		MultiRenderTexture::destroy_internal();
 	}
 
 	void GLMultiRenderTexture::getCustomAttribute(const String& name, void* pData)

+ 7 - 5
CamelotRenderer/Include/CmMultiRenderTexture.h

@@ -5,13 +5,18 @@
 
 namespace CamelotEngine
 {
+	struct CM_EXPORT MULTI_RENDER_TEXTURE_DESC
+	{
+		vector<RENDER_SURFACE_DESC>::type colorSurfaces;
+		RENDER_SURFACE_DESC depthStencilSurface;
+	};
+
 	class CM_EXPORT MultiRenderTexture : public RenderTarget
 	{
 	public:
 		virtual ~MultiRenderTexture();
 
-		void setColorSurface(UINT32 surfaceIdx, TexturePtr texture, UINT32 face = 0, UINT32 numFaces = 1, UINT32 mipLevel = 0);
-		void setDepthStencilSurface(TexturePtr depthStencil, UINT32 face = 0, UINT32 numFaces = 1, UINT32 mipLevel = 0);
+		void initialize(const MULTI_RENDER_TEXTURE_DESC& desc);
 
 		bool requiresTextureFlipping() const { return false; }
 
@@ -21,9 +26,6 @@ namespace CamelotEngine
 
 		MultiRenderTexture();
 
-		virtual void setColorSurfaceImpl(UINT32 surfaceIdx, TexturePtr texture, UINT32 face = 0, UINT32 numFaces = 1, UINT32 mipLevel = 0) = 0;
-		virtual void setDepthStencilImpl(TexturePtr depthStencilstencil, UINT32 face = 0, UINT32 numFaces = 1, UINT32 mipLevel = 0) = 0;
-
 		/**
 		 * @copydoc RenderTarget::destroy_internal()
 		 */

+ 8 - 0
CamelotRenderer/Include/CmRenderTarget.h

@@ -44,6 +44,14 @@ THE SOFTWARE.
 
 namespace CamelotEngine 
 {
+	struct CM_EXPORT RENDER_SURFACE_DESC
+	{
+		TexturePtr texture;
+		UINT32 face;
+		UINT32 numFaces;
+		UINT32 mipLevel;
+	};
+
 	/** \addtogroup Core
 	*  @{
 	*/

+ 0 - 8
CamelotRenderer/Include/CmRenderTexture.h

@@ -34,14 +34,6 @@ THE SOFTWARE.
 
 namespace CamelotEngine
 {    
-	struct RENDER_SURFACE_DESC
-	{
-		TexturePtr texture;
-		UINT32 face;
-		UINT32 numFaces;
-		UINT32 mipLevel;
-	};
-
 	struct CM_EXPORT RENDER_TEXTURE_DESC
 	{
 		RENDER_SURFACE_DESC colorSurface;

+ 51 - 52
CamelotRenderer/Source/CmMultiRenderTexture.cpp

@@ -1,6 +1,7 @@
 #include "CmMultiRenderTexture.h"
 #include "CmTexture.h"
 #include "CmException.h"
+#include "CmDebug.h"
 
 namespace CamelotEngine
 {
@@ -14,75 +15,73 @@ namespace CamelotEngine
 
 	}
 
-	void MultiRenderTexture::destroy_internal()
+	void MultiRenderTexture::initialize(const MULTI_RENDER_TEXTURE_DESC& desc)
 	{
-		for(auto iter = mColorSurfaces.begin(); iter != mColorSurfaces.end(); ++iter)
+		bool colorSurfacePropertiesSet = false;
+		for(size_t i = 0; i < desc.colorSurfaces.size(); i++)
 		{
-			if(*iter != nullptr)
-				Texture::releaseView(*iter);
+			if(desc.colorSurfaces[i].texture != nullptr)
+			{
+				if(i >= CM_MAX_MULTIPLE_RENDER_TARGETS)
+				{
+					LOGWRN("Render texture index is larger than the maximum number of supported render targets. Index: " + toString(i) + 
+						". Max. number of render targets: " + toString(CM_MAX_MULTIPLE_RENDER_TARGETS));
+
+					continue;
+				}
+
+				TexturePtr texture = desc.colorSurfaces[i].texture;
+
+				if(texture->getUsage() != TU_RENDERTARGET)
+					CM_EXCEPT(InvalidParametersException, "Provided texture is not created with render target usage.");
+
+				mColorSurfaces[i] = Texture::requestView(texture, desc.colorSurfaces[i].mipLevel, 1, 
+					desc.colorSurfaces[i].face, desc.colorSurfaces[i].numFaces, GVU_RENDERTARGET);
+
+				if(!colorSurfacePropertiesSet)
+				{
+					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();
+
+					colorSurfacePropertiesSet = true;
+				}
+			}
 		}
 
-		if(mDepthStencilSurface != nullptr)
-			Texture::releaseView(mDepthStencilSurface);
-
-		RenderTarget::destroy_internal();
-	}
-
-	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");
-
-		if(texture != nullptr && texture->getUsage() != TU_RENDERTARGET)
-			CM_EXCEPT(InvalidParametersException, "Provided texture is not created with render target usage.");
-
-		if(mColorSurfaces[surfaceIdx] != nullptr)
+		if(desc.depthStencilSurface.texture != nullptr)
 		{
-			mColorSurfaces[surfaceIdx]->getTexture()->releaseView(mColorSurfaces[surfaceIdx]);
-			mColorSurfaces[surfaceIdx] = nullptr;
-		}
+			TexturePtr texture = desc.depthStencilSurface.texture;
 
-		if(texture == nullptr)
-		{
-			setColorSurfaceImpl(surfaceIdx, texture, face, numFaces, mipLevel);
-			return;
-		}
-
-		mColorSurfaces[surfaceIdx] = Texture::requestView(texture, mipLevel, 1, face, numFaces, GVU_RENDERTARGET);
+			if(texture->getUsage() != TU_DEPTHSTENCIL)
+				CM_EXCEPT(InvalidParametersException, "Provided texture is not created with depth stencil usage.");
 
-		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();
+			mDepthStencilSurface = Texture::requestView(texture, desc.depthStencilSurface.mipLevel, 1, 
+				desc.depthStencilSurface.face, desc.depthStencilSurface.numFaces, GVU_DEPTHSTENCIL);
+		}
 
 		throwIfBuffersDontMatch();
 
-		setColorSurfaceImpl(surfaceIdx, texture, face, numFaces, mipLevel);
+		RenderTarget::initialize();
 	}
 
-	void MultiRenderTexture::setDepthStencilSurface(TexturePtr depthStencil, UINT32 face, UINT32 numFaces, UINT32 mipLevel)
+	void MultiRenderTexture::destroy_internal()
 	{
-		if(depthStencil != nullptr && depthStencil->getUsage() != TU_DEPTHSTENCIL)
-			CM_EXCEPT(InvalidParametersException, "Provided texture is not created with depth stencil usage.");
-
-		if(mDepthStencilSurface != nullptr)
+		for(auto iter = mColorSurfaces.begin(); iter != mColorSurfaces.end(); ++iter)
 		{
-			Texture::releaseView(mDepthStencilSurface);
-			mDepthStencilSurface = nullptr;
+			if(*iter != nullptr)
+				Texture::releaseView(*iter);
 		}
 
-		if(depthStencil == nullptr)
-			return;
-
-		mDepthStencilSurface = Texture::requestView(depthStencil, mipLevel, 1, face, numFaces, GVU_DEPTHSTENCIL);
-
-		throwIfBuffersDontMatch();
+		if(mDepthStencilSurface != nullptr)
+			Texture::releaseView(mDepthStencilSurface);
 
-		setDepthStencilImpl(depthStencil, face, numFaces, mipLevel);
+		RenderTarget::destroy_internal();
 	}
 
 	void MultiRenderTexture::throwIfBuffersDontMatch() const

+ 0 - 4
CamelotRenderer/TODO.txt

@@ -20,10 +20,6 @@ Pass
 GpuParamBlock - Needs to derive from CoreGpuObject and needs to be initialized better
  - HardwareBufferManager::createGpuParamBlock needs &CoreGpuObject::_deleteDelayed added as a deleted to shared_ptr
 
-RenderTextures and MultiRenderTextures will only work properly if used directly from render thread, as setting each surface calls render methods, so its impossible to set one outside of render thread
- - also they don't have initialize_internal
- - I should probably make these immutable. Once they are set they can't be changed, so everything can be initialized when calling initialize()
-
 Support loading of compound objects:
    - Loading Material also loads attached Shader and Textures/Samplers