Ver código fonte

Added support for clearing individual color buffers when multi-rendertarget is bound
RenderBeast now properly respects camera's clear color once again

BearishSun 10 anos atrás
pai
commit
8fcb0fe00a

+ 12 - 4
BansheeCore/Include/BsRenderAPI.h

@@ -101,10 +101,12 @@ namespace BansheeEngine
 		static void endRender(CoreAccessor& accessor);
 
 		/** @copydoc RenderAPICore::clearRenderTarget() */
-		static void clearRenderTarget(CoreAccessor& accessor, UINT32 buffers, const Color& color = Color::Black, float depth = 1.0f, UINT16 stencil = 0);
+		static void clearRenderTarget(CoreAccessor& accessor, UINT32 buffers, 
+			const Color& color = Color::Black, float depth = 1.0f, UINT16 stencil = 0, UINT8 targetMask = 0xFF);
 
 		/** @copydoc RenderAPICore::clearViewport() */
-		static void clearViewport(CoreAccessor& accessor, UINT32 buffers, const Color& color = Color::Black, float depth = 1.0f, UINT16 stencil = 0);
+		static void clearViewport(CoreAccessor& accessor, UINT32 buffers, const Color& color = Color::Black, 
+			float depth = 1.0f, UINT16 stencil = 0, UINT8 targetMask = 0xFF);
 
 		/** @copydoc RenderAPICore::swapBuffers() */
 		static void swapBuffers(CoreAccessor& accessor, const RenderTargetPtr& target);
@@ -312,8 +314,11 @@ namespace BansheeEngine
 		 * @param[in]	color		(optional) The color to clear the color buffer with, if enabled.
 		 * @param[in]	depth		(optional) The value to initialize the depth buffer with, if enabled.
 		 * @param[in]	stencil		(optional) The value to initialize the stencil buffer with, if enabled.
+		 * @param[in]	targetMask	(optional) In case multiple render targets are bound, this allows you to control
+		 *							which ones to clear (0x01 first, 0x02 second, 0x04 third, etc., and combinations).
 		 */
-		virtual void clearRenderTarget(UINT32 buffers, const Color& color = Color::Black, float depth = 1.0f, UINT16 stencil = 0) = 0;
+		virtual void clearRenderTarget(UINT32 buffers, const Color& color = Color::Black, float depth = 1.0f, 
+			UINT16 stencil = 0, UINT8 targetMask = 0xFF) = 0;
 
 		/**
 		 * Clears the currently active viewport (i.e. it clears just a sub-area of a render-target that is covered by the 
@@ -324,8 +329,11 @@ namespace BansheeEngine
 		 * @param[in]	color		(optional) The color to clear the color buffer with, if enabled.
 		 * @param[in]	depth		(optional) The value to initialize the depth buffer with, if enabled.
 		 * @param[in]	stencil		(optional) The value to initialize the stencil buffer with, if enabled.
+		 * @param[in]	targetMask	(optional) In case multiple render targets are bound, this allows you to control
+		 *							which ones to clear (0x01 first, 0x02 second, 0x04 third, etc., and combinations).
 		 */
