Przeglądaj źródła

Added depth stencil state

Marko Pintera 13 lat temu
rodzic
commit
2f668d6cbe

+ 90 - 12
CamelotD3D9Renderer/Include/CmD3D9RenderSystem.h

@@ -51,14 +51,6 @@ namespace CamelotEngine
 
 		const String& getName() const;
 
-		void setStencilCheckEnabled(bool enabled);
-        void setStencilBufferParams(CompareFunction func = CMPF_ALWAYS_PASS, 
-            UINT32 refValue = 0, UINT32 mask = 0xFFFFFFFF, 
-            StencilOperation stencilFailOp = SOP_KEEP, 
-            StencilOperation depthFailOp = SOP_KEEP,
-            StencilOperation passOp = SOP_KEEP, 
-            bool twoSidedOperation = false);
-
 		void createRenderWindow_internal(const String &name, unsigned int width, unsigned int height, 
 			bool fullScreen, const NameValuePairList& miscParams, AsyncOp& asyncOp);
 		void destroyRenderTarget(RenderTarget* renderTarget);
@@ -86,15 +78,21 @@ namespace CamelotEngine
 		 */
 		void setRasterizerState(const RasterizerState& rasterizerState);
 
+		/**
+		 * @copydoc RenderSystem::setDepthStencilState()
+		 */
+		void setDepthStencilState(const DepthStencilState& depthStencilState);
+
+		/**
+		 * @copydoc RenderSystem::setStencilRefValue()
+		 */
+		void setStencilRefValue(UINT32 refValue);
+
 		void disableTextureUnit(UINT16 texUnit);
 		void setViewport(const Viewport& vp);		
 		void beginFrame();
 		void endFrame();		
 
-		void setDepthBufferParams( bool depthTest = true, bool depthWrite = true, CompareFunction depthFunction = CMPF_LESS_EQUAL );
-		void setDepthBufferCheckEnabled( bool enabled = true );
-		void setDepthBufferWriteEnabled(bool enabled = true);
-		void setDepthBufferFunction( CompareFunction func = CMPF_LESS_EQUAL );
 		void convertProjectionMatrix(const Matrix4& matrix, Matrix4& dest, bool forGpuProgram = false);
 		void setVertexDeclaration(VertexDeclarationPtr decl);
 		void setVertexBufferBinding(VertexBufferBinding* binding);
@@ -422,6 +420,86 @@ namespace CamelotEngine
 		*/
 		void setScissorTestEnable(bool enable);
 
+		/************************************************************************/
+		/* 						Depth stencil state                      		*/
+		/************************************************************************/
+		
+		/** Sets the mode of operation for depth buffer tests from this point onwards.
+		Sometimes you may wish to alter the behaviour of the depth buffer to achieve
+		special effects. Because it's unlikely that you'll set these options for an entire frame,
+		but rather use them to tweak settings between rendering objects, this is an internal
+		method (indicated by the '_' prefix) which will be used by a SceneManager implementation
+		rather than directly from the client application.
+		If this method is never called the settings are automatically the same as the default parameters.
+		@param depthTest If true, the depth buffer is tested for each pixel and the frame buffer is only updated
+		if the depth function test succeeds. If false, no test is performed and pixels are always written.
+		@param depthWrite If true, the depth buffer is updated with the depth of the new pixel if the depth test succeeds.
+		If false, the depth buffer is left unchanged even if a new pixel is written.
+		@param depthFunction Sets the function required for the depth test.
+		*/
+		void setDepthBufferParams(bool depthTest = true, bool depthWrite = true, CompareFunction depthFunction = CMPF_LESS_EQUAL);
+
+		/** Sets whether or not the depth buffer check is performed before a pixel write.
+		@param enabled If true, the depth buffer is tested for each pixel and the frame buffer is only updated
+		if the depth function test succeeds. If false, no test is performed and pixels are always written.
+		*/
+		void setDepthBufferCheckEnabled(bool enabled = true);
+
+		/** Sets whether or not the depth buffer is updated after a pixel write.
+		@param enabled If true, the depth buffer is updated with the depth of the new pixel if the depth test succeeds.
+		If false, the depth buffer is left unchanged even if a new pixel is written.
+		*/
+		void setDepthBufferWriteEnabled(bool enabled = true);
+
+		/** Sets the comparison function for the depth buffer check.
+		Advanced use only - allows you to choose the function applied to compare the depth values of
+		new and existing pixels in the depth buffer. Only an issue if the deoth buffer check is enabled
+		(see _setDepthBufferCheckEnabled)
+		@param  func The comparison between the new depth and the existing depth which must return true
+		for the new pixel to be written.
+		*/
+		void setDepthBufferFunction(CompareFunction func = CMPF_LESS_EQUAL);
+
+		/** Turns stencil buffer checking on or off.
+		@remarks
+		Stencilling (masking off areas of the rendering target based on the stencil
+		buffer) can be turned on or off using this method. By default, stencilling is
+		disabled.
+		*/
+		void setStencilCheckEnabled(bool enabled);
+
+		/** This method allows you to set stencil buffer operations in one call.
+		@param stencilFailOp The action to perform when the stencil check fails
+		@param depthFailOp The action to perform when the stencil check passes, but the
+		depth buffer check still fails
+		@param passOp The action to take when both the stencil and depth check pass.
+		@param ccw If set to true, the stencil operations will be applied to counterclockwise
+		faces. Otherwise they will be applied to clockwise faces.
+		*/
+		void setStencilBufferOperations(StencilOperation stencilFailOp = SOP_KEEP,
+			StencilOperation depthFailOp = SOP_KEEP, StencilOperation passOp = SOP_KEEP,
+			bool ccw = true);
+
+		/**
+		* @brief	Sets a stencil buffer comparison function. The result of this will cause one of 3 actions depending on whether the test fails,
+		*		succeeds but with the depth buffer check still failing, or succeeds with the
+		*		depth buffer check passing too.
+		* @param ccw If set to true, the stencil operations will be applied to counterclockwise
+		*		faces. Otherwise they will be applied to clockwise faces.
+		 */
+		void setStencilBufferFunc(CompareFunction func = CMPF_ALWAYS_PASS, bool ccw = true);
+
+		/**
+		* @brief	The bitmask applied to both the stencil value and the reference value
+		*		before comparison
+		 */
+		void setStencilBufferReadMask(UINT32 mask = 0xFFFFFFFF);
+
+		/**
+		* @brief	The bitmask applied to the stencil value before writing it to the stencil buffer.
+		 */
+		void setStencilBufferWriteMask(UINT32 mask = 0xFFFFFFFF);
+
 		/// Notify when a device has been lost.
 		void notifyOnDeviceLost(D3D9Device* device);
 

+ 91 - 51
CamelotD3D9Renderer/Source/CmD3D9RenderSystem.cpp

@@ -51,6 +51,7 @@ THE SOFTWARE.
 #include "CmAsyncOp.h"
 #include "CmBlendState.h"
 #include "CmRasterizerState.h"
+#include "CmDepthStencilState.h"
 
 #if CM_DEBUG_MODE
 #define THROW_IF_NOT_RENDER_THREAD throwIfNotRenderThread();
@@ -604,14 +605,14 @@ namespace CamelotEngine
 
 		// Color write mask
 		UINT8 writeMask = blendState.getRenderTargetWriteMask(0);
-		setColorBufferWriteEnabled(writeMask & 0x1, writeMask & 0x2, writeMask & 0x4, writeMask & 0x8);
+		setColorBufferWriteEnabled((writeMask & 0x1) != 0, (writeMask & 0x2) != 0, (writeMask & 0x4) != 0, (writeMask & 0x8) != 0);
 	}
 	//----------------------------------------------------------------------
 	void D3D9RenderSystem::setRasterizerState(const RasterizerState& rasterizerState)
 	{
 		THROW_IF_NOT_RENDER_THREAD;
 
-		setDepthBias(rasterizerState.getDepthBias(), rasterizerState.getSlopeScaledDepthBias());
+		setDepthBias((float)rasterizerState.getDepthBias(), rasterizerState.getSlopeScaledDepthBias());
 
 		setCullingMode(rasterizerState.getCullMode());
 
@@ -619,6 +620,37 @@ namespace CamelotEngine
 
 		setScissorTestEnable(rasterizerState.getScissorEnable());
 	}
+	//----------------------------------------------------------------------
+	void D3D9RenderSystem::setDepthStencilState(const DepthStencilState& depthStencilState)
+	{
+		THROW_IF_NOT_RENDER_THREAD;
+
+		// Set stencil buffer options
+		setStencilCheckEnabled(depthStencilState.getStencilEnable());
+
+		setStencilBufferOperations(depthStencilState.getStencilFrontFailOp(), depthStencilState.getStencilFrontZFailOp(), depthStencilState.getStencilFrontPassOp(), true);
+		setStencilBufferFunc(depthStencilState.getStencilFrontCompFunc(), true);
+
+		setStencilBufferOperations(depthStencilState.getStencilBackFailOp(), depthStencilState.getStencilBackZFailOp(), depthStencilState.getStencilBackPassOp(), false);
+		setStencilBufferFunc(depthStencilState.getStencilBackCompFunc(), false);
+
+		setStencilBufferReadMask(depthStencilState.getStencilReadMask());
+		setStencilBufferWriteMask(depthStencilState.getStencilWriteMask());
+
+		// Set depth buffer options
+		setDepthBufferCheckEnabled(depthStencilState.getDepthReadEnable());
+		setDepthBufferWriteEnabled(depthStencilState.getDepthWriteEnable());
+		setDepthBufferFunction(depthStencilState.getDepthComparisonFunc());		
+	}
+	//----------------------------------------------------------------------
+	void D3D9RenderSystem::setStencilRefValue(UINT32 refValue)
+	{
+		THROW_IF_NOT_RENDER_THREAD;
+
+		HRESULT hr = __SetRenderState(D3DRS_STENCILREF, refValue);
+		if (FAILED(hr))
+			CM_EXCEPT(RenderingAPIException, "Error setting stencil buffer reference value.");
+	}
 	//---------------------------------------------------------------------
 	void D3D9RenderSystem::setTextureMipmapBias(UINT16 unit, float bias)
 	{
@@ -631,7 +663,6 @@ namespace CamelotEngine
 				*(DWORD*)&bias);
 			if(FAILED(hr))
 				CM_EXCEPT(RenderingAPIException, "Unable to set texture mipmap bias");
-
 		}
 	}
 	//---------------------------------------------------------------------
@@ -908,84 +939,93 @@ namespace CamelotEngine
 		HRESULT hr = __SetRenderState(D3DRS_STENCILENABLE, enabled);
 		if (FAILED(hr))
 			CM_EXCEPT(RenderingAPIException, "Error enabling / disabling stencilling.");
+
+		if (mCurrentCapabilities->hasCapability(RSC_TWO_SIDED_STENCIL))
+		{
+			hr = __SetRenderState(D3DRS_TWOSIDEDSTENCILMODE, TRUE);
+
+			if (FAILED(hr))
+				CM_EXCEPT(RenderingAPIException, "Error setting 2-sided stencil mode.");
+		}
+		else
+		{
+			hr = __SetRenderState(D3DRS_TWOSIDEDSTENCILMODE, FALSE);
+
+			if (FAILED(hr))
+				CM_EXCEPT(RenderingAPIException, "Error setting 1-sided stencil mode.");
+		}
 	}
 	//---------------------------------------------------------------------
-	void D3D9RenderSystem::setStencilBufferParams(CompareFunction func, 
-		UINT32 refValue, UINT32 mask, StencilOperation stencilFailOp, 
-		StencilOperation depthFailOp, StencilOperation passOp, 
-		bool twoSidedOperation)
+	void D3D9RenderSystem::setStencilBufferOperations(StencilOperation stencilFailOp, StencilOperation depthFailOp, StencilOperation passOp, bool ccw)
 	{
 		THROW_IF_NOT_RENDER_THREAD;
 
 		HRESULT hr;
-		bool flip;
 
 		// 2-sided operation
-		if (twoSidedOperation)
+		if (ccw)
 		{
-			if (!mCurrentCapabilities->hasCapability(RSC_TWO_SIDED_STENCIL))
-				CM_EXCEPT(InvalidParametersException, "2-sided stencils are not supported");
-			hr = __SetRenderState(D3DRS_TWOSIDEDSTENCILMODE, TRUE);
-			if (FAILED(hr))
-				CM_EXCEPT(RenderingAPIException, "Error setting 2-sided stencil mode.");
-			// NB: We should always treat CCW as front face for consistent with default
-			// culling mode. Therefore, we must take care with two-sided stencil settings.
-			flip = (mInvertVertexWinding && mActiveRenderTarget->requiresTextureFlipping()) ||
-				(!mInvertVertexWinding && !mActiveRenderTarget->requiresTextureFlipping());
-
-			// Set alternative versions of ops
 			// fail op
-			hr = __SetRenderState(D3DRS_CCW_STENCILFAIL, D3D9Mappings::get(stencilFailOp, !flip));
+			hr = __SetRenderState(D3DRS_CCW_STENCILFAIL, D3D9Mappings::get(stencilFailOp, mInvertVertexWinding));
 			if (FAILED(hr))
-				CM_EXCEPT(RenderingAPIException, "Error setting stencil fail operation (2-sided).");
+				CM_EXCEPT(RenderingAPIException, "Error setting stencil fail operation (ccw).");
 
 			// depth fail op
-			hr = __SetRenderState(D3DRS_CCW_STENCILZFAIL, D3D9Mappings::get(depthFailOp, !flip));
+			hr = __SetRenderState(D3DRS_CCW_STENCILZFAIL, D3D9Mappings::get(depthFailOp, mInvertVertexWinding));
 			if (FAILED(hr))
-				CM_EXCEPT(RenderingAPIException, "Error setting stencil depth fail operation (2-sided).");
+				CM_EXCEPT(RenderingAPIException, "Error setting stencil depth fail operation (ccw).");
 
 			// pass op
-			hr = __SetRenderState(D3DRS_CCW_STENCILPASS, D3D9Mappings::get(passOp, !flip));
+			hr = __SetRenderState(D3DRS_CCW_STENCILPASS, D3D9Mappings::get(passOp, mInvertVertexWinding));
 			if (FAILED(hr))
-				CM_EXCEPT(RenderingAPIException, "Error setting stencil pass operation (2-sided).");
+				CM_EXCEPT(RenderingAPIException, "Error setting stencil pass operation (ccw).");
 		}
 		else
 		{
-			hr = __SetRenderState(D3DRS_TWOSIDEDSTENCILMODE, FALSE);
+			// fail op
+			hr = __SetRenderState(D3DRS_STENCILFAIL, D3D9Mappings::get(stencilFailOp, !mInvertVertexWinding));
 			if (FAILED(hr))
-				CM_EXCEPT(RenderingAPIException, "Error setting 1-sided stencil mode.");
-			flip = false;
+				CM_EXCEPT(RenderingAPIException, "Error setting stencil fail operation (cw).");
+
+			// depth fail op
+			hr = __SetRenderState(D3DRS_STENCILZFAIL, D3D9Mappings::get(depthFailOp, !mInvertVertexWinding));
+			if (FAILED(hr))
+				CM_EXCEPT(RenderingAPIException, "Error setting stencil depth fail operation (cw).");
+
+			// pass op
+			hr = __SetRenderState(D3DRS_STENCILPASS, D3D9Mappings::get(passOp, !mInvertVertexWinding));
+			if (FAILED(hr))
+				CM_EXCEPT(RenderingAPIException, "Error setting stencil pass operation (cw).");
 		}
+	}
+	//---------------------------------------------------------------------
+	void D3D9RenderSystem::setStencilBufferFunc(CompareFunction func, bool ccw)
+	{
+		HRESULT hr;
+		
+		if(ccw)
+			hr = __SetRenderState(D3DRS_CCW_STENCILFUNC, D3D9Mappings::get(func));
+		else
+			hr = __SetRenderState(D3DRS_STENCILFUNC, D3D9Mappings::get(func));
 
-		// func
-		hr = __SetRenderState(D3DRS_STENCILFUNC, D3D9Mappings::get(func));
 		if (FAILED(hr))
 			CM_EXCEPT(RenderingAPIException, "Error setting stencil buffer test function.");
+	}
+	//---------------------------------------------------------------------
+	void D3D9RenderSystem::setStencilBufferReadMask(UINT32 mask)
+	{
+		HRESULT hr = __SetRenderState(D3DRS_STENCILMASK, mask);
 
-		// reference value
-		hr = __SetRenderState(D3DRS_STENCILREF, refValue);
-		if (FAILED(hr))
-			CM_EXCEPT(RenderingAPIException, "Error setting stencil buffer reference value.");
-
-		// mask
-		hr = __SetRenderState(D3DRS_STENCILMASK, mask);
 		if (FAILED(hr))
 			CM_EXCEPT(RenderingAPIException, "Error setting stencil buffer mask.");
+	}
+	//--------------------------------------------------------------------
+	void D3D9RenderSystem::setStencilBufferWriteMask(UINT32 mask)
+	{
+		HRESULT hr = __SetRenderState(D3DRS_STENCILWRITEMASK, mask);
 
-		// fail op
-		hr = __SetRenderState(D3DRS_STENCILFAIL, D3D9Mappings::get(stencilFailOp, flip));
-		if (FAILED(hr))
-			CM_EXCEPT(RenderingAPIException, "Error setting stencil fail operation.");
-
-		// depth fail op
-		hr = __SetRenderState(D3DRS_STENCILZFAIL, D3D9Mappings::get(depthFailOp, flip));
-		if (FAILED(hr))
-			CM_EXCEPT(RenderingAPIException, "Error setting stencil depth fail operation.");
-
-		// pass op
-		hr = __SetRenderState(D3DRS_STENCILPASS, D3D9Mappings::get(passOp, flip));
 		if (FAILED(hr))
-			CM_EXCEPT(RenderingAPIException, "Error setting stencil pass operation.");
+			CM_EXCEPT(RenderingAPIException, "Error setting stencil buffer write mask.");
 	}
 	//---------------------------------------------------------------------
 	void D3D9RenderSystem::setTextureFiltering(UINT16 unit, FilterType ftype, 

+ 7 - 8
CamelotForwardRenderer/Source/CmForwardRenderer.cpp

@@ -8,6 +8,7 @@
 #include "CmPass.h"
 #include "CmBlendState.h"
 #include "CmRasterizerState.h"
+#include "CmDepthStencilState.h"
 #include "CmApplication.h"
 
 namespace CamelotEngine
@@ -29,9 +30,6 @@ namespace CamelotEngine
 	{
 		DeferredRenderContextPtr renderContext = gApplication().getPrimaryRenderContext();
 
-		// TODO - No point in setting these each frame?
-		renderContext->setDepthBufferParams();
-
 		const vector<CameraPtr>::type& allCameras = gSceneManager().getAllCameras();
 		for(auto iter = allCameras.begin(); iter != allCameras.end(); ++iter)
 		{
@@ -145,11 +143,12 @@ namespace CamelotEngine
 
 
 		// Set up non-texture related material settings
-		// Depth buffer settings
-		renderContext->setDepthBufferFunction(pass->getDepthFunction());
-		renderContext->setDepthBufferCheckEnabled(pass->getDepthCheckEnabled());
-		renderContext->setDepthBufferWriteEnabled(pass->getDepthWriteEnabled());
-
+		// Stencil & depth buffer settings
+		DepthStencilStatePtr depthStancilState = pass->getDepthStencilState();
+		if(depthStancilState != nullptr)
+			renderContext->setDepthStencilState(*depthStancilState);
+		else
+			renderContext->setDepthStencilState(DepthStencilState::getDefault());
 
 		RasterizerStatePtr rasterizerState = pass->getRasterizerState();
 		if(rasterizerState != nullptr)

+ 92 - 31
CamelotGLRenderer/Include/CmGLRenderSystem.h

@@ -100,6 +100,16 @@ namespace CamelotEngine {
 		 */
 		void setRasterizerState(const RasterizerState& rasterizerState);
 
+		/**
+		 * @copydoc RenderSystem::setDepthStencilState()
+		 */
+		void setDepthStencilState(const DepthStencilState& depthStencilState);
+
+		/**
+		 * @copydoc RenderSystem::setStencilRefValue()
+		 */
+		void setStencilRefValue(UINT32 refValue);
+
         /** See
           RenderSystem
          */
@@ -112,40 +122,11 @@ namespace CamelotEngine {
           RenderSystem
          */
         void endFrame(void);
-        /** See
-          RenderSystem
-         */
-        void setDepthBufferParams(bool depthTest = true, bool depthWrite = true, CompareFunction depthFunction = CMPF_LESS_EQUAL);
-        /** See
-          RenderSystem
-         */
-        void setDepthBufferCheckEnabled(bool enabled = true);
-        /** See
-          RenderSystem
-         */
-        void setDepthBufferWriteEnabled(bool enabled = true);
-        /** See
-          RenderSystem
-         */
-        void setDepthBufferFunction(CompareFunction func = CMPF_LESS_EQUAL);
         /** See
           RenderSystem
          */
         void convertProjectionMatrix(const Matrix4& matrix,
             Matrix4& dest, bool forGpuProgram = false);
-        /** See
-          RenderSystem
-         */
-        void setStencilCheckEnabled(bool enabled);
-        /** See
-          RenderSystem.
-         */
-        void setStencilBufferParams(CompareFunction func = CMPF_ALWAYS_PASS, 
-            UINT32 refValue = 0, UINT32 mask = 0xFFFFFFFF, 
-            StencilOperation stencilFailOp = SOP_KEEP, 
-            StencilOperation depthFailOp = SOP_KEEP,
-            StencilOperation passOp = SOP_KEEP, 
-            bool twoSidedOperation = false);
         /** See
           RenderSystem
          */
@@ -185,6 +166,12 @@ namespace CamelotEngine {
 		// Scissor test
 		UINT32 mScissorTop, mScissorBottom, mScissorLeft, mScissorRight;
 
+		UINT32 mStencilReadMask;
+		UINT32 mStencilWriteMask;
+		UINT32 mStencilRefValue;
+		CompareFunction mStencilCompareFront;
+		CompareFunction mStencilCompareBack;
+
         /// View matrix to set world against
         Matrix4 mViewMatrix;
         Matrix4 mWorldMatrix;
@@ -224,8 +211,6 @@ namespace CamelotEngine {
 
         /// Store last depth write state
         bool mDepthWrite;
-		/// Store last stencil mask state
-		UINT32 mStencilMask;
 		/// Store last colour write state
 		bool mColourWrite[4];
 
@@ -427,6 +412,82 @@ namespace CamelotEngine {
 		*/
 		void setScissorTestEnable(bool enable);
 
+		/************************************************************************/
+		/* 						Depth stencil state                      		*/
+		/************************************************************************/
+		
+		/** Sets the mode of operation for depth buffer tests from this point onwards.
+		Sometimes you may wish to alter the behaviour of the depth buffer to achieve
+		special effects. Because it's unlikely that you'll set these options for an entire frame,
+		but rather use them to tweak settings between rendering objects, this is an internal
+		method (indicated by the '_' prefix) which will be used by a SceneManager implementation
+		rather than directly from the client application.
+		If this method is never called the settings are automatically the same as the default parameters.
+		@param depthTest If true, the depth buffer is tested for each pixel and the frame buffer is only updated
+		if the depth function test succeeds. If false, no test is performed and pixels are always written.
+		@param depthWrite If true, the depth buffer is updated with the depth of the new pixel if the depth test succeeds.
+		If false, the depth buffer is left unchanged even if a new pixel is written.
+		@param depthFunction Sets the function required for the depth test.
+		*/
+		void setDepthBufferParams(bool depthTest = true, bool depthWrite = true, CompareFunction depthFunction = CMPF_LESS_EQUAL);
+
+		/** Sets whether or not the depth buffer check is performed before a pixel write.
+		@param enabled If true, the depth buffer is tested for each pixel and the frame buffer is only updated
+		if the depth function test succeeds. If false, no test is performed and pixels are always written.
+		*/
+		void setDepthBufferCheckEnabled(bool enabled = true);
+
+		/** Sets whether or not the depth buffer is updated after a pixel write.
+		@param enabled If true, the depth buffer is updated with the depth of the new pixel if the depth test succeeds.
+		If false, the depth buffer is left unchanged even if a new pixel is written.
+		*/
+		void setDepthBufferWriteEnabled(bool enabled = true);
+
+		/** Sets the comparison function for the depth buffer check.
+		Advanced use only - allows you to choose the function applied to compare the depth values of
+		new and existing pixels in the depth buffer. Only an issue if the deoth buffer check is enabled
+		(see _setDepthBufferCheckEnabled)
+		@param  func The comparison between the new depth and the existing depth which must return true
+		for the new pixel to be written.
+		*/
+		void setDepthBufferFunction(CompareFunction func = CMPF_LESS_EQUAL);
+
+		/** Turns stencil buffer checking on or off.
+		@remarks
+		Stencilling (masking off areas of the rendering target based on the stencil
+		buffer) can be turned on or off using this method. By default, stencilling is
+		disabled.
+		*/
+		void setStencilCheckEnabled(bool enabled);
+
+		/** This method allows you to set stencil buffer operations in one call.
+		@param stencilFailOp The action to perform when the stencil check fails
+		@param depthFailOp The action to perform when the stencil check passes, but the
+		depth buffer check still fails
+		@param passOp The action to take when both the stencil and depth check pass.
+		@param ccw If set to true, the stencil operations will be applied to counterclockwise
+		faces. Otherwise they will be applied to clockwise faces.
+		*/
+		void setStencilBufferOperations(StencilOperation stencilFailOp = SOP_KEEP,
+			StencilOperation depthFailOp = SOP_KEEP, StencilOperation passOp = SOP_KEEP,
+			bool front = true);
+
+		/**
+		* @brief	Sets a stencil buffer comparison function. The result of this will cause one of 3 actions depending on whether the test fails,
+		*		succeeds but with the depth buffer check still failing, or succeeds with the
+		*		depth buffer check passing too.
+		* @param mask The bitmask applied to both the stencil value and the reference value
+		*		before comparison
+		* @param ccw If set to true, the stencil operations will be applied to counterclockwise
+		*		faces. Otherwise they will be applied to clockwise faces.
+		 */
+		void setStencilBufferFunc(CompareFunction func = CMPF_ALWAYS_PASS, UINT32 mask = 0xFFFFFFFF, bool front = true);
+
+		/**
+		* @brief	The bitmask applied to the stencil value before writing it to the stencil buffer.
+		 */
+		void setStencilBufferWriteMask(UINT32 mask = 0xFFFFFFFF);
+
 		// ----------------------------------
         // GLRenderSystem specific members
         // ----------------------------------

Plik diff jest za duży
+ 533 - 562
CamelotGLRenderer/Source/CmGLRenderSystem.cpp


+ 1 - 0
CamelotRenderer/CamelotRenderer.vcxproj

@@ -189,6 +189,7 @@
     <ClInclude Include="Include\CmConfigOptionMap.h" />
     <ClInclude Include="Include\CmDefaultHardwareBufferManager.h" />
     <ClInclude Include="Include\CmDeferredRenderContext.h" />
+    <ClInclude Include="Include\CmDepthStencilStateRTTI.h" />
     <ClInclude Include="Include\CmDepthStencilState.h" />
     <ClInclude Include="Include\CmGpuProgram.h" />
     <ClInclude Include="Include\CmGpuProgramManager.h" />

+ 3 - 0
CamelotRenderer/CamelotRenderer.vcxproj.filters

@@ -338,6 +338,9 @@
     <ClInclude Include="Include\CmRasterizerStateRTTI.h">
       <Filter>Header Files\RTTI</Filter>
     </ClInclude>
+    <ClInclude Include="Include\CmDepthStencilStateRTTI.h">
+      <Filter>Header Files\RTTI</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="Source\CamelotRenderer.cpp">

+ 6 - 16
CamelotRenderer/Include/CmDeferredRenderContext.h

@@ -45,25 +45,15 @@ namespace CamelotEngine
 		/** @copydoc RenderSystem::setRasterizerState() */
 		void setRasterizerState(const RasterizerState& rasterizerState);
 
+		/** @copydoc RenderSystem::setRasterizerState() */
+		void setDepthStencilState(const DepthStencilState& depthStencilState);
+
+		/** @copydoc RenderSystem::setStencilRefValue() */
+		void setStencilRefValue(UINT32 refValue);
+
 		/** @copydoc RenderSystem::setViewport() */
 		void setViewport(const Viewport& vp);
 
-		/** @copydoc RenderSystem::setDepthBufferParams() */
-		void setDepthBufferParams(bool depthTest = true, bool depthWrite = true, CompareFunction depthFunction = CMPF_LESS_EQUAL);
-		/** @copydoc RenderSystem::setDepthBufferCheckEnabled() */
-		void setDepthBufferCheckEnabled(bool enabled = true);
-		/** @copydoc RenderSystem::setDepthBufferWriteEnabled() */
-		void setDepthBufferWriteEnabled(bool enabled = true);
-		/** @copydoc RenderSystem::setDepthBufferFunction() */
-		void setDepthBufferFunction(CompareFunction func = CMPF_LESS_EQUAL);
-
-		/** @copydoc RenderSystem::setStencilCheckEnabled() */
-		void setStencilCheckEnabled(bool enabled);
-		/** @copydoc RenderSystem::setStencilBufferParams() */
-		void setStencilBufferParams(CompareFunction func = CMPF_ALWAYS_PASS, UINT32 refValue = 0, UINT32 mask = 0xFFFFFFFF, 
-			StencilOperation stencilFailOp = SOP_KEEP, StencilOperation depthFailOp = SOP_KEEP, StencilOperation passOp = SOP_KEEP, 
-			bool twoSidedOperation = false);
-
 		/** @copydoc RenderSystem::setClipPlanes() */
 		void setClipPlanes(const PlaneList& clipPlanes);
 		/** @copydoc RenderSystem::addClipPlane(const Plane&) */

+ 20 - 10
CamelotRenderer/Include/CmDepthStencilState.h

@@ -2,12 +2,13 @@
 
 #include "CmPrerequisites.h"
 #include "CmCommon.h"
+#include "CmIReflectable.h"
 
 namespace CamelotEngine
 {
-	struct CM_EXPORT DEPTH_STENCIL_DESC
+	struct CM_EXPORT DEPTH_STENCIL_STATE_DESC
 	{
-		DEPTH_STENCIL_DESC()
+		DEPTH_STENCIL_STATE_DESC()
 			: depthReadEnable(true)
 			, depthWriteEnable(true)
 			, depthComparisonFunc(CMPF_LESS)
@@ -44,7 +45,7 @@ namespace CamelotEngine
 	};
 
 	// TODO Low priority - Write doc explaining various states
-	class CM_EXPORT DepthStencilState
+	class CM_EXPORT DepthStencilState : public IReflectable
 	{
 	public:
 		virtual ~DepthStencilState() {}
@@ -67,17 +68,26 @@ namespace CamelotEngine
 		StencilOperation getStencilBackPassOp() const { return mData.backStencilPassOp; }
 		CompareFunction getStencilBackCompFunc() const { return mData.backStencilComparisonFunc; }
 
-		void setStencilRefValue(UINT32 refValue) { mStencilRefValue = refValue; }
-		UINT32 getStencilRefValue() const { return mStencilRefValue; }
+		static DepthStencilStatePtr create(const DEPTH_STENCIL_STATE_DESC& desc);
 
-		static DepthStencilStatePtr create(const DEPTH_STENCIL_DESC& desc);
+		/**
+		 * @brief	Returns the default depth stencil state;
+		 */
+		static const DepthStencilState& getDefault();
 	private:
 		friend class RenderStateManager;
-		DepthStencilState();
 
-		virtual void initialize(const DEPTH_STENCIL_DESC& desc);
+		virtual void initialize(const DEPTH_STENCIL_STATE_DESC& desc);
 
-		DEPTH_STENCIL_DESC mData;
-		UINT32 mStencilRefValue;
+		DEPTH_STENCIL_STATE_DESC mData;
+
+		/************************************************************************/
+		/* 								RTTI		                     		*/
+		/************************************************************************/
+
+	public:
+		friend class DepthStencilStateRTTI;
+		static RTTITypeBase* getRTTIStatic();
+		virtual RTTITypeBase* getRTTI() const;	
 	};
 }

+ 52 - 0
CamelotRenderer/Include/CmDepthStencilStateRTTI.h

@@ -0,0 +1,52 @@
+#pragma once
+
+#include "CmPrerequisites.h"
+#include "CmRTTIType.h"
+#include "CmDepthStencilState.h"
+#include "CmRenderStateManager.h"
+
+namespace CamelotEngine
+{
+	class CM_EXPORT DepthStencilStateRTTI : public RTTIType<DepthStencilState, IReflectable, DepthStencilStateRTTI>
+	{
+	private:
+		DEPTH_STENCIL_STATE_DESC& getData(DepthStencilState* obj) { return obj->mData; }
+		void setData(DepthStencilState* obj, DEPTH_STENCIL_STATE_DESC& val) 
+		{ 
+			obj->mRTTIData = val;
+		} 
+
+	public:
+		DepthStencilStateRTTI()
+		{
+			addPlainField("mData", 0, &DepthStencilStateRTTI::getData, &DepthStencilStateRTTI::setData);
+		}
+
+		virtual void onDeserializationEnded(IReflectable* obj)
+		{
+			DepthStencilState* depthStencilState = static_cast<DepthStencilState*>(obj);
+			if(!depthStencilState->mRTTIData.empty())
+			{
+				DEPTH_STENCIL_STATE_DESC desc = boost::any_cast<DEPTH_STENCIL_STATE_DESC>(depthStencilState->mRTTIData);
+
+				depthStencilState->initialize(desc);
+			}
+		}
+
+		virtual const String& getRTTIName()
+		{
+			static String name = "DepthStencilState";
+			return name;
+		}
+
+		virtual UINT32 getRTTIId()
+		{
+			return TID_DepthStencilState;
+		}
+
+		virtual std::shared_ptr<IReflectable> newRTTIObject()
+		{
+			return RenderStateManager::instance().createEmptyDepthStencilState();
+		}
+	};
+}

+ 3 - 68
CamelotRenderer/Include/CmPass.h

@@ -17,26 +17,9 @@ namespace CamelotEngine
 	class CM_EXPORT Pass : public IReflectable
     {
     protected:
-        //-------------------------------------------------------------------------
-        // Depth buffer settings
-        bool mDepthCheck;
-        bool mDepthWrite;
-        CompareFunction mDepthFunc;
-        float mDepthBiasConstant;
-		float mDepthBiasSlopeScale;
-		float mDepthBiasPerIteration;
-
-        //-------------------------------------------------------------------------
-        // Culling mode
-        CullingMode mCullMode;
-
-        //-------------------------------------------------------------------------
-		/// Polygon mode
-		PolygonMode mPolygonMode;
-        //-------------------------------------------------------------------------
-
 		BlendStatePtr mBlendState;
 		RasterizerStatePtr mRasterizerState;
+		DepthStencilStatePtr mDepthStencilState;
 
 		// Vertex program
 		GpuProgramHandle mVertexProgram;
@@ -72,56 +55,8 @@ namespace CamelotEngine
 		void setRasterizerState(RasterizerStatePtr rasterizerState);
 		RasterizerStatePtr getRasterizerState() const;
 
-		/** Sets whether or not this pass renders with depth-buffer checking on or not.
-        @remarks
-        If depth-buffer checking is on, whenever a pixel is about to be written to the frame buffer
-        the depth buffer is checked to see if the pixel is in front of all other pixels written at that
-        point. If not, the pixel is not written.
-        @par
-        If depth checking is off, pixels are written no matter what has been rendered before.
-        Also see setDepthFunction for more advanced depth check configuration.
-        @see
-        setDepthFunction
-        */
-        void setDepthCheckEnabled(bool enabled);
-
-        /** Returns whether or not this pass renders with depth-buffer checking on or not.
-        @see
-        setDepthCheckEnabled
-        */
-        bool getDepthCheckEnabled(void) const;
-
-        /** Sets whether or not this pass renders with depth-buffer writing on or not.
-        @remarks
-        If depth-buffer writing is on, whenever a pixel is written to the frame buffer
-        the depth buffer is updated with the depth value of that new pixel, thus affecting future
-        rendering operations if future pixels are behind this one.
-        @par
-        If depth writing is off, pixels are written without updating the depth buffer Depth writing should
-        normally be on but can be turned off when rendering static backgrounds or when rendering a collection
-        of transparent objects at the end of a scene so that they overlap each other correctly.
-        */
-        void setDepthWriteEnabled(bool enabled);
-
-        /** Returns whether or not this pass renders with depth-buffer writing on or not.
-        @see
-        setDepthWriteEnabled
-        */
-        bool getDepthWriteEnabled(void) const;
-
-        /** Sets the function used to compare depth values when depth checking is on.
-        @remarks
-        If depth checking is enabled (see setDepthCheckEnabled) a comparison occurs between the depth
-        value of the pixel to be written and the current contents of the buffer. This comparison is
-        normally CMPF_LESS_EQUAL, i.e. the pixel is written if it is closer (or at the same distance)
-        than the current contents. If you wish you can change this comparison using this method.
-        */
-        void setDepthFunction( CompareFunction func );
-        /** Returns the function used to compare depth values when depth checking is on.
-        @see
-        setDepthFunction
-        */
-        CompareFunction getDepthFunction(void) const;
+		void setDepthStencilState(DepthStencilStatePtr depthStencilState);
+		DepthStencilStatePtr getDepthStencilState() const;
 
 		/** Sets the details of the vertex program to use.
 		*/

+ 6 - 37
CamelotRenderer/Include/CmPassRTTI.h

@@ -3,7 +3,6 @@
 #include "CmPrerequisites.h"
 #include "CmRTTIType.h"
 #include "CmPass.h"
-#include "CmRasterizerState.h"
 
 namespace CamelotEngine
 {
@@ -16,29 +15,8 @@ namespace CamelotEngine
 		RasterizerStatePtr getRasterizerState(Pass* obj) { return obj->mRasterizerState; }
 		void setRasterizerState(Pass* obj, RasterizerStatePtr val) { obj->mRasterizerState = val; } 
 
-		bool& getDepthCheck(Pass* obj) { return obj->mDepthCheck; }
-		void setDepthCheck(Pass* obj, bool& val) { obj->mDepthCheck = val; } 
-
-		bool& getDepthWrite(Pass* obj) { return obj->mDepthWrite; }
-		void setDepthWrite(Pass* obj, bool& val) { obj->mDepthWrite = val; } 
-
-		CompareFunction& getCompareFunction(Pass* obj) { return obj->mDepthFunc; }
-		void setCompareFunction(Pass* obj, CompareFunction& val) { obj->mDepthFunc = val; } 
-
-		float& getDepthBiasConstant(Pass* obj) { return obj->mDepthBiasConstant; }
-		void setDepthBiasConstant(Pass* obj, float& val) { obj->mDepthBiasConstant = val; } 
-
-		float& getDepthBiasSlopeScale(Pass* obj) { return obj->mDepthBiasSlopeScale; }
-		void setDepthBiasSlopeScale(Pass* obj, float& val) { obj->mDepthBiasSlopeScale = val; } 
-
-		float& getDepthBiasPerIteration(Pass* obj) { return obj->mDepthBiasPerIteration; }
-		void setDepthBiasPerIteration(Pass* obj, float& val) { obj->mDepthBiasPerIteration = val; } 
-
-		CullingMode& getCullMode(Pass* obj) { return obj->mCullMode; }
-		void setCullMode(Pass* obj, CullingMode& val) { obj->mCullMode = val; } 
-
-		PolygonMode& getPolygonMode(Pass* obj) { return obj->mPolygonMode; }
-		void setPolygonMode(Pass* obj, PolygonMode& val) { obj->mPolygonMode = val; } 
+		DepthStencilStatePtr getDepthStencilState(Pass* obj) { return obj->mDepthStencilState; }
+		void setDepthStencilState(Pass* obj, DepthStencilStatePtr val) { obj->mDepthStencilState = val; } 
 
 		GpuProgramHandle& getVertexProgram(Pass* obj) { return obj->mVertexProgram; }
 		void setVertexProgram(Pass* obj, GpuProgramHandle& val) { obj->mVertexProgram = val; } 
@@ -53,20 +31,11 @@ namespace CamelotEngine
 		{
 			addReflectablePtrField("mBlendState", 0, &PassRTTI::getBlendState, &PassRTTI::setBlendState);
 			addReflectablePtrField("mRasterizerState", 1, &PassRTTI::getRasterizerState, &PassRTTI::setRasterizerState);
+			addReflectablePtrField("mDepthStencilState", 2, &PassRTTI::getDepthStencilState, &PassRTTI::setDepthStencilState);
 
-			addPlainField("mDepthCheck", 2, &PassRTTI::getDepthCheck, &PassRTTI::setDepthCheck);
-			addPlainField("mDepthWrite", 3, &PassRTTI::getDepthWrite, &PassRTTI::setDepthWrite);
-			addPlainField("mDepthFunc", 4, &PassRTTI::getCompareFunction, &PassRTTI::setCompareFunction);
-			addPlainField("mDepthBiasConstant", 5, &PassRTTI::getDepthBiasConstant, &PassRTTI::setDepthBiasConstant);
-			addPlainField("mDepthBiasSlopeScale", 6, &PassRTTI::getDepthBiasSlopeScale, &PassRTTI::setDepthBiasSlopeScale);
-			addPlainField("mDepthBiasPerIteration", 7, &PassRTTI::getDepthBiasPerIteration, &PassRTTI::setDepthBiasPerIteration);
-
-			addPlainField("mCullMode", 8, &PassRTTI::getCullMode, &PassRTTI::setCullMode);
-			addPlainField("mPolygonMode", 9, &PassRTTI::getPolygonMode, &PassRTTI::setPolygonMode);
-
-			addReflectableField("mVertexProgram", 10, &PassRTTI::getVertexProgram, &PassRTTI::setVertexProgram);
-			addReflectableField("mFragmentProgram", 11, &PassRTTI::getFragmentProgram, &PassRTTI::setFragmentProgram);
-			addReflectableField("mGeometryProgram", 12, &PassRTTI::getGeometryProgram, &PassRTTI::setGeometryProgram);
+			addReflectableField("mVertexProgram", 3, &PassRTTI::getVertexProgram, &PassRTTI::setVertexProgram);
+			addReflectableField("mFragmentProgram", 4, &PassRTTI::getFragmentProgram, &PassRTTI::setFragmentProgram);
+			addReflectableField("mGeometryProgram", 5, &PassRTTI::getGeometryProgram, &PassRTTI::setGeometryProgram);
 		}
 
 		virtual const String& getRTTIName()

+ 3 - 2
CamelotRenderer/Include/CmPrerequisites.h

@@ -130,7 +130,7 @@ namespace CamelotEngine {
 	class MeshRTTI;
 	// Desc structs
 	struct SAMPLER_STATE_DESC;
-	struct DEPTH_STENCIL_DESC;
+	struct DEPTH_STENCIL_STATE_DESC;
 	struct RASTERIZER_STATE_DESC;
 	struct BLEND_STATE_DESC;
 	struct RENDER_TARGET_BLEND_STATE_DESC;
@@ -195,7 +195,8 @@ namespace CamelotEngine
 		TID_SamplerState = 1021,
 		TID_SamplerStateParamKVP = 1022,
 		TID_BlendState = 1023,
-		TID_RasterizerState = 1024
+		TID_RasterizerState = 1024,
+		TID_DepthStencilState = 1025
 	};
 }
 

+ 1 - 1
CamelotRenderer/Include/CmRenderStateManager.h

@@ -16,7 +16,7 @@ namespace CamelotEngine
 		/**
 		 * @brief	Creates and initializes a new DepthStencilState.
 		 */
-		virtual DepthStencilStatePtr createDepthStencilState(const DEPTH_STENCIL_DESC& desc) const;
+		virtual DepthStencilStatePtr createDepthStencilState(const DEPTH_STENCIL_STATE_DESC& desc) const;
 
 		/**
 		 * @brief	Creates and initializes a new RasterizerState.

+ 24 - 86
CamelotRenderer/Include/CmRenderSystem.h

@@ -373,6 +373,29 @@ namespace CamelotEngine
 		 */
 		virtual void setRasterizerState(const RasterizerState& rasterizerState) = 0;
 
+		/**
+		 * @brief	Sets a state that controls depth & stencil buffer options.
+		 * @see		DepthStencilState
+		 */
+		virtual void setDepthStencilState(const DepthStencilState& depthStencilState) = 0;
+
+		/**
+		 * @brief	Sets a reference values used for stencil buffer comparisons. 
+		 * 			Actual comparison function and stencil operations are set by setting the StencilState.
+		 * 			
+		 * @remarks
+		 *		 The stencil buffer is used to mask out pixels in the render target, allowing
+		 *		 you to do effects like mirrors, cut-outs, stencil shadows and more. Each of
+		 *		 your batches of rendering is likely to ignore the stencil buffer,
+		 *		 update it with new values, or apply it to mask the output of the render.
+		 *		 The stencil test is:<PRE>
+		 *		 (Reference Value & Mask) CompareFunction (Stencil Buffer Value & Mask)</PRE>
+		 *		 The result of this will cause one of 3 actions depending on whether the test fails,
+		 *		 succeeds but with the depth buffer check still failing, or succeeds with the
+		 *		 depth buffer check passing too.
+		 */
+		virtual void setStencilRefValue(UINT32 refValue) = 0;
+
 		/**
 		Sets the texture to bind to a given texture unit.
 
@@ -408,92 +431,6 @@ namespace CamelotEngine
 		/** Get the current active viewport for rendering. */
 		virtual Viewport getViewport(void);
 
-		/** Sets the mode of operation for depth buffer tests from this point onwards.
-		Sometimes you may wish to alter the behaviour of the depth buffer to achieve
-		special effects. Because it's unlikely that you'll set these options for an entire frame,
-		but rather use them to tweak settings between rendering objects, this is an internal
-		method (indicated by the '_' prefix) which will be used by a SceneManager implementation
-		rather than directly from the client application.
-		If this method is never called the settings are automatically the same as the default parameters.
-		@param depthTest If true, the depth buffer is tested for each pixel and the frame buffer is only updated
-		if the depth function test succeeds. If false, no test is performed and pixels are always written.
-		@param depthWrite If true, the depth buffer is updated with the depth of the new pixel if the depth test succeeds.
-		If false, the depth buffer is left unchanged even if a new pixel is written.
-		@param depthFunction Sets the function required for the depth test.
-		*/
-		virtual void setDepthBufferParams(bool depthTest = true, bool depthWrite = true, CompareFunction depthFunction = CMPF_LESS_EQUAL) = 0;
-
-		/** Sets whether or not the depth buffer check is performed before a pixel write.
-		@param enabled If true, the depth buffer is tested for each pixel and the frame buffer is only updated
-		if the depth function test succeeds. If false, no test is performed and pixels are always written.
-		*/
-		virtual void setDepthBufferCheckEnabled(bool enabled = true) = 0;
-
-		/** Sets whether or not the depth buffer is updated after a pixel write.
-		@param enabled If true, the depth buffer is updated with the depth of the new pixel if the depth test succeeds.
-		If false, the depth buffer is left unchanged even if a new pixel is written.
-		*/
-		virtual void setDepthBufferWriteEnabled(bool enabled = true) = 0;
-
-		/** Sets the comparison function for the depth buffer check.
-		Advanced use only - allows you to choose the function applied to compare the depth values of
-		new and existing pixels in the depth buffer. Only an issue if the deoth buffer check is enabled
-		(see _setDepthBufferCheckEnabled)
-		@param  func The comparison between the new depth and the existing depth which must return true
-		for the new pixel to be written.
-		*/
-		virtual void setDepthBufferFunction(CompareFunction func = CMPF_LESS_EQUAL) = 0;
-
-		/** Turns stencil buffer checking on or off. 
-		@remarks
-		Stencilling (masking off areas of the rendering target based on the stencil 
-		buffer) can be turned on or off using this method. By default, stencilling is
-		disabled.
-		*/
-		virtual void setStencilCheckEnabled(bool enabled) = 0;
-
-		/** This method allows you to set all the stencil buffer parameters in one call.
-		@remarks
-		The stencil buffer is used to mask out pixels in the render target, allowing
-		you to do effects like mirrors, cut-outs, stencil shadows and more. Each of
-		your batches of rendering is likely to ignore the stencil buffer, 
-		update it with new values, or apply it to mask the output of the render.
-		The stencil test is:<PRE>
-		(Reference Value & Mask) CompareFunction (Stencil Buffer Value & Mask)</PRE>
-		The result of this will cause one of 3 actions depending on whether the test fails,
-		succeeds but with the depth buffer check still failing, or succeeds with the
-		depth buffer check passing too.
-		@par
-		Unlike other render states, stencilling is left for the application to turn
-		on and off when it requires. This is because you are likely to want to change
-		parameters between batches of arbitrary objects and control the ordering yourself.
-		In order to batch things this way, you'll want to use OGRE's separate render queue
-		groups (see RenderQueue) and register a RenderQueueListener to get notifications
-		between batches.
-		@par
-		There are individual state change methods for each of the parameters set using 
-		this method. 
-		Note that the default values in this method represent the defaults at system 
-		start up too.
-		@param func The comparison function applied.
-		@param refValue The reference value used in the comparison
-		@param mask The bitmask applied to both the stencil value and the reference value 
-		before comparison
-		@param stencilFailOp The action to perform when the stencil check fails
-		@param depthFailOp The action to perform when the stencil check passes, but the
-		depth buffer check still fails
-		@param passOp The action to take when both the stencil and depth check pass.
-		@param twoSidedOperation If set to true, then if you render both back and front faces 
-		(you'll have to turn off culling) then these parameters will apply for front faces, 
-		and the inverse of them will happen for back faces (keep remains the same).
-		*/
-		virtual void setStencilBufferParams(CompareFunction func = CMPF_ALWAYS_PASS, 
-			UINT32 refValue = 0, UINT32 mask = 0xFFFFFFFF, 
-			StencilOperation stencilFailOp = SOP_KEEP, 
-			StencilOperation depthFailOp = SOP_KEEP,
-			StencilOperation passOp = SOP_KEEP, 
-			bool twoSidedOperation = false) = 0;
-
 		/** Sets the current vertex declaration, ie the source of vertex data. */
 		virtual void setVertexDeclaration(VertexDeclarationPtr decl) = 0;
 		/** Sets the current vertex buffer binding state. */
@@ -647,6 +584,7 @@ namespace CamelotEngine
 		@see Renderable::getUseIdentityView, Renderable::getUseIdentityProjection
 		*/
 		virtual float getMaximumDepthInputValue(void) = 0;
+
 		/************************************************************************/
 		/* 						INTERNAL DATA & METHODS                      	*/
 		/************************************************************************/

+ 11 - 31
CamelotRenderer/Source/CmDeferredRenderContext.cpp

@@ -4,6 +4,7 @@
 #include "CmRenderSystem.h"
 #include "CmBlendState.h"
 #include "CmRasterizerState.h"
+#include "CmDepthStencilState.h"
 
 namespace CamelotEngine
 {
@@ -45,6 +46,16 @@ namespace CamelotEngine
 		mCommandQueue->queue(boost::bind(&RenderSystem::setRasterizerState, mRenderSystem, rasterizerState));
 	}
 
+	void DeferredRenderContext::setDepthStencilState(const DepthStencilState& depthStencilState)
+	{
+		mCommandQueue->queue(boost::bind(&RenderSystem::setDepthStencilState, mRenderSystem, depthStencilState));
+	}
+
+	void DeferredRenderContext::setStencilRefValue(UINT32 refValue)
+	{
+		mCommandQueue->queue(boost::bind(&RenderSystem::setStencilRefValue, mRenderSystem, refValue));
+	}
+
 	void DeferredRenderContext::setTexture(UINT16 unit, bool enabled, const TexturePtr& texPtr)
 	{
 		mCommandQueue->queue(boost::bind(&RenderSystem::setTexture, mRenderSystem, unit, enabled, texPtr));
@@ -76,37 +87,6 @@ namespace CamelotEngine
 		mCommandQueue->queue(boost::bind(&RenderSystem::setWaitForVerticalBlank, mRenderSystem, enabled));
 	}
 
-	void DeferredRenderContext::setDepthBufferParams(bool depthTest, bool depthWrite, CompareFunction depthFunction)
-	{
-		mCommandQueue->queue(boost::bind(&RenderSystem::setDepthBufferParams, mRenderSystem, depthTest, depthWrite, depthFunction));
-	}
-
-	void DeferredRenderContext::setDepthBufferCheckEnabled(bool enabled)
-	{
-		mCommandQueue->queue(boost::bind(&RenderSystem::setDepthBufferCheckEnabled, mRenderSystem, enabled));
-	}
-
-	void DeferredRenderContext::setDepthBufferWriteEnabled(bool enabled)
-	{
-		mCommandQueue->queue(boost::bind(&RenderSystem::setDepthBufferWriteEnabled, mRenderSystem, enabled));
-	}
-
-	void DeferredRenderContext::setDepthBufferFunction(CompareFunction func)
-	{
-		mCommandQueue->queue(boost::bind(&RenderSystem::setDepthBufferFunction, mRenderSystem, func));
-	}
-
-	void DeferredRenderContext::setStencilCheckEnabled(bool enabled)
-	{
-		mCommandQueue->queue(boost::bind(&RenderSystem::setStencilCheckEnabled, mRenderSystem, enabled));
-	}
-
-	void DeferredRenderContext::setStencilBufferParams(CompareFunction func, UINT32 refValue, UINT32 mask, StencilOperation stencilFailOp, 
-		StencilOperation depthFailOp, StencilOperation passOp, bool twoSidedOperation)
-	{
-		mCommandQueue->queue(boost::bind(&RenderSystem::setStencilBufferParams, mRenderSystem, func, refValue, mask, stencilFailOp, depthFailOp, passOp, twoSidedOperation));
-	}
-
 	void DeferredRenderContext::addClipPlane(const Plane &p)
 	{
 		mCommandQueue->queue(boost::bind(&RenderSystem::addClipPlane, mRenderSystem, p));

+ 27 - 5
CamelotRenderer/Source/CmDepthStencilState.cpp

@@ -1,23 +1,45 @@
 #include "CmDepthStencilState.h"
 #include "CmRenderStateManager.h"
+#include "CmDepthStencilStateRTTI.h"
 #include "CmException.h"
 
 namespace CamelotEngine
 {
-	void DepthStencilState::initialize(const DEPTH_STENCIL_DESC& desc)
+	void DepthStencilState::initialize(const DEPTH_STENCIL_STATE_DESC& desc)
 	{
 		mData = desc;
-		mStencilRefValue = 0;
 	}
 
-	DepthStencilState::DepthStencilState()
-		:mStencilRefValue(0)
+	const DepthStencilState& DepthStencilState::getDefault()
 	{
+		static DepthStencilState depthStencilState;
+		static bool initialized = false;
 
+		if(!initialized)
+		{
+			depthStencilState.initialize(DEPTH_STENCIL_STATE_DESC());
+			initialized = true;
+		}
+
+		return depthStencilState;
 	}
 
-	DepthStencilStatePtr DepthStencilState::create(const DEPTH_STENCIL_DESC& desc)
+	DepthStencilStatePtr DepthStencilState::create(const DEPTH_STENCIL_STATE_DESC& desc)
 	{
 		return RenderStateManager::instance().createDepthStencilState(desc);
 	}
+
+	/************************************************************************/
+	/* 								RTTI		                     		*/
+	/************************************************************************/
+
+	RTTITypeBase* DepthStencilState::getRTTIStatic()
+	{
+		return DepthStencilStateRTTI::instance();
+	}
+
+	RTTITypeBase* DepthStencilState::getRTTI() const
+	{
+		return DepthStencilState::getRTTIStatic();
+	}
 }

+ 16 - 52
CamelotRenderer/Source/CmPass.cpp

@@ -1,24 +1,15 @@
 #include "CmPass.h"
+#include "CmRasterizerState.h"
+#include "CmBlendState.h"
+#include "CmDepthStencilState.h"
 #include "CmPassRTTI.h"
 #include "CmException.h"
-#include "CmBlendState.h"
 
 namespace CamelotEngine
 {
     //-----------------------------------------------------------------------------
 	Pass::Pass()
-		: mDepthCheck(true)
-		, mDepthWrite(true)
-		, mDepthFunc(CMPF_LESS_EQUAL)
-		, mDepthBiasConstant(0.0f)
-		, mDepthBiasSlopeScale(0.0f)
-		, mDepthBiasPerIteration(0.0f)
-		, mCullMode(CULL_CLOCKWISE)
-		, mPolygonMode(PM_SOLID)
-    {
-
-   }
-
+    { }
     //-----------------------------------------------------------------------------
 	Pass::Pass(const Pass& oth)
     {
@@ -34,15 +25,8 @@ namespace CamelotEngine
     {
 	    // Default blending (overwrite)
 	    mBlendState = oth.mBlendState;
-
-	    mDepthCheck = oth.mDepthCheck;
-	    mDepthWrite = oth.mDepthWrite;
-	    mDepthFunc = oth.mDepthFunc;
-        mDepthBiasConstant = oth.mDepthBiasConstant;
-		mDepthBiasSlopeScale = oth.mDepthBiasSlopeScale;
-		mDepthBiasPerIteration = oth.mDepthBiasPerIteration;
-	    mCullMode = oth.mCullMode;
-		mPolygonMode = oth.mPolygonMode;
+		mRasterizerState = oth.mRasterizerState;
+		mDepthStencilState = oth.mDepthStencilState;
 
 		mVertexProgram = oth.mVertexProgram;
 		mFragmentProgram = oth.mFragmentProgram;
@@ -93,36 +77,16 @@ namespace CamelotEngine
 	{
 		return mRasterizerState;
 	}
-    //-----------------------------------------------------------------------
-    void Pass::setDepthCheckEnabled(bool enabled)
-    {
-	    mDepthCheck = enabled;
-    }
-    //-----------------------------------------------------------------------
-    bool Pass::getDepthCheckEnabled(void) const
-    {
-	    return mDepthCheck;
-    }
-    //-----------------------------------------------------------------------
-    void Pass::setDepthWriteEnabled(bool enabled)
-    {
-	    mDepthWrite = enabled;
-    }
-    //-----------------------------------------------------------------------
-    bool Pass::getDepthWriteEnabled(void) const
-    {
-	    return mDepthWrite;
-    }
-    //-----------------------------------------------------------------------
-    void Pass::setDepthFunction( CompareFunction func)
-    {
-	    mDepthFunc = func;
-    }
-    //-----------------------------------------------------------------------
-    CompareFunction Pass::getDepthFunction(void) const
-    {
-	    return mDepthFunc;
-    }
+	//-----------------------------------------------------------------------
+	void Pass::setDepthStencilState(DepthStencilStatePtr depthStencilState)
+	{
+		mDepthStencilState = depthStencilState;
+	}
+	//-----------------------------------------------------------------------
+	DepthStencilStatePtr Pass::getDepthStencilState() const
+	{
+		return mDepthStencilState;
+	}
     //-----------------------------------------------------------------------
 	void Pass::setVertexProgram(GpuProgramHandle gpuProgram)
 	{

+ 1 - 1
CamelotRenderer/Source/CmRenderStateManager.cpp

@@ -14,7 +14,7 @@ namespace CamelotEngine
 		return samplerState;
 	}
 
-	DepthStencilStatePtr RenderStateManager::createDepthStencilState(const DEPTH_STENCIL_DESC& desc) const
+	DepthStencilStatePtr RenderStateManager::createDepthStencilState(const DEPTH_STENCIL_STATE_DESC& desc) const
 	{
 		DepthStencilStatePtr depthStencilState = DepthStencilStatePtr(new DepthStencilState());
 		depthStencilState->initialize(desc);

+ 7 - 7
CamelotRenderer/TODO.txt

@@ -17,17 +17,17 @@
 
 
 /////
+Check out how to deal with clip planes so that both DX9, DX11 and GL support them
+waitForVsync can probably be moved somewhere other than being directly in RenderSystem? (where is it in DX11?)
 
-RasterizerState TODO: 
- Add setRasterizerState to RenderSystems
- Add setRasterizerState to Pass and it's RTTI
- Make RasterizerState IReflectable
- Add support for multisampleEnable & antialiasedLineEnable to DX9 if possible?
- Add depth slope & depth clamp
+Rasterizer state:
+ D3DRS_MULTISAMPLEANTIALIAS
+ - but first check if available using D3DPRASTERCAPS_MULTISAMPLE_TOGGLE
+ - see if opengl has something similar
+ - see if either dx9 or opengl have something similar to DX11 antialias line
 
 Move createRenderWindow outside of RenderSystem
 RenderSystem::setRenderTarget needs to accept multiple targets
-First port (and test!) existing render systems so it is capable of dealing with DX11 stuff(samplerState, depthStencilState, rasterizerState objects primarily. Also split pass into Texture/sampler) 
 
 Make CommandQueue not use mutexes and use atomics instead??
 Make sure that the simulation can't run faster then the render thread! (Block the main thread until previous render finishes)

Niektóre pliki nie zostały wyświetlone z powodu dużej ilości zmienionych plików