Browse Source

Refactored viewport
Refactored RenderSystem::clear so it's more in line with DX11 way of things

Marko Pintera 13 years ago
parent
commit
e3e5d96d67

+ 1 - 1
CamelotD3D11RenderSystem/Include/CmD3D11RenderSystem.h

@@ -24,7 +24,7 @@ namespace CamelotEngine
 
 		void beginFrame();
 		void endFrame();
-		void clearFrameBuffer(unsigned int buffers, const Color& color = Color::Black, float depth = 1.0f, unsigned short stencil = 0);
+		void clear(RenderTargetPtr target, unsigned int buffers, const Color& color = Color::Black, float depth = 1.0f, unsigned short stencil = 0);
 
 		void setRenderTarget(RenderTarget* target);
 		void setViewport(const Viewport& vp);

+ 1 - 1
CamelotD3D11RenderSystem/Source/CmD3D11RenderSystem.cpp

@@ -187,7 +187,7 @@ namespace CamelotEngine
 		throw std::exception("The method or operation is not implemented.");
 	}
 
-	void D3D11RenderSystem::clearFrameBuffer(unsigned int buffers, const Color& color /*= Color::Black*/, float depth /*= 1.0f*/, unsigned short stencil /*= 0 */)
+	void D3D11RenderSystem::clear(RenderTargetPtr target, unsigned int buffers, const Color& color /*= Color::Black*/, float depth /*= 1.0f*/, unsigned short stencil /*= 0 */)
 	{
 		//mDevice->getImmediateContext()->c
 

+ 1 - 1
CamelotD3D9Renderer/Include/CmD3D9RenderSystem.h

@@ -113,7 +113,7 @@ namespace CamelotEngine
         void render(const RenderOperation& op);
 
         void setScissorRect(UINT32 left = 0, UINT32 top = 0, UINT32 right = 800, UINT32 bottom = 600);
-        void clearFrameBuffer(unsigned int buffers, 
+        void clear(RenderTargetPtr target, unsigned int buffers, 
             const Color& colour = Color::Black, 
             float depth = 1.0f, unsigned short stencil = 0);
 

+ 15 - 1
CamelotD3D9Renderer/Source/CmD3D9RenderSystem.cpp

@@ -1412,11 +1412,18 @@ namespace CamelotEngine
 		}
 	}
 	//---------------------------------------------------------------------
-	void D3D9RenderSystem::clearFrameBuffer(unsigned int buffers, 
+	void D3D9RenderSystem::clear(RenderTargetPtr target, unsigned int buffers, 
 		const Color& colour, float depth, unsigned short stencil)
 	{
 		THROW_IF_NOT_RENDER_THREAD;
 
+		RenderTarget* previousRenderTarget = mActiveRenderTarget;
+		if(target.get() != mActiveRenderTarget)
+		{
+			previousRenderTarget = mActiveRenderTarget;
+			setRenderTarget(target.get());
+		}
+
 		DWORD flags = 0;
 		if (buffers & FBT_COLOUR)
 		{
@@ -1426,11 +1433,13 @@ namespace CamelotEngine
 		{
 			flags |= D3DCLEAR_ZBUFFER;
 		}
+
 		// Only try to clear the stencil buffer if supported
 		if (buffers & FBT_STENCIL && mCurrentCapabilities->hasCapability(RSC_HWSTENCIL))
 		{
 			flags |= D3DCLEAR_STENCIL;
 		}
+
 		HRESULT hr;
 		if( FAILED( hr = getActiveD3D9Device()->Clear( 
 			0, 
@@ -1443,6 +1452,11 @@ namespace CamelotEngine
 			String msg = DXGetErrorDescription(hr);
 			CM_EXCEPT(RenderingAPIException, "Error clearing frame buffer : " + msg);
 		}
+
+		if(target.get() != previousRenderTarget)
+		{
+			setRenderTarget(previousRenderTarget);
+		}
 	}
 	//---------------------------------------------------------------------
 	IDirect3D9*	D3D9RenderSystem::getDirect3D9()

+ 2 - 1
CamelotForwardRenderer/Source/CmForwardRenderer.cpp

@@ -10,6 +10,7 @@
 #include "CmRasterizerState.h"
 #include "CmDepthStencilState.h"
 #include "CmApplication.h"
+#include "CmViewport.h"
 
 namespace CamelotEngine
 {
@@ -51,7 +52,7 @@ namespace CamelotEngine
 
 		Matrix4 viewProjMatrix = projMatrixCstm * viewMatrixCstm;
 
-		renderContext->clearFrameBuffer(FBT_COLOUR | FBT_DEPTH, Color::Blue);
+		renderContext->clear(camera->getViewport()->getTarget(), FBT_COLOUR | FBT_DEPTH, Color::Blue);
 		renderContext->beginFrame();
 
 		// TODO - sort renderables by material/pass/parameters to minimize state changes

+ 2 - 2
CamelotGLRenderer/Include/CmGLRenderSystem.h

@@ -137,9 +137,9 @@ namespace CamelotEngine {
         void render(const RenderOperation& op);
 
 		/**
-		 * @copydoc RenderSystem::clearFrameBuffer()
+		 * @copydoc RenderSystem::clear()
 		 */
-        void clearFrameBuffer(unsigned int buffers, 
+        void clear(RenderTargetPtr target, unsigned int buffers, 
             const Color& colour = Color::Black, 
             float depth = 1.0f, unsigned short stencil = 0);
 

+ 18 - 25
CamelotGLRenderer/Source/CmGLRenderSystem.cpp

@@ -796,11 +796,18 @@ namespace CamelotEngine
 		mScissorRight = right;
 	}
 	//---------------------------------------------------------------------
-	void GLRenderSystem::clearFrameBuffer(unsigned int buffers, 
+	void GLRenderSystem::clear(RenderTargetPtr target, unsigned int buffers, 
 		const Color& colour, float depth, unsigned short stencil)
 	{
 		THROW_IF_NOT_RENDER_THREAD;
 
+		RenderTarget* previousRenderTarget = mActiveRenderTarget;
+		if(target.get() != mActiveRenderTarget)
+		{
+			previousRenderTarget = mActiveRenderTarget;
+			setRenderTarget(target.get());
+		}
+
 		bool colourMask = !mColourWrite[0] || !mColourWrite[1] 
 		|| !mColourWrite[2] || !mColourWrite[3]; 
 
@@ -834,39 +841,20 @@ namespace CamelotEngine
 			glClearStencil(stencil);
 		}
 
-		// Should be enable scissor test due the clear region is
-		// relied on scissor box bounds.
+		// Disable scissor test as we want to clear the entire render surface
 		GLboolean scissorTestEnabled = glIsEnabled(GL_SCISSOR_TEST);
-		if (!scissorTestEnabled)
-		{
-			glEnable(GL_SCISSOR_TEST);
-		}
-
-		// Sets the scissor box as same as viewport
-        GLint viewport[4] = { 0, 0, 0, 0 };
-        GLint scissor[4] = { 0, 0, 0, 0 };
-		glGetIntegerv(GL_VIEWPORT, viewport);
-		glGetIntegerv(GL_SCISSOR_BOX, scissor);
-		bool scissorBoxDifference =
-			viewport[0] != scissor[0] || viewport[1] != scissor[1] ||
-			viewport[2] != scissor[2] || viewport[3] != scissor[3];
-		if (scissorBoxDifference)
+		if (scissorTestEnabled)
 		{
-			glScissor(viewport[0], viewport[1], viewport[2], viewport[3]);
+			glDisable(GL_SCISSOR_TEST);
 		}
 
 		// Clear buffers
 		glClear(flags);
 
-		// Restore scissor box
-		if (scissorBoxDifference)
-		{
-			glScissor(scissor[0], scissor[1], scissor[2], scissor[3]);
-		}
 		// Restore scissor test
-		if (!scissorTestEnabled)
+		if (scissorTestEnabled)
 		{
-			glDisable(GL_SCISSOR_TEST);
+			glEnable(GL_SCISSOR_TEST);
 		}
 
 		// Reset buffer write state
@@ -882,6 +870,11 @@ namespace CamelotEngine
 		{
 			glStencilMask(mStencilWriteMask);
 		}
+
+		if(target.get() != previousRenderTarget)
+		{
+			setRenderTarget(previousRenderTarget);
+		}
 	}
 
 

+ 2 - 2
CamelotRenderer/Include/CmDeferredRenderContext.h

@@ -84,8 +84,8 @@ namespace CamelotEngine
 
 		/** @copydoc RenderSystem::swapAllRenderTargetBuffers() */
 		void swapAllRenderTargetBuffers(bool waitForVsync = true);
-		/** @copydoc RenderSystem::clearFrameBuffer() */
-		void clearFrameBuffer(unsigned int buffers, const Color& color = Color::Black, float depth = 1.0f, unsigned short stencil = 0);
+		/** @copydoc RenderSystem::clear() */
+		void clear(RenderTargetPtr target, unsigned int buffers, const Color& color = Color::Black, float depth = 1.0f, unsigned short stencil = 0);
 
 		/**
 		 * @brief	Makes all the currently queued commands available to the GPU. They will be executed

+ 4 - 2
CamelotRenderer/Include/CmRenderSystem.h

@@ -280,14 +280,16 @@ namespace CamelotEngine
 		*/
 		virtual void setScissorRect(UINT32 left = 0, UINT32 top = 0, UINT32 right = 800, UINT32 bottom = 600) = 0;
 
-		/** Clears one or more frame buffers on the active render target. 
+		/** Clears the provided render target to the specified values
+		@param renderTarget Render target to clear. Entire surface will be cleared
+				regardless of viewport or scissor rect.
 		@param buffers Combination of one or more elements of FrameBufferType
 		denoting which buffers are to be cleared
 		@param colour The colour to clear the colour buffer with, if enabled
 		@param depth The value to initialise the depth buffer with, if enabled
 		@param stencil The value to initialise the stencil buffer with, if enabled.
 		*/
-		virtual void clearFrameBuffer(unsigned int buffers, 
+		virtual void clear(RenderTargetPtr renderTarget, unsigned int buffers, 
 			const Color& color = Color::Black, 
 			float depth = 1.0f, unsigned short stencil = 0) = 0;
 

+ 0 - 47
CamelotRenderer/Include/CmViewport.h

@@ -88,22 +88,6 @@ namespace CamelotEngine {
         */
         virtual ~Viewport();
 
-		/** Instructs the viewport to clear itself, without performing an update.
-		 @remarks
-			You would not normally call this method when updating the viewport, 
-			since the viewport usually clears itself when updating anyway (@see 
-		    Viewport::setClearEveryFrame). However, if you wish you have the
-			option of manually clearing the frame buffer (or elements of it)
-		    using this method.
-		 @param buffers Bitmask identifying which buffer elements to clear
-		 @param colour The colour value to clear to, if FBT_COLOUR is included
-		 @param depth The depth value to clear to, if FBT_DEPTH is included
-		 @param stencil The stencil value to clear to, if FBT_STENCIL is included
-		*/
-		void clear(unsigned int buffers = FBT_COLOUR | FBT_DEPTH,
-				   const Color& colour = Color::Black, 
-				   float depth = 1.0f, unsigned short stencil = 0);
-
         /** Retrieves a pointer to the render target for this viewport.
         */
         RenderTargetPtr getTarget(void) const;
@@ -164,33 +148,6 @@ namespace CamelotEngine {
         */
         void setDimensions(float left, float top, float width, float height);
 
-        /** Sets the initial background colour of the viewport (before
-            rendering).
-        */
-        void setBackgroundColour(const Color& colour);
-
-        /** Gets the background colour.
-        */
-        const Color& getBackgroundColour(void) const;
-
-        /** Determines whether to clear the viewport before rendering.
-		@remarks
-			You can use this method to set which buffers are cleared
-			(if any) before rendering every frame.
-        @param clear Whether or not to clear any buffers
-		@param buffers One or more values from FrameBufferType denoting
-			which buffers to clear, if clear is set to true. Note you should
-			not clear the stencil buffer here unless you know what you're doing.
-         */
-        void setClearEveryFrame(bool clear, unsigned int buffers = FBT_COLOUR | FBT_DEPTH);
-
-        /** Determines if the viewport is cleared before every frame.
-        */
-        bool getClearEveryFrame(void) const;
-
-		/** Gets which buffers are to be cleared each frame. */
-        unsigned int getClearBuffers(void) const;
-
 		/** Access to actual dimensions (based on target size).
         */
         void getActualDimensions(
@@ -204,10 +161,6 @@ namespace CamelotEngine {
         int mActLeft, mActTop, mActWidth, mActHeight;
         /// ZOrder
         int mZOrder;
-        /// Background options
-        Color mBackColour;
-        bool mClearEveryFrame;
-		unsigned int mClearBuffers;
 
 		/** Notifies the viewport of a possible change in dimensions.
             @remarks

+ 2 - 2
CamelotRenderer/Source/CmDeferredRenderContext.cpp

@@ -123,9 +123,9 @@ namespace CamelotEngine
 		mCommandQueue->queue(boost::bind(&RenderSystem::setRenderTarget, mRenderSystem, target));
 	}
 
-	void DeferredRenderContext::clearFrameBuffer(unsigned int buffers, const Color& color, float depth, unsigned short stencil)
+	void DeferredRenderContext::clear(RenderTargetPtr target, unsigned int buffers, const Color& color, float depth, unsigned short stencil)
 	{
-		mCommandQueue->queue(boost::bind(&RenderSystem::clearFrameBuffer, mRenderSystem, buffers, color, depth, stencil));
+		mCommandQueue->queue(boost::bind(&RenderSystem::clear, mRenderSystem, target, buffers, color, depth, stencil));
 	}
 
 	void DeferredRenderContext::beginFrame()

+ 0 - 46
CamelotRenderer/Source/CmViewport.cpp

@@ -43,9 +43,6 @@ namespace CamelotEngine {
 		, mRelHeight(0)
 		// Actual dimensions will update later
 		, mZOrder(0)
-		, mBackColour(Color::Black)
-		, mClearEveryFrame(true)
-		, mClearBuffers(FBT_COLOUR | FBT_DEPTH)
 	{
 		// Calculate actual dimensions
 		updateDimensions();
@@ -59,9 +56,6 @@ namespace CamelotEngine {
         , mRelHeight(height)
         // Actual dimensions will update later
         , mZOrder(ZOrder)
-        , mBackColour(Color::Black)
-        , mClearEveryFrame(true)
-		, mClearBuffers(FBT_COLOUR | FBT_DEPTH)
     {
         // Calculate actual dimensions
         updateDimensions();
@@ -145,46 +139,6 @@ namespace CamelotEngine {
         updateDimensions();
     }
     //---------------------------------------------------------------------
-    void Viewport::setBackgroundColour(const Color& colour)
-    {
-        mBackColour = colour;
-    }
-    //---------------------------------------------------------------------
-    const Color& Viewport::getBackgroundColour(void) const
-    {
-        return mBackColour;
-    }
-    //---------------------------------------------------------------------
-    void Viewport::setClearEveryFrame(bool inClear, unsigned int inBuffers)
-    {
-        mClearEveryFrame = inClear;
-		mClearBuffers = inBuffers;
-    }
-    //---------------------------------------------------------------------
-    bool Viewport::getClearEveryFrame(void) const
-    {
-        return mClearEveryFrame;
-    }
-    //---------------------------------------------------------------------
-    unsigned int Viewport::getClearBuffers(void) const
-    {
-        return mClearBuffers;
-    }
-    //---------------------------------------------------------------------
-	void Viewport::clear(unsigned int buffers, const Color& col,  
-						 float depth, unsigned short stencil)
-	{
-		RenderSystem* rs = CamelotEngine::RenderSystem::instancePtr();
-		if (rs)
-		{
-			Viewport currentvp = rs->getViewport();
-
-			rs->setViewport(*this);
-			rs->clearFrameBuffer(buffers, col, depth, stencil);
-			rs->setViewport(currentvp);
-		}
-	}
-    //---------------------------------------------------------------------
     void Viewport::getActualDimensions(int &left, int&top, int &width, int &height) const
     {
         left = mActLeft;

+ 1 - 9
CamelotRenderer/TODO.txt

@@ -68,15 +68,6 @@ Handling of array parameters? This needs testing
 
 ---------------------------------------------------
 
-RenderSystem::clearFrameBuffer
- - Change so it accepts a RenderTarget as a parameter
-
-RenderSystem::setScissorRect(RECT[] array)
- - Change it so it accepts an array
-
-RenderSystem::setViewport(RECT[] array)
- - Change it so it accepts an array
-
 monitorIndex is ignored in DX11
 
 Creating a primary window and initializing the render system should probably be one step
@@ -123,6 +114,7 @@ RenderSystem needed modifications
   
  - Low priority
   - OpenGL provides image load/store which seems to be GL UAV equivalent (http://www.opengl.org/wiki/Image_Load_Store)
+  - Resolving MSAA textures (i.e. copying them to non-MSAA so they can be displayed on-screen). DX has ResolveSubresource, and OpenGL might have something similar.
   - Single and dual channel textures (especially render textures, which are very important for effects like SSAO)
   - Compute pipeline
   - Instancing (DrawInstanced) (DX11 and GL)