-		virtual void clearViewport(UINT32 buffers, const Color& color = Color::Black, float depth = 1.0f, UINT16 stencil = 0) = 0;
+		virtual void clearViewport(UINT32 buffers, const Color& color = Color::Black, float depth = 1.0f, 
+			UINT16 stencil = 0, UINT8 targetMask = 0xFF) = 0;
 
 		/**
 		 * Change the render target into which we want to draw.

+ 8 - 5
BansheeCore/Source/BsRenderAPI.cpp

@@ -146,14 +146,16 @@ namespace BansheeEngine
 		accessor.queueCommand(std::bind(&RenderAPICore::endFrame, RenderAPICore::instancePtr()));
 	}
 
-	void RenderAPI::clearRenderTarget(CoreAccessor& accessor, UINT32 buffers, const Color& color, float depth, UINT16 stencil)
+	void RenderAPI::clearRenderTarget(CoreAccessor& accessor, UINT32 buffers, const Color& color, float depth, UINT16 stencil, UINT8 targetMask)
 	{
-		accessor.queueCommand(std::bind(&RenderAPICore::clearRenderTarget, RenderAPICore::instancePtr(), buffers, color, depth, stencil));
+		accessor.queueCommand(std::bind(&RenderAPICore::clearRenderTarget, RenderAPICore::instancePtr(), buffers, color,
+			depth, stencil, targetMask));
 	}
 
-	void RenderAPI::clearViewport(CoreAccessor& accessor, UINT32 buffers, const Color& color, float depth, UINT16 stencil)
+	void RenderAPI::clearViewport(CoreAccessor& accessor, UINT32 buffers, const Color& color, float depth, UINT16 stencil, UINT8 targetMask)
 	{
-		accessor.queueCommand(std::bind(&RenderAPICore::clearViewport, RenderAPICore::instancePtr(), buffers, color, depth, stencil));
+		accessor.queueCommand(std::bind(&RenderAPICore::clearViewport, RenderAPICore::instancePtr(), buffers, color, depth,
+			stencil, targetMask));
 	}
 
 	void RenderAPI::swapBuffers(CoreAccessor& accessor, const RenderTargetPtr& target)
@@ -168,7 +170,8 @@ namespace BansheeEngine
 
 	void RenderAPI::drawIndexed(CoreAccessor& accessor, UINT32 startIndex, UINT32 indexCount, UINT32 vertexOffset, UINT32 vertexCount)
 	{
-		accessor.queueCommand(std::bind(&RenderAPICore::drawIndexed, RenderAPICore::instancePtr(), startIndex, indexCount, vertexOffset, vertexCount));
+		accessor.queueCommand(std::bind(&RenderAPICore::drawIndexed, RenderAPICore::instancePtr(), startIndex, indexCount, 
+			vertexOffset, vertexCount));
 	}
 
 	const VideoModeInfo& RenderAPI::getVideoModeInfo()

+ 4 - 2
BansheeD3D11RenderAPI/Include/BsD3D11RenderAPI.h

@@ -74,12 +74,14 @@ namespace BansheeEngine
 		/**
 		 * @copydoc RenderAPICore::clearRenderTarget
 		 */
-		void clearRenderTarget(UINT32 buffers, const Color& color = Color::Black, float depth = 1.0f, UINT16 stencil = 0) override;
+		void clearRenderTarget(UINT32 buffers, const Color& color = Color::Black, float depth = 1.0f, UINT16 stencil = 0, 
+			UINT8 targetMask = 0xFF) override;
 
 		/**
 		 * @copydoc RenderAPICore::clearViewport
 		 */
-		void clearViewport(UINT32 buffers, const Color& color = Color::Black, float depth = 1.0f, UINT16 stencil = 0) override;
+		void clearViewport(UINT32 buffers, const Color& color = Color::Black, float depth = 1.0f, UINT16 stencil = 0,
+			UINT8 targetMask = 0xFF) override;
 
 		/**
 		 * @copydoc	RenderAPICore::setRenderTarget

+ 5 - 4
BansheeD3D11RenderAPI/Source/BsD3D11RenderAPI.cpp

@@ -658,7 +658,7 @@ namespace BansheeEngine
 		mDevice->getImmediateContext()->RSSetScissorRects(1, &mScissorRect);
 	}
 
-	void D3D11RenderAPI::clearViewport(UINT32 buffers, const Color& color, float depth, UINT16 stencil)
+	void D3D11RenderAPI::clearViewport(UINT32 buffers, const Color& color, float depth, UINT16 stencil, UINT8 targetMask)
 	{
 		THROW_IF_NOT_CORE_THREAD;
 
@@ -674,14 +674,15 @@ namespace BansheeEngine
 
 		if (!clearEntireTarget)
 		{
+			// TODO - Ignoring targetMask here
 			D3D11RenderUtility::instance().drawClearQuad(buffers, color, depth, stencil);
 			BS_INC_RENDER_STAT(NumClears);
 		}
 		else
-			clearRenderTarget(buffers, color, depth, stencil);
+			clearRenderTarget(buffers, color, depth, stencil, targetMask);
 	}
 
-	void D3D11RenderAPI::clearRenderTarget(UINT32 buffers, const Color& color, float depth, UINT16 stencil)
+	void D3D11RenderAPI::clearRenderTarget(UINT32 buffers, const Color& color, float depth, UINT16 stencil, UINT8 targetMask)
 	{
 		THROW_IF_NOT_CORE_THREAD;
 
@@ -711,7 +712,7 @@ namespace BansheeEngine
 
 			for(UINT32 i = 0; i < maxRenderTargets; i++)
 			{
-				if(views[i] != nullptr)
+				if(views[i] != nullptr && ((1 << i) & targetMask) != 0)
 					mDevice->getImmediateContext()->ClearRenderTargetView(views[i], clearColor);
 			}
 

+ 4 - 2
BansheeD3D9RenderAPI/Include/BsD3D9RenderAPI.h

@@ -134,12 +134,14 @@ namespace BansheeEngine
 		/**
 		 * @copydoc RenderAPICore::clearRenderTarget()
 		 */
-		void clearRenderTarget(UINT32 buffers, const Color& color = Color::Black, float depth = 1.0f, UINT16 stencil = 0) override;
+		void clearRenderTarget(UINT32 buffers, const Color& color = Color::Black, float depth = 1.0f, UINT16 stencil = 0, 
+			UINT8 targetMask = 0xFF) override;
 
 		/**
 		 * @copydoc RenderAPICore::clearViewport()
 		 */
-		void clearViewport(UINT32 buffers, const Color& color = Color::Black, float depth = 1.0f, UINT16 stencil = 0) override;
+		void clearViewport(UINT32 buffers, const Color& color = Color::Black, float depth = 1.0f, UINT16 stencil = 0, 
+			UINT8 targetMask = 0xFF) override;
 
 		/**
 		 * @copydoc RenderAPICore::convertProjectionMatrix()

+ 8 - 3
BansheeD3D9RenderAPI/Source/BsD3D9RenderAPI.cpp

@@ -1276,21 +1276,26 @@ namespace BansheeEngine
 		}
 	}
 
-	void D3D9RenderAPI::clearRenderTarget(UINT32 buffers, const Color& color, float depth, UINT16 stencil)
+	void D3D9RenderAPI::clearRenderTarget(UINT32 buffers, const Color& color, float depth, UINT16 stencil, UINT8 targetMask)
 	{
 		if(mActiveRenderTarget == nullptr)
 			return;
 
+		if (targetMask != 0xFF)
+			LOGWRN("DirectX 9 ignoring target mask for clearRenderTarget(). Only 0xFF is supported.");
+
 		const RenderTargetProperties& rtProps = mActiveRenderTarget->getProperties();
 		Rect2I clearRect(0, 0, rtProps.getWidth(), rtProps.getHeight());
 
 		clearArea(buffers, color, depth, stencil, clearRect);
 	}
 
-	void D3D9RenderAPI::clearViewport(UINT32 buffers, const Color& color, float depth, UINT16 stencil)
+	void D3D9RenderAPI::clearViewport(UINT32 buffers, const Color& color, float depth, UINT16 stencil, UINT8 targetMask)
 	{
-		Rect2I clearRect(mViewportLeft, mViewportTop, mViewportWidth, mViewportHeight);
+		if (targetMask != 0xFF)
+			LOGWRN("DirectX 9 ignoring target mask for clearRenderTarget(). Only 0xFF is supported.");
 
+		Rect2I clearRect(mViewportLeft, mViewportTop, mViewportWidth, mViewportHeight);
 		clearArea(buffers, color, depth, stencil, clearRect);
 	}
 

+ 93 - 90
BansheeGLRenderAPI/Include/BsGLFrameBufferObject.h

@@ -1,91 +1,94 @@
-#pragma once
-
-#include "BsGLPrerequisites.h"
-#include "BsGLContext.h"
-#include "BsGLPixelBuffer.h"
-#include "BsPixelData.h"
-
-namespace BansheeEngine 
-{
-	/**
-	 * @brief	Describes OpenGL frame buffer surface.
-	 */
-    struct BS_RSGL_EXPORT GLSurfaceDesc
-    {
-    public:
-		GLSurfaceDesc() 
-			:zoffset(0), numSamples(0) 
-		{ }
-
-		GLPixelBufferPtr buffer;
-		UINT32 zoffset;
-		UINT32 numSamples;
-    };
-
-	/**
-	 * @brief	Manages an OpenGL frame-buffer object. Frame buffer object
-	 *			is used as a rendering destination in the render system pipeline,
-	 *			and it may consist out of one or multiple color surfaces and an optional
-	 *			depth/stencil surface.
-	 */
-    class BS_RSGL_EXPORT GLFrameBufferObject
-    {
-    public:
-        GLFrameBufferObject();
-        ~GLFrameBufferObject();
-
-		/**
-		 * @brief	Binds a color surface to the specific attachment point.
-		 *
-		 * @param	attachment	Attachment point index in the range [0, BS_MAX_MULTIPLE_RENDER_TARGETS).
-		 * @param	target		Description of the color surface to attach.
-		 *
-		 * @note	Multisample counts of all surfaces must match.
-		 *			0th attachment must be bound in order for the object to be usable, rest are optional.
-		 */
-        void bindSurface(UINT32 attachment, const GLSurfaceDesc& target);
-
-		/**
-		 * @brief	Unbinds the attachment at the specified attachment index.
-		 *
-		 * @param	attachment	Attachment point index in the range [0, BS_MAX_MULTIPLE_RENDER_TARGETS).
-		 */
-        void unbindSurface(UINT32 attachment);
-
-		/**
-		 * @brief	Binds a depth/stencil buffer.
-		 *
-		 * @note	Multisample counts of depth/stencil and color surfaces must match.
-		 *			Binding a depth/stencil buffer is optional.
-		 */
-		void bindDepthStencil(GLPixelBufferPtr depthStencilBuffer);
-
-		/**
-		 * @brief	Unbinds a depth stencil buffer.
-		 */
-		void unbindDepthStencil();
-        
-		/**
-		 * @brief	Binds the frame buffer object to the OpenGL pipeline, making it used
-		 *			for any further rendering operations.
-		 */
-        void bind();
-
-		/**
-		 * @brief	Returns internal OpenGL frame buffer id.
-		 */
-		GLuint getGLFBOID() const { return mFB; }
-
-    private:
-		/**
-		 * @brief	Rebuilds internal frame buffer object. Should be called whenever surfaces change.
-		 */
-        void rebuild();
-
-	private:
-        GLuint mFB;
-
-        GLSurfaceDesc mColor[BS_MAX_MULTIPLE_RENDER_TARGETS];
-		GLPixelBufferPtr mDepthStencilBuffer;
-    };
+#pragma once
+
+#include "BsGLPrerequisites.h"
+#include "BsGLContext.h"
+#include "BsGLPixelBuffer.h"
+#include "BsPixelData.h"
+
+namespace BansheeEngine 
+{
+	/**
+	 * @brief	Describes OpenGL frame buffer surface.
+	 */
+    struct BS_RSGL_EXPORT GLSurfaceDesc
+    {
+    public:
+		GLSurfaceDesc() 
+			:zoffset(0), numSamples(0) 
+		{ }
+
+		GLPixelBufferPtr buffer;
+		UINT32 zoffset;
+		UINT32 numSamples;
+    };
+
+	/**
+	 * @brief	Manages an OpenGL frame-buffer object. Frame buffer object
+	 *			is used as a rendering destination in the render system pipeline,
+	 *			and it may consist out of one or multiple color surfaces and an optional
+	 *			depth/stencil surface.
+	 */
+    class BS_RSGL_EXPORT GLFrameBufferObject
+    {
+    public:
+        GLFrameBufferObject();
+        ~GLFrameBufferObject();
+
+		/**
+		 * @brief	Binds a color surface to the specific attachment point.
+		 *
+		 * @param	attachment	Attachment point index in the range [0, BS_MAX_MULTIPLE_RENDER_TARGETS).
+		 * @param	target		Description of the color surface to attach.
+		 *
+		 * @note	Multisample counts of all surfaces must match.
+		 *			0th attachment must be bound in order for the object to be usable, rest are optional.
+		 */
+        void bindSurface(UINT32 attachment, const GLSurfaceDesc& target);
+
+		/**
+		 * @brief	Unbinds the attachment at the specified attachment index.
+		 *
+		 * @param	attachment	Attachment point index in the range [0, BS_MAX_MULTIPLE_RENDER_TARGETS).
+		 */
+        void unbindSurface(UINT32 attachment);
+
+		/**
+		 * @brief	Binds a depth/stencil buffer.
+		 *
+		 * @note	Multisample counts of depth/stencil and color surfaces must match.
+		 *			Binding a depth/stencil buffer is optional.
+		 */
+		void bindDepthStencil(GLPixelBufferPtr depthStencilBuffer);
+
+		/**
+		 * @brief	Unbinds a depth stencil buffer.
+		 */
+		void unbindDepthStencil();
+        
+		/**
+		 * @brief	Binds the frame buffer object to the OpenGL pipeline, making it used
+		 *			for any further rendering operations.
+		 */
+        void bind();
+
+		/** Checks is the color buffer at the specified index bound. */
+		bool hasColorBuffer(UINT32 idx) const { return mColor[idx].buffer != nullptr; }
+
+		/**
+		 * @brief	Returns internal OpenGL frame buffer id.
+		 */
+		GLuint getGLFBOID() const { return mFB; }
+
+    private:
+		/**
+		 * @brief	Rebuilds internal frame buffer object. Should be called whenever surfaces change.
+		 */
+        void rebuild();
+
+	private:
+        GLuint mFB;
+
+        GLSurfaceDesc mColor[BS_MAX_MULTIPLE_RENDER_TARGETS];
+		GLPixelBufferPtr mDepthStencilBuffer;
+    };
 }

+ 6 - 3
BansheeGLRenderAPI/Include/BsGLRenderAPI.h

@@ -132,12 +132,14 @@ namespace BansheeEngine
 		/**
 		 * @copydoc RenderAPICore::clearRenderTarget()
 		 */
-		void clearRenderTarget(UINT32 buffers, const Color& color = Color::Black, float depth = 1.0f, UINT16 stencil = 0) override;
+		void clearRenderTarget(UINT32 buffers, const Color& color = Color::Black, float depth = 1.0f, UINT16 stencil = 0, 
+			UINT8 targetMask = 0xFF) override;
 
 		/**
 		 * @copydoc RenderAPICore::clearViewport()
 		 */
-		void clearViewport(UINT32 buffers, const Color& color = Color::Black, float depth = 1.0f, UINT16 stencil = 0) override;
+		void clearViewport(UINT32 buffers, const Color& color = Color::Black, float depth = 1.0f, UINT16 stencil = 0, 
+			UINT8 targetMask = 0xFF) override;
 
         /**
 		 * @copydoc RenderAPICore::getColorVertexElementType()
@@ -227,7 +229,8 @@ namespace BansheeEngine
 		/**
 		 * @brief	Clear a part of a render target.
 		 */
-		void clearArea(UINT32 buffers, const Color& color = Color::Black, float depth = 1.0f, UINT16 stencil = 0, const Rect2I& clearArea = Rect2I::EMPTY);
+		void clearArea(UINT32 buffers, const Color& color = Color::Black, float depth = 1.0f, UINT16 stencil = 0, 
+			const Rect2I& clearArea = Rect2I::EMPTY, UINT8 targetMask = 0xFF);
 
 		/**
 		 * @brief	Set up clip planes against which all geometry will get clipped.

+ 84 - 40
BansheeGLRenderAPI/Source/BsGLRenderAPI.cpp

@@ -559,7 +559,7 @@ namespace BansheeEngine
 		// This must happen after context switch to ensure previous context is still alive
 		mActiveRenderTarget = target;
 
-		GLFrameBufferObject *fbo = 0;
+		GLFrameBufferObject* fbo = nullptr;
 		target->getCustomAttribute("FBO", &fbo);
 		if(fbo)
 			fbo->bind();
@@ -696,7 +696,7 @@ namespace BansheeEngine
 		mScissorRight = right;
 	}
 
-	void GLRenderAPI::clearRenderTarget(UINT32 buffers, const Color& color, float depth, UINT16 stencil)
+	void GLRenderAPI::clearRenderTarget(UINT32 buffers, const Color& color, float depth, UINT16 stencil, UINT8 targetMask)
 	{
 		if(mActiveRenderTarget == nullptr)
 			return;
@@ -704,17 +704,18 @@ namespace BansheeEngine
 		const RenderTargetProperties& rtProps = mActiveRenderTarget->getProperties();
 		Rect2I clearRect(0, 0, rtProps.getWidth(), rtProps.getHeight());
 
-		clearArea(buffers, color, depth, stencil, clearRect);
+		clearArea(buffers, color, depth, stencil, clearRect, targetMask);
 	}
 
-	void GLRenderAPI::clearViewport(UINT32 buffers, const Color& color, float depth, UINT16 stencil)
+	void GLRenderAPI::clearViewport(UINT32 buffers, const Color& color, float depth, UINT16 stencil, UINT8 targetMask)
 	{
 		Rect2I clearRect(mViewportLeft, mViewportTop, mViewportWidth, mViewportHeight);
 
-		clearArea(buffers, color, depth, stencil, clearRect);
+		clearArea(buffers, color, depth, stencil, clearRect, targetMask);
 	}
 
-	void GLRenderAPI::clearArea(UINT32 buffers, const Color& color, float depth, UINT16 stencil, const Rect2I& clearRect)
+	void GLRenderAPI::clearArea(UINT32 buffers, const Color& color, float depth, UINT16 stencil, const Rect2I& clearRect, 
+		UINT8 targetMask)
 	{
 		THROW_IF_NOT_CORE_THREAD;
 
@@ -724,66 +725,109 @@ namespace BansheeEngine
 		bool colorMask = !mColorWrite[0] || !mColorWrite[1] 
 		|| !mColorWrite[2] || !mColorWrite[3]; 
 
-		GLbitfield flags = 0;
-		if (buffers & FBT_COLOR)
+		// Disable scissor test as we want to clear the entire render surface
+		GLboolean scissorTestEnabled = glIsEnabled(GL_SCISSOR_TEST);
+		UINT32 oldScissorTop = mScissorTop;
+		UINT32 oldScissorBottom = mScissorBottom;
+		UINT32 oldScissorLeft = mScissorLeft;
+		UINT32 oldScissorRight = mScissorRight;
+
+		if (scissorTestEnabled)
+		{
+			glDisable(GL_SCISSOR_TEST);
+		}
+
+		const RenderTargetProperties& rtProps = mActiveRenderTarget->getProperties();
+
+		bool clearEntireTarget = clearRect.width == 0 || clearRect.height == 0;
+		clearEntireTarget |= (clearRect.x == 0 && clearRect.y == 0 && clearRect.width == rtProps.getWidth() && clearRect.height == rtProps.getHeight());
+
+		if (!clearEntireTarget)
 		{
-			flags |= GL_COLOR_BUFFER_BIT;
+			setScissorRect(clearRect.x, clearRect.y, clearRect.x + clearRect.width, clearRect.y + clearRect.height);
+			setScissorTestEnable(true);
+		}
 
+		if (buffers & FBT_COLOR)
+		{
 			// Enable buffer for writing if it isn't
 			if (colorMask)
 				glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
-
-			glClearColor(color.r, color.g, color.b, color.a);
 		}
 		if (buffers & FBT_DEPTH)
 		{
-			flags |= GL_DEPTH_BUFFER_BIT;
-
 			// Enable buffer for writing if it isn't
 			if (!mDepthWrite)
 				glDepthMask(GL_TRUE);
-
-			glClearDepth(depth);
 		}
 		if (buffers & FBT_STENCIL)
 		{
-			flags |= GL_STENCIL_BUFFER_BIT;
-
 			// Enable buffer for writing if it isn't
 			glStencilMask(0xFFFFFFFF);
-
-			glClearStencil(stencil);
 		}
 
-		// Disable scissor test as we want to clear the entire render surface
-		GLboolean scissorTestEnabled = glIsEnabled(GL_SCISSOR_TEST);
-		UINT32 oldScissorTop = mScissorTop;
-		UINT32 oldScissorBottom = mScissorBottom;
-		UINT32 oldScissorLeft = mScissorLeft;
-		UINT32 oldScissorRight = mScissorRight;
-
-		if (scissorTestEnabled)
+		if (targetMask == 0xFF)
 		{
-			glDisable(GL_SCISSOR_TEST);
-		}
+			GLbitfield flags = 0;
+			if (buffers & FBT_COLOR)
+			{
+				flags |= GL_COLOR_BUFFER_BIT;
 
-		const RenderTargetProperties& rtProps = mActiveRenderTarget->getProperties();
+				glClearColor(color.r, color.g, color.b, color.a);
+			}
 
-		bool clearEntireTarget = clearRect.width == 0 || clearRect.height == 0;
-		clearEntireTarget |= (clearRect.x == 0 && clearRect.y == 0 && clearRect.width == rtProps.getWidth() && clearRect.height == rtProps.getHeight());
+			if (buffers & FBT_DEPTH)
+			{
+				flags |= GL_DEPTH_BUFFER_BIT;
 
-		if(!clearEntireTarget)
-		{
-			setScissorRect(clearRect.x, clearRect.y, clearRect.x + clearRect.width, clearRect.y + clearRect.height);
-			setScissorTestEnable(true);			
+				glClearDepth(depth);
+			}
+
+			if (buffers & FBT_STENCIL)
+			{
+				flags |= GL_STENCIL_BUFFER_BIT;
+
+				glClearStencil(stencil);
+			}
+
+			// Clear buffers
+			glClear(flags);
 		}
+		else
+		{
+			GLFrameBufferObject* fbo = nullptr;
+			mActiveRenderTarget->getCustomAttribute("FBO", &fbo);
+
+			if (buffers & FBT_COLOR)
+			{
+				for (UINT32 i = 0; i < BS_MAX_MULTIPLE_RENDER_TARGETS; i++)
+				{
+					if (fbo->hasColorBuffer(i) && ((1 << i) & targetMask) != 0)
+						glClearBufferfv(GL_COLOR, i, (GLfloat*)&color);
+				}
+			}
 
-		// Clear buffers
-		glClear(flags);
+			if (buffers & FBT_DEPTH)
+			{
+				if (buffers & FBT_STENCIL)
+				{
+					glClearBufferfi(GL_DEPTH_STENCIL, 0, depth, stencil);
+				}
+				else
+				{
+					glClearBufferfv(GL_DEPTH, 0, &depth);
+				}
+			}
+			else if (buffers & FBT_STENCIL)
+			{
+				INT32 stencilClear = (INT32)stencil;
+				glClearBufferiv(GL_STENCIL, 0, &stencilClear);
+			}
+		}
 
-		if(!clearEntireTarget)
+		if (!clearEntireTarget)
 		{
-			setScissorTestEnable(false);	
+			setScissorTestEnable(false);
 		}
 
 		// Restore scissor test

+ 19 - 2
RenderBeast/Source/BsRenderTargets.cpp

@@ -124,8 +124,25 @@ namespace BansheeEngine
 		Rect2 area(0.0f, 0.0f, 1.0f, 1.0f);
 		rapi.setViewport(area);
 
-		UINT32 clearBuffers = FBT_COLOR | FBT_DEPTH | FBT_STENCIL;
-		RenderAPICore::instance().clearViewport(clearBuffers, Color::ZERO, 1.0f, 0);
+		UINT32 clearBuffers = 0;
+		if (mViewport->getRequiresColorClear())
+			clearBuffers |= FBT_COLOR;
+
+		if (mViewport->getRequiresDepthClear())
+			clearBuffers |= FBT_DEPTH;
+
+		if (mViewport->getRequiresStencilClear())
+			clearBuffers |= FBT_STENCIL;
+
+		// Clear scene color, depth, stencil according to user defined values
+		if (clearBuffers != 0)
+		{
+			RenderAPICore::instance().clearViewport(clearBuffers, mViewport->getClearColor(),
+				mViewport->getClearDepthValue(), mViewport->getClearStencilValue(), 0x01);
+		}
+
+		// Clear all others
+		RenderAPICore::instance().clearViewport(FBT_COLOR, Color::ZERO, 1.0f, 0, 0xFF & ~0x01);
 	}
 
 	void RenderTargets::bindSceneColor(bool readOnlyDepthStencil)