Browse Source

Add DeferredRenderer and a bunch of deferred render commands

Marko Pintera 13 năm trước cách đây
mục cha
commit
f67e37bb8c

+ 5 - 5
CamelotD3D9Renderer/Include/CmD3D9RenderSystem.h

@@ -206,7 +206,7 @@ namespace CamelotEngine
 		void reinitialise();
 		void shutdown();
 		void destroyRenderTarget(const String& name);
-		VertexElementType getColourVertexElementType() const;
+		VertexElementType getColorVertexElementType() const;
 		void setStencilCheckEnabled(bool enabled);
         void setStencilBufferParams(CompareFunction func = CMPF_ALWAYS_PASS, 
             UINT32 refValue = 0, UINT32 mask = 0xFFFFFFFF, 
@@ -222,7 +222,7 @@ namespace CamelotEngine
 		void setVertexTexture(size_t unit, const TexturePtr& tex);
 		void disableTextureUnit(size_t texUnit);
         void setTextureAddressingMode(size_t stage, const SamplerState::UVWAddressingMode& uvw);
-        void setTextureBorderColour(size_t stage, const Color& colour);
+        void setTextureBorderColor(size_t stage, const Color& colour);
 		void setTextureMipmapBias(size_t unit, float bias);
 		void setSceneBlending( SceneBlendFactor sourceFactor, SceneBlendFactor destFactor, SceneBlendOperation op );
 		void setSeparateSceneBlending( SceneBlendFactor sourceFactor, SceneBlendFactor destFactor, SceneBlendFactor sourceFactorAlpha, SceneBlendFactor destFactorAlpha, SceneBlendOperation op, SceneBlendOperation alphaOp );
@@ -233,14 +233,14 @@ namespace CamelotEngine
 		void setCullingMode( CullingMode mode );
 		void setDepthBufferParams( bool depthTest = true, bool depthWrite = true, CompareFunction depthFunction = CMPF_LESS_EQUAL );
 		void setDepthBufferCheckEnabled( bool enabled = true );
-		void setColourBufferWriteEnabled(bool red, bool green, bool blue, bool alpha);
+		void setColorBufferWriteEnabled(bool red, bool green, bool blue, bool alpha);
 		void setDepthBufferWriteEnabled(bool enabled = true);
 		void setDepthBufferFunction( CompareFunction func = CMPF_LESS_EQUAL );
 		void setDepthBias(float constantBias, float slopeScaleBias);
 		void _convertProjectionMatrix(const Matrix4& matrix, Matrix4& dest, bool forGpuProgram = false);
 		void setPolygonMode(PolygonMode level);
-        void setTextureUnitFiltering(size_t unit, FilterType ftype, FilterOptions filter);
-		void setTextureLayerAnisotropy(size_t unit, unsigned int maxAnisotropy);
+        void setTextureFiltering(size_t unit, FilterType ftype, FilterOptions filter);
+		void setTextureAnisotropy(size_t unit, unsigned int maxAnisotropy);
 		void setVertexDeclaration(VertexDeclarationPtr decl);
 		void setVertexBufferBinding(VertexBufferBinding* binding);
         void render(const RenderOperation& op);

+ 5 - 5
CamelotD3D9Renderer/Source/CmD3D9RenderSystem.cpp

@@ -1440,7 +1440,7 @@ namespace CamelotEngine
 		return errMsg;
 	}
 	//---------------------------------------------------------------------
-	VertexElementType D3D9RenderSystem::getColourVertexElementType() const
+	VertexElementType D3D9RenderSystem::getColorVertexElementType() const
 	{
 		return VET_COLOUR_ARGB;
 	}
@@ -1624,7 +1624,7 @@ namespace CamelotEngine
 			CM_EXCEPT(RenderingAPIException, "Failed to set texture addressing mode for W");
 	}
 	//-----------------------------------------------------------------------------
-	void D3D9RenderSystem::setTextureBorderColour(size_t stage,
+	void D3D9RenderSystem::setTextureBorderColor(size_t stage,
 		const Color& colour)
 	{
 		HRESULT hr;
@@ -1825,7 +1825,7 @@ namespace CamelotEngine
 
 	}
 	//---------------------------------------------------------------------
-	void D3D9RenderSystem::setColourBufferWriteEnabled(bool red, bool green, 
+	void D3D9RenderSystem::setColorBufferWriteEnabled(bool red, bool green, 
 		bool blue, bool alpha)
 	{
 		DWORD val = 0;
@@ -1933,7 +1933,7 @@ namespace CamelotEngine
 			CM_EXCEPT(RenderingAPIException, "Error setting stencil pass operation.");
 	}
 	//---------------------------------------------------------------------
-	void D3D9RenderSystem::setTextureUnitFiltering(size_t unit, FilterType ftype, 
+	void D3D9RenderSystem::setTextureFiltering(size_t unit, FilterType ftype, 
 		FilterOptions filter)
 	{
 		HRESULT hr;
@@ -1951,7 +1951,7 @@ namespace CamelotEngine
 		return oldVal;
 	}
 	//---------------------------------------------------------------------
-	void D3D9RenderSystem::setTextureLayerAnisotropy(size_t unit, unsigned int maxAnisotropy)
+	void D3D9RenderSystem::setTextureAnisotropy(size_t unit, unsigned int maxAnisotropy)
 	{
 		if (static_cast<DWORD>(maxAnisotropy) > mDeviceManager->getActiveDevice()->getD3D9DeviceCaps().MaxAnisotropy)
 			maxAnisotropy = mDeviceManager->getActiveDevice()->getD3D9DeviceCaps().MaxAnisotropy;

+ 1 - 8
CamelotForwardRenderer/Source/CmForwardRenderer.cpp

@@ -7,15 +7,11 @@
 #include "CmMaterial.h"
 #include "CmMesh.h"
 #include "CmPass.h"
-#include "CmRenderCommandBuffer.h"
 
 namespace CamelotEngine
 {
 	ForwardRenderer::ForwardRenderer()
 	{
-		//RenderSystem* renderSystem = RenderSystemManager::getActive();
-
-		//mCommandBuffer = renderSystem->createCommandBuffer();
 	}
 
 	ForwardRenderer::~ForwardRenderer()
@@ -84,9 +80,6 @@ namespace CamelotEngine
 				setPassParameters(material->getPassParameters(i));
 
 				renderSystem->render(mesh->getRenderOperation());
-
-				//mCommandBuffer->applyPass(material->getPass(i), material->getPassParameters(i));
-				//mCommandBuffer->render(mesh->getRenderOperation());
 			}
 		}
 
@@ -195,7 +188,7 @@ namespace CamelotEngine
 		// Set colour write mode
 		// Right now we only use on/off, not per-channel
 		bool colWrite = pass->getColourWriteEnabled();
-		renderSystem->setColourBufferWriteEnabled(colWrite, colWrite, colWrite, colWrite);
+		renderSystem->setColorBufferWriteEnabled(colWrite, colWrite, colWrite, colWrite);
 
 		// Culling mode
 		renderSystem->setCullingMode(pass->getCullingMode());

+ 5 - 5
CamelotGLRenderer/Include/CmGLRenderSystem.h

@@ -192,7 +192,7 @@ namespace CamelotEngine {
         /** See
           RenderSystem
          */
-        VertexElementType getColourVertexElementType(void) const;
+        VertexElementType getColorVertexElementType(void) const;
 
         // -----------------------------
         // Low-level overridden members
@@ -213,7 +213,7 @@ namespace CamelotEngine {
         /** See
           RenderSystem
          */
-        void setTextureBorderColour(size_t stage, const Color& colour);
+        void setTextureBorderColor(size_t stage, const Color& colour);
 		/** See
 		  RenderSystem
 		 */
@@ -277,7 +277,7 @@ namespace CamelotEngine {
         /** See
           RenderSystem
          */
-        void setColourBufferWriteEnabled(bool red, bool green, bool blue, bool alpha);
+        void setColorBufferWriteEnabled(bool red, bool green, bool blue, bool alpha);
         /** See
           RenderSystem
          */
@@ -311,11 +311,11 @@ namespace CamelotEngine {
         /** See
           RenderSystem
          */
-        void setTextureUnitFiltering(size_t unit, FilterType ftype, FilterOptions filter);
+        void setTextureFiltering(size_t unit, FilterType ftype, FilterOptions filter);
         /** See
           RenderSystem
          */
-		void setTextureLayerAnisotropy(size_t unit, unsigned int maxAnisotropy);
+		void setTextureAnisotropy(size_t unit, unsigned int maxAnisotropy);
         /** See
           RenderSystem
          */

+ 5 - 5
CamelotGLRenderer/Source/CmGLRenderSystem.cpp

@@ -1218,7 +1218,7 @@ namespace CamelotEngine {
 		activateGLTextureUnit(0);
 	}
 	//-----------------------------------------------------------------------------
-	void GLRenderSystem::setTextureBorderColour(size_t stage, const Color& colour)
+	void GLRenderSystem::setTextureBorderColor(size_t stage, const Color& colour)
 	{
 		GLfloat border[4] = { colour.r, colour.g, colour.b, colour.a };
 		if (activateGLTextureUnit(stage))
@@ -1574,7 +1574,7 @@ namespace CamelotEngine {
 		}
 	}
 	//-----------------------------------------------------------------------------
-	void GLRenderSystem::setColourBufferWriteEnabled(bool red, bool green, bool blue, bool alpha)
+	void GLRenderSystem::setColorBufferWriteEnabled(bool red, bool green, bool blue, bool alpha)
 	{
 		glColorMask(red, green, blue, alpha);
 		// record this
@@ -1590,7 +1590,7 @@ namespace CamelotEngine {
 		return (errString != 0) ? String((const char*) errString) : StringUtil::BLANK;
     }
 
-	VertexElementType GLRenderSystem::getColourVertexElementType(void) const
+	VertexElementType GLRenderSystem::getColorVertexElementType(void) const
 	{
 		return VET_COLOUR_ABGR;
 	}
@@ -1796,7 +1796,7 @@ namespace CamelotEngine {
 
 	}
 	//---------------------------------------------------------------------
-	void GLRenderSystem::setTextureUnitFiltering(size_t unit, 
+	void GLRenderSystem::setTextureFiltering(size_t unit, 
 		FilterType ftype, FilterOptions fo)
 	{
 		if (!activateGLTextureUnit(unit))
@@ -1851,7 +1851,7 @@ namespace CamelotEngine {
 		return curAniso ? curAniso : 1;
 	}
 	//---------------------------------------------------------------------
-	void GLRenderSystem::setTextureLayerAnisotropy(size_t unit, unsigned int maxAnisotropy)
+	void GLRenderSystem::setTextureAnisotropy(size_t unit, unsigned int maxAnisotropy)
 	{
 		if (!mCurrentCapabilities->hasCapability(RSC_ANISOTROPY))
 			return;

+ 1 - 3
CamelotRenderer/CamelotRenderer.vcxproj

@@ -97,13 +97,11 @@
     <ClInclude Include="Include\CmApplication.h" />
     <ClInclude Include="Include\CmDeferredGpuCommands.h" />
     <ClInclude Include="Include\CmDeferredRenderSystem.h" />
-    <ClInclude Include="Include\CmRenderCommand.h" />
     <ClInclude Include="Include\CmCamera.h" />
     <ClInclude Include="Include\CmCameraRTTI.h" />
     <ClInclude Include="Include\CmCgProgram.h" />
     <ClInclude Include="Include\CmCgProgramFactory.h" />
     <ClInclude Include="Include\CmCgProgramRTTI.h" />
-    <ClInclude Include="Include\CmRenderCommandBuffer.h" />
     <ClInclude Include="Include\CmCommon.h" />
     <ClInclude Include="Include\CmComponentRTTI.h" />
     <ClInclude Include="Include\CmConfigOptionMap.h" />
@@ -173,13 +171,13 @@
     <ClInclude Include="Source\CmMeshRTTI.h" />
   </ItemGroup>
   <ItemGroup>
-    <ClCompile Include="Include\CmRenderCommandBuffer.cpp" />
     <ClCompile Include="Source\CamelotRenderer.cpp" />
     <ClCompile Include="Source\CmApplication.cpp" />
     <ClCompile Include="Source\CmCamera.cpp" />
     <ClCompile Include="Source\CmCgProgram.cpp" />
     <ClCompile Include="Source\CmCgProgramFactory.cpp" />
     <ClCompile Include="Source\CmDefaultHardwareBufferManager.cpp" />
+    <ClCompile Include="Source\CmDeferredGpuCommands.cpp" />
     <ClCompile Include="Source\CmGpuProgram.cpp" />
     <ClCompile Include="Source\CmGpuProgramManager.cpp" />
     <ClCompile Include="Source\CmGpuProgramParams.cpp" />

+ 2 - 8
CamelotRenderer/CamelotRenderer.vcxproj.filters

@@ -307,12 +307,6 @@
     <ClInclude Include="Include\CmRenderOperation.h">
       <Filter>Header Files\RenderSystem</Filter>
     </ClInclude>
-    <ClInclude Include="Include\CmRenderCommand.h">
-      <Filter>Header Files\RenderSystem</Filter>
-    </ClInclude>
-    <ClInclude Include="Include\CmRenderCommandBuffer.h">
-      <Filter>Header Files\RenderSystem</Filter>
-    </ClInclude>
     <ClInclude Include="Include\CmDeferredRenderSystem.h">
       <Filter>Header Files\RenderSystem</Filter>
     </ClInclude>
@@ -462,10 +456,10 @@
     <ClCompile Include="Source\CmSamplerState.cpp">
       <Filter>Source Files\RenderSystem</Filter>
     </ClCompile>
-    <ClCompile Include="Include\CmRenderCommandBuffer.cpp">
+    <ClCompile Include="Source\CmDeferredRenderSystem.cpp">
       <Filter>Source Files\RenderSystem</Filter>
     </ClCompile>
-    <ClCompile Include="Source\CmDeferredRenderSystem.cpp">
+    <ClCompile Include="Source\CmDeferredGpuCommands.cpp">
       <Filter>Source Files\RenderSystem</Filter>
     </ClCompile>
   </ItemGroup>

+ 412 - 7
CamelotRenderer/Include/CmDeferredGpuCommands.h

@@ -1,20 +1,425 @@
 #pragma once
 
 #include "CmPrerequisites.h"
+#include "CmRenderSystem.h"
 
 namespace CamelotEngine
 {
-	enum DeferredGpuCommandType
+	class CM_EXPORT DeferredGpuCommand
 	{
-		Draw,
-		BeginFrame,
-		EndFrame,
-		Present
+	public:
+		DeferredGpuCommand();
+
+		virtual void submitCommand(RenderSystem* rs) = 0;
 	};
 
-	class CM_EXPORT DeferredGpuCommand
+	class CM_EXPORT DfrdRenderGpuCommand : public DeferredGpuCommand
+	{
+	public:
+		DfrdRenderGpuCommand(RenderOperation& _renderOp);
+
+		RenderOperation renderOp;
+
+		virtual void submitCommand(RenderSystem* rs);
+	};
+
+	class CM_EXPORT DfrdBindGpuProgramCommand : public DeferredGpuCommand
+	{
+	public:
+		DfrdBindGpuProgramCommand(GpuProgramPtr _gpuProgram);
+
+		GpuProgramPtr gpuProgram;
+
+		virtual void submitCommand(RenderSystem* rs);
+	};
+
+	class CM_EXPORT DfrdBindGpuParamsCommand : public DeferredGpuCommand
+	{
+	public:
+		DfrdBindGpuParamsCommand(GpuProgramType _type, GpuProgramParametersPtr& _progParams);
+
+		GpuProgramType type;
+		GpuProgramParametersPtr progParams;
+
+		virtual void submitCommand(RenderSystem* rs);
+	};
+
+	class CM_EXPORT DfrdInvVertWindingCommand : public DeferredGpuCommand
+	{
+	public:
+		DfrdInvVertWindingCommand(bool _invert);
+
+		bool invert;
+
+		virtual void submitCommand(RenderSystem* rs);
+	};
+
+	class CM_EXPORT DfrdScissorTestCommand : public DeferredGpuCommand
+	{
+	public:
+		DfrdScissorTestCommand(bool _enabled, size_t _left, size_t _top, size_t _right, size_t _bottom);
+
+		bool enabled;
+		size_t left;
+		size_t top;
+		size_t right;
+		size_t bottom;
+
+		virtual void submitCommand(RenderSystem* rs);
+	};
+
+	class CM_EXPORT DfrdStencilBufferParamsCommand : public DeferredGpuCommand
+	{
+	public:
+		DfrdStencilBufferParamsCommand(CompareFunction _func, UINT32 _refValue, UINT32 _mask, 
+			StencilOperation _stencilFailOp, StencilOperation _depthFailOp, 
+			StencilOperation _passOp, bool _twoSidedOperation);
+
+		CompareFunction func;
+		UINT32 refValue;
+		UINT32 mask; 
+		StencilOperation stencilFailOp;
+		StencilOperation depthFailOp;
+		StencilOperation passOp;
+		bool twoSidedOperation;
+
+		virtual void submitCommand(RenderSystem* rs);
+	};
+
+	// TODO !
+	class CM_EXPORT DfrdVertexDeclCommand : public DeferredGpuCommand
+	{
+	public:
+		DfrdVertexDeclCommand();
+
+		virtual void submitCommand(RenderSystem* rs);
+	};
+
+	// TODO !
+	class CM_EXPORT DfrdVertBufferBindCommand : public DeferredGpuCommand
+	{
+	public:
+		DfrdVertBufferBindCommand();
+
+		virtual void submitCommand(RenderSystem* rs);
+	};
+
+	class CM_EXPORT DfrdPolygonModeCommand : public DeferredGpuCommand
+	{
+	public:
+		DfrdPolygonModeCommand(PolygonMode _level);
+
+		PolygonMode mode;
+
+		virtual void submitCommand(RenderSystem* rs);
+	};
+
+	class CM_EXPORT DfrdStencilCheckCommand : public DeferredGpuCommand
+	{
+	public:
+		DfrdStencilCheckCommand(bool _enabled);
+
+		bool enabled;
+
+		virtual void submitCommand(RenderSystem* rs);
+	};
+
+	class CM_EXPORT DfrdWaitForVerticalBlankCommand : public DeferredGpuCommand
+	{
+	public:
+		DfrdWaitForVerticalBlankCommand(bool _enabled);
+
+		bool enabled;
+
+		virtual void submitCommand(RenderSystem* rs);
+	};
+
+	class CM_EXPORT DfrdTextureUnitSettingsCommand : public DeferredGpuCommand
+	{
+	public:
+		DfrdTextureUnitSettingsCommand(size_t _texUnit, const TexturePtr& _tex, 
+			const SamplerState& _samplerState);
+
+		size_t texUnit;
+		TexturePtr tex;
+		SamplerState samplerState;
+
+		virtual void submitCommand(RenderSystem* rs);
+	};
+
+	class CM_EXPORT DfrdPointParamsCommand : public DeferredGpuCommand
+	{
+	public:
+		DfrdPointParamsCommand(float _size, bool _attenuationEnabled, 
+			float _constant, float _linear, float _quadratic, float _minSize, float _maxSize);
+
+		float size; 
+		bool attenuationEnabled; 
+		float constant; 
+		float linear; 
+		float quadratic; 
+		float minSize; 
+		float maxSize;
+
+		virtual void submitCommand(RenderSystem* rs);
+	};
+
+	class CM_EXPORT DfrdTextureCommand : public DeferredGpuCommand
 	{
 	public:
-		DeferredGpuCommandType commandType;
+		DfrdTextureCommand(size_t _texUnit, bool _enabled, const TexturePtr& _tex);
+
+		size_t texUnit;
+		bool enabled;
+		const TexturePtr &tex;
+
+		virtual void submitCommand(RenderSystem* rs);
+	};
+
+	class CM_EXPORT DfrdVertexTextureCommand : public DeferredGpuCommand
+	{
+	public:
+		DfrdVertexTextureCommand(size_t _texUnit, const TexturePtr& _tex);
+
+		size_t texUnit;
+		const TexturePtr& tex;
+
+		virtual void submitCommand(RenderSystem* rs);
+	};
+
+	class CM_EXPORT DfrdTextureFilteringCommand : public DeferredGpuCommand
+	{
+	public:
+		DfrdTextureFilteringCommand(size_t _texUnit, FilterType _ftype, FilterOptions _filter);
+
+		size_t texUnit;
+		FilterType ftype;
+		FilterOptions filter;
+
+		virtual void submitCommand(RenderSystem* rs);
+	};
+
+	class CM_EXPORT DfrdTextureAnisotropyCommand : public DeferredGpuCommand
+	{
+	public:
+		DfrdTextureAnisotropyCommand(size_t _texUnit, unsigned int _maxAnisotropy);
+
+		size_t texUnit;
+		unsigned int maxAnisotropy;
+
+		virtual void submitCommand(RenderSystem* rs);
+	};
+
+	class CM_EXPORT DfrdTextureAddrModeCommand : public DeferredGpuCommand
+	{
+	public:
+		DfrdTextureAddrModeCommand(size_t _texUnit, const SamplerState::UVWAddressingMode& _uvw);
+
+		size_t texUnit;
+		SamplerState::UVWAddressingMode uvw;
+
+		virtual void submitCommand(RenderSystem* rs);
+	};
+
+	class CM_EXPORT DfrdTextureBorderColorCommand : public DeferredGpuCommand
+	{
+	public:
+		DfrdTextureBorderColorCommand(size_t _texUnit, const Color& _color);
+
+		size_t texUnit;
+		Color color;
+
+		virtual void submitCommand(RenderSystem* rs);
+	};
+
+	class CM_EXPORT DfrdTextureMipBiasCommand : public DeferredGpuCommand
+	{
+	public:
+		DfrdTextureMipBiasCommand(size_t _texUnit, float _bias);
+
+		size_t texUnit;
+		float bias;
+
+		virtual void submitCommand(RenderSystem* rs);
+	};
+
+	class CM_EXPORT DfrdSceneBlendingCommand : public DeferredGpuCommand
+	{
+	public:
+		DfrdSceneBlendingCommand(SceneBlendFactor _sourceFactor, 
+			SceneBlendFactor _destFactor, SceneBlendOperation _op);
+
+		SceneBlendFactor sourceFactor;
+		SceneBlendFactor destFactor;
+		SceneBlendOperation op;
+
+		virtual void submitCommand(RenderSystem* rs);
+	};
+
+	class CM_EXPORT DfrdSeparateSceneBlendingCommand : public DeferredGpuCommand
+	{
+	public:
+		DfrdSeparateSceneBlendingCommand(SceneBlendFactor _sourceFactor, 
+			SceneBlendFactor _destFactor, SceneBlendFactor _sourceFactorAlpha, 
+			SceneBlendFactor _destFactorAlpha, SceneBlendOperation _op, 
+			SceneBlendOperation _alphaOp);
+
+		SceneBlendFactor sourceFactor;
+		SceneBlendFactor destFactor;
+		SceneBlendFactor sourceFactorAlpha;
+		SceneBlendFactor destFactorAlpha;
+		SceneBlendOperation op;
+		SceneBlendOperation alphaOp;
+
+		virtual void submitCommand(RenderSystem* rs);
+	};
+
+	class CM_EXPORT DfrdAlphaRejectParamsCommand : public DeferredGpuCommand
+	{
+	public:
+		DfrdAlphaRejectParamsCommand(CompareFunction _func, 
+			unsigned char _value, bool _alphaToCoverage);
+
+		CompareFunction func;
+		unsigned char value;
+		bool alphaToCoverage;
+
+		virtual void submitCommand(RenderSystem* rs);
+	};
+
+	// TODO
+	class CM_EXPORT DfrdViewportCommand : public DeferredGpuCommand
+	{
+	public:
+		DfrdViewportCommand();
+
+		virtual void submitCommand(RenderSystem* rs);
+	};
+
+	class CM_EXPORT DfrdCullingCommand : public DeferredGpuCommand
+	{
+	public:
+		DfrdCullingCommand(CullingMode _mode);
+
+		CullingMode mode;
+
+		virtual void submitCommand(RenderSystem* rs);
+	};
+
+	class CM_EXPORT DfrdDepthBufferParamsCommand : public DeferredGpuCommand
+	{
+	public:
+		DfrdDepthBufferParamsCommand(bool _depthTest, bool _depthWrite, 
+			CompareFunction _depthFunction);
+
+		bool depthTest;
+		bool depthWrite;
+		CompareFunction depthFunction;
+
+		virtual void submitCommand(RenderSystem* rs);
+	};
+
+	class CM_EXPORT DfrdDepthBufferCheckCommand : public DeferredGpuCommand
+	{
+	public:
+		DfrdDepthBufferCheckCommand(bool _enabled);
+
+		bool enabled;
+
+		virtual void submitCommand(RenderSystem* rs);
+	};
+
+	class CM_EXPORT DfrdDepthBufferWriteCommand : public DeferredGpuCommand
+	{
+	public:
+		DfrdDepthBufferWriteCommand(bool _enabled);
+
+		bool enabled;
+
+		virtual void submitCommand(RenderSystem* rs);
+	};
+
+	class CM_EXPORT DfrdDepthBufferFuncCommand : public DeferredGpuCommand
+	{
+	public:
+		DfrdDepthBufferFuncCommand(CompareFunction _func);
+
+		CompareFunction func;
+
+		virtual void submitCommand(RenderSystem* rs);
+	};
+
+	class CM_EXPORT DfrdDepthBiasCommand : public DeferredGpuCommand
+	{
+	public:
+		DfrdDepthBiasCommand(float _constantBias, float _slopeScaleBias);
+
+		float constantBias;
+		float slopeScaleBias;
+
+		virtual void submitCommand(RenderSystem* rs);
+	};
+
+	class CM_EXPORT DfrdColorBufferWriteCommand : public DeferredGpuCommand
+	{
+	public:
+		DfrdColorBufferWriteCommand(bool _red, bool _green, bool _blue, bool _alpha);
+
+		bool red;
+		bool green;
+		bool blue;
+		bool alpha;
+
+		virtual void submitCommand(RenderSystem* rs);
+	};
+
+	class CM_EXPORT DfrdDisableTextureUnitCommand : public DeferredGpuCommand
+	{
+	public:
+		DfrdDisableTextureUnitCommand(size_t _texUnit);
+
+		size_t texUnit;
+
+		virtual void submitCommand(RenderSystem* rs);
+	};
+
+	class CM_EXPORT DfrdDisableTextureUnitsFromCommand : public DeferredGpuCommand
+	{
+	public:
+		DfrdDisableTextureUnitsFromCommand(size_t _texUnit);
+
+		size_t texUnit;
+
+		virtual void submitCommand(RenderSystem* rs);
+	};
+
+	class CM_EXPORT DfrdBeginFrameCommand : public DeferredGpuCommand
+	{
+	public:
+		DfrdBeginFrameCommand();
+
+		virtual void submitCommand(RenderSystem* rs);
+	};
+
+	class CM_EXPORT DfrdEndFrameCommand : public DeferredGpuCommand
+	{
+	public:
+		DfrdEndFrameCommand();
+
+		virtual void submitCommand(RenderSystem* rs);
+	};
+
+	class CM_EXPORT DfrdClearFrameBufferCommand : public DeferredGpuCommand
+	{
+	public:
+		DfrdClearFrameBufferCommand(unsigned int _buffers, 
+			const Color& _color, float _depth, unsigned short _stencil);
+
+		unsigned int buffers;
+		Color color;
+		float depth;
+		unsigned short stencil;
+
+		virtual void submitCommand(RenderSystem* rs);
 	};
 }

+ 295 - 2
CamelotRenderer/Include/CmDeferredRenderSystem.h

@@ -1,12 +1,17 @@
 #pragma once
 
 #include "CmPrerequisites.h"
+#include "CmRenderSystem.h"
 
 namespace CamelotEngine
 {
-	class DeferredRenderSystem
+	// TODO Low priority - We have too many allocations for RenderCommands in this class. Maybe pool the commands somewhere?
+
+	class CM_EXPORT DeferredRenderSystem
 	{
 	public:
+		DeferredRenderSystem(CM_THREAD_ID_TYPE threadId);
+
 		/**
 		 * @brief	Wrapper around RenderSystem method of the same name. See RenderSystem doc.
 		 * 			
@@ -14,9 +19,297 @@ namespace CamelotEngine
 		 */
 		void render(const RenderOperation& op);
 
+		/**
+		 * @brief	Wrapper around RenderSystem method of the same name. See RenderSystem doc.
+		 * 			
+		 * @see		RenderSystem::bindGpuProgram()
+		 */
+		virtual void bindGpuProgram(GpuProgramPtr prg);
+
+		/**
+		 * @brief	Wrapper around RenderSystem method of the same name. See RenderSystem doc.
+		 * 			
+		 * @see		RenderSystem::bindGpuProgramParameters()
+		 */
+		void bindGpuProgramParameters(GpuProgramType gptype, GpuProgramParametersSharedPtr params);
+				
+		/**
+		 * @brief	Wrapper around RenderSystem method of the same name. See RenderSystem doc.
+		 * 			
+		 * @see		RenderSystem::bindGpuProgramParameters()
+		 */
+		void setInvertVertexWinding(bool invert);
+		
+		/**
+		 * @brief	Wrapper around RenderSystem method of the same name. See RenderSystem doc.
+		 * 			
+		 * @see		RenderSystem::setScissorTest()
+		 */
+		void setScissorTest(bool enabled, size_t left = 0, size_t top = 0, 
+			size_t right = 1280, size_t bottom = 720);
+		
+		/**
+		 * @brief	Wrapper around RenderSystem method of the same name. See RenderSystem doc.
+		 * 			
+		 * @see		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);
+		
+		/**
+		 * @brief	Wrapper around RenderSystem method of the same name. See RenderSystem doc.
+		 * 			
+		 * @see		RenderSystem::setVertexDeclaration()
+		 */
+		void setVertexDeclaration(VertexDeclarationPtr decl);
+		
+		/**
+		 * @brief	Wrapper around RenderSystem method of the same name. See RenderSystem doc.
+		 * 			
+		 * @see		RenderSystem::setVertexBufferBinding()
+		 */
+		void setVertexBufferBinding(VertexBufferBinding* binding);
+		
+		/**
+		 * @brief	Wrapper around RenderSystem method of the same name. See RenderSystem doc.
+		 * 			
+		 * @see		RenderSystem::setPolygonMode()
+		 */
+		void setPolygonMode(PolygonMode mode);
+		
+		/**
+		 * @brief	Wrapper around RenderSystem method of the same name. See RenderSystem doc.
+		 * 			
+		 * @see		RenderSystem::setStencilCheckEnabled()
+		 */
+		void setStencilCheckEnabled(bool enabled);
+		
+		/**
+		 * @brief	Wrapper around RenderSystem method of the same name. See RenderSystem doc.
+		 * 			
+		 * @see		RenderSystem::setWaitForVerticalBlank()
+		 */
+		void setWaitForVerticalBlank(bool enabled);
+		
+		/**
+		 * @brief	Wrapper around RenderSystem method of the same name. See RenderSystem doc.
+		 * 			
+		 * @see		RenderSystem::setTextureUnitSettings()
+		 */
+		void setTextureUnitSettings(size_t texUnit, const TexturePtr& texture, const SamplerState& samplerState);
+		
+		/**
+		 * @brief	Wrapper around RenderSystem method of the same name. See RenderSystem doc.
+		 * 			
+		 * @see		RenderSystem::setPointParameters()
+		 */
+		void setPointParameters(float size, bool attenuationEnabled, 
+			float constant, float linear, float quadratic, float minSize, float maxSize);
+		
+		/**
+		 * @brief	Wrapper around RenderSystem method of the same name. See RenderSystem doc.
+		 * 			
+		 * @see		RenderSystem::setTexture()
+		 */
+		void setTexture(size_t unit, bool enabled, const TexturePtr &texPtr);
+		
+		/**
+		 * @brief	Wrapper around RenderSystem method of the same name. See RenderSystem doc.
+		 * 			
+		 * @see		RenderSystem::setVertexTexture()
+		 */
+		void setVertexTexture(size_t unit, const TexturePtr& tex);
+		
+		/**
+		 * @brief	Wrapper around RenderSystem method of the same name. See RenderSystem doc.
+		 * 			
+		 * @see		RenderSystem::setTextureUnitFiltering()
+		 */
+		void setTextureFiltering(size_t unit, FilterOptions minFilter,
+			FilterOptions magFilter, FilterOptions mipFilter);
+		
+		/**
+		 * @brief	Wrapper around RenderSystem method of the same name. See RenderSystem doc.
+		 * 			
+		 * @see		RenderSystem::setTextureFiltering()
+		 */
+		void setTextureFiltering(size_t unit, FilterType ftype, FilterOptions filter);
+		
+		/**
+		 * @brief	Wrapper around RenderSystem method of the same name. See RenderSystem doc.
+		 * 			
+		 * @see		RenderSystem::setTextureAnisotropy()
+		 */
+		void setTextureAnisotropy(size_t unit, unsigned int maxAnisotropy);
+		
+		/**
+		 * @brief	Wrapper around RenderSystem method of the same name. See RenderSystem doc.
+		 * 			
+		 * @see		RenderSystem::setTextureAddressingMode()
+		 */
+		void setTextureAddressingMode(size_t unit, const SamplerState::UVWAddressingMode& uvw);
+		
+		/**
+		 * @brief	Wrapper around RenderSystem method of the same name. See RenderSystem doc.
+		 * 			
+		 * @see		RenderSystem::setTextureBorderColor()
+		 */
+		void setTextureBorderColor(size_t unit, const Color& color);
+		
+		/**
+		 * @brief	Wrapper around RenderSystem method of the same name. See RenderSystem doc.
+		 * 			
+		 * @see		RenderSystem::setTextureMipmapBias()
+		 */
+		void setTextureMipmapBias(size_t unit, float bias);
+		
+		/**
+		 * @brief	Wrapper around RenderSystem method of the same name. See RenderSystem doc.
+		 * 			
+		 * @see		RenderSystem::setSceneBlending()
+		 */
+		void setSceneBlending(SceneBlendFactor sourceFactor, SceneBlendFactor destFactor, SceneBlendOperation op = SBO_ADD);
+		
+		/**
+		 * @brief	Wrapper around RenderSystem method of the same name. See RenderSystem doc.
+		 * 			
+		 * @see		RenderSystem::setSeparateSceneBlending()
+		 */
+		void setSeparateSceneBlending(SceneBlendFactor sourceFactor, SceneBlendFactor destFactor, SceneBlendFactor sourceFactorAlpha, 
+			SceneBlendFactor destFactorAlpha, SceneBlendOperation op = SBO_ADD, SceneBlendOperation alphaOp = SBO_ADD);
+		
+		/**
+		 * @brief	Wrapper around RenderSystem method of the same name. See RenderSystem doc.
+		 * 			
+		 * @see		RenderSystem::setAlphaRejectSettings()
+		 */
+		void setAlphaRejectSettings(CompareFunction func, unsigned char value, bool alphaToCoverage);
+		
+		/**
+		 * @brief	Wrapper around RenderSystem method of the same name. See RenderSystem doc.
+		 * 			
+		 * @see		RenderSystem::setViewport()
+		 */
+		void setViewport(Viewport *vp);
+		
+		/**
+		 * @brief	Wrapper around RenderSystem method of the same name. See RenderSystem doc.
+		 * 			
+		 * @see		RenderSystem::setCullingMode()
+		 */
+		void setCullingMode(CullingMode mode);
+		
+		/**
+		 * @brief	Wrapper around RenderSystem method of the same name. See RenderSystem doc.
+		 * 			
+		 * @see		RenderSystem::setDepthBufferParams()
+		 */
+		void setDepthBufferParams(bool depthTest = true, bool depthWrite = true, CompareFunction depthFunction = CMPF_LESS_EQUAL);
+		
+		/**
+		 * @brief	Wrapper around RenderSystem method of the same name. See RenderSystem doc.
+		 * 			
+		 * @see		RenderSystem::setDepthBufferCheckEnabled()
+		 */
+		void setDepthBufferCheckEnabled(bool enabled = true);
+		
+		/**
+		 * @brief	Wrapper around RenderSystem method of the same name. See RenderSystem doc.
+		 * 			
+		 * @see		RenderSystem::setDepthBufferWriteEnabled()
+		 */
+		void setDepthBufferWriteEnabled(bool enabled = true);
+		
+		/**
+		 * @brief	Wrapper around RenderSystem method of the same name. See RenderSystem doc.
+		 * 			
+		 * @see		RenderSystem::setDepthBufferFunction()
+		 */
+		void setDepthBufferFunction(CompareFunction func = CMPF_LESS_EQUAL);
+		
+		/**
+		 * @brief	Wrapper around RenderSystem method of the same name. See RenderSystem doc.
+		 * 			
+		 * @see		RenderSystem::setDepthBias()
+		 */
+		void setDepthBias(float constantBias, float slopeScaleBias = 0.0f);
+		
+		/**
+		 * @brief	Wrapper around RenderSystem method of the same name. See RenderSystem doc.
+		 * 			
+		 * @see		RenderSystem::setColorBufferWriteEnabled()
+		 */
+		void setColorBufferWriteEnabled(bool red, bool green, bool blue, bool alpha);
+
+		/**
+		 * @brief	Wrapper around RenderSystem method of the same name. See RenderSystem doc.
+		 * 			
+		 * @see		RenderSystem::disableTextureUnit()
+		 */
+		void disableTextureUnit(size_t texUnit);
+		
+		/**
+		 * @brief	Wrapper around RenderSystem method of the same name. See RenderSystem doc.
+		 * 			
+		 * @see		RenderSystem::disableTextureUnitsFrom()
+		 */
+		void disableTextureUnitsFrom(size_t texUnit);
+
+		/**
+		 * @brief	Wrapper around RenderSystem method of the same name. See RenderSystem doc.
+		 * 			
+		 * @see		RenderSystem::beginFrame()
+		 */
+		void beginFrame(void);
+
+		/**
+		 * @brief	Wrapper around RenderSystem method of the same name. See RenderSystem doc.
+		 * 			
+		 * @see		RenderSystem::endFrame()
+		 */
+		void endFrame(void);
+
+		/**
+		 * @brief	Wrapper around RenderSystem method of the same name. See RenderSystem doc.
+		 * 			
+		 * @see		RenderSystem::clearFrameBuffer()
+		 */
+		void clearFrameBuffer(unsigned int buffers, 
+			const Color& colour = 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
+		 * 			as soon as the render thread is ready.
+		 * 			
+		 * @note	This is expected to be called once per frame. If the previous set of commands hasn't even started rendering
+		 * 			yet, it will be discarded. This is to prevent lag if the simulation executes faster than the render thread.
+		 */
 		void submitToGpu();
 
 	private:
-		vector<DeferredGpuCommand*>::type mRenderCommands;
+		// Actively being filled up
+		vector<DeferredGpuCommand*>::type* mActiveRenderCommandBuffer;
+
+		// Finalized and ready for rendering
+		vector<DeferredGpuCommand*>::type* mReadyRenderCommandBuffer;
+
+		CM_THREAD_ID_TYPE mMyThreadId;
+		CM_MUTEX(mCommandBufferMutex)
+
+		/**
+		 * @brief	Plays all queued commands
+		 */
+		void playbackCommands();
+
+		/**
+		 * @brief	Throw an exception if the current thread is not the original
+		 * 			thread the DeferredRenderSystem was started on.
+		 */
+		void throwIfInvalidThread();
 	};
 }

+ 0 - 23
CamelotRenderer/Include/CmRenderCommand.h

@@ -1,23 +0,0 @@
-#pragma once
-
-#include "CmPrerequisites.h"
-
-namespace CamelotEngine
-{
-	class RenderCommand
-	{
-	public:
-		RenderCommand(RenderOperation& ro, PassPtr& pass, PassParametersPtr& passParams)
-			:mRO(ro), mPass(pass), mPassParameters(passParams)
-		{ }
-
-		const RenderOperation& getRenderOperation() const { return mRO; }
-		PassPtr getPass() const { return mPass; }
-		PassParametersPtr getPassParameters() const { return mPassParameters; }
-
-	private:
-		RenderOperation mRO; // TODO Low priority - Keeping this by value is unnecessary overhead
-		PassPtr mPass;
-		PassParametersPtr mPassParameters;
-	};
-}

+ 0 - 80
CamelotRenderer/Include/CmRenderCommandBuffer.cpp

@@ -1,80 +0,0 @@
-#include "CmRenderCommandBuffer.h"
-#include "CmRenderSystem.h"
-#include "CmRenderer.h"
-#include "CmApplication.h"
-#include "CmRenderSystemManager.h"
-#include "CmRendererManager.h"
-#include "CmException.h"
-
-namespace CamelotEngine
-{
-	RenderCommandBuffer::RenderCommandBuffer(CM_THREAD_ID_TYPE threadId)
-	{
-		mMyThreadId = threadId;
-		mRenderCommands = new vector<RenderCommand>::type();
-	}
-
-	RenderCommandBuffer::~RenderCommandBuffer()
-	{
-		mActivePass = nullptr;
-		mActiveParameters = nullptr;
-
-		if(mRenderCommands != nullptr)
-			delete mRenderCommands;
-	}
-
-	void RenderCommandBuffer::render(RenderOperation renderOp)
-	{
-		CM_LOCK_MUTEX(mCommandBufferMutex)
-
-		throwIfInvalidThread();
-
-		RenderCommand newCommand(renderOp, mActivePass, mActiveParameters);
-
-		mRenderCommands->push_back(newCommand);
-	}
-
-	void RenderCommandBuffer::applyPass(PassPtr pass, PassParametersPtr passParameters)
-	{
-		CM_LOCK_MUTEX(mCommandBufferMutex)
-
-		throwIfInvalidThread();
-
-		mActivePass = pass;
-		mActiveParameters = passParameters;
-	}
-
-	void RenderCommandBuffer::playDeferredCommands()
-	{
-		vector<RenderCommand>::type* oldRenderCommands = nullptr;
-		
-		{
-			CM_LOCK_MUTEX(mCommandBufferMutex)
-			oldRenderCommands = mRenderCommands;
-			mRenderCommands = new vector<RenderCommand>::type();
-		}
-
-		RenderSystem* renderSystem = RenderSystemManager::getActive();
-		RendererPtr renderer = RendererManager::getActive();
-		
-		for(auto iter = oldRenderCommands->begin(); iter != oldRenderCommands->end(); ++iter)
-		{
-			renderer->setPass(iter->getPass());
-			renderer->setPassParameters(iter->getPassParameters());
-
-			renderSystem->render(iter->getRenderOperation());
-		}
-
-		if(oldRenderCommands != nullptr)
-			delete oldRenderCommands;
-
-		mActivePass = nullptr;
-		mActiveParameters = nullptr;
-	}
-
-	void RenderCommandBuffer::throwIfInvalidThread()
-	{
-		if(mMyThreadId != CM_THREAD_CURRENT_ID)
-			CM_EXCEPT(InternalErrorException, "Calling the rendering context from an invalid thread.");
-	}
-}

+ 0 - 52
CamelotRenderer/Include/CmRenderCommandBuffer.h

@@ -1,52 +0,0 @@
-#pragma once
-
-#include "CmPrerequisites.h"
-#include "CmRenderOperation.h"
-#include "CmRenderCommand.h"
-
-namespace CamelotEngine
-{
-	/**
-	 * @brief	Used for multithreaded rendering. One render command buffer should exist per thread.
-	 * 			All render operations are recorded in the buffer, and then played back
-	 * 			on the render thread. 
-	 */
-	class RenderCommandBuffer
-	{
-	public:
-		RenderCommandBuffer(CM_THREAD_ID_TYPE threadId);
-		~RenderCommandBuffer();
-
-		/**
-		 * @brief	Adds a new render command that will be executed when the playback is initiated.
-		 * 			CommandBuffer takes ownership of the command, and will release it after playback is complete.
-		 */
-		void render(RenderOperation renderOp);
-
-		/**
-		 * @brief	Adds a new apply pass command that will be executed when the playback is initiated. Selected
-		 * 			pass will be used for all subsequent render commands.
-		 */
-		void applyPass(PassPtr pass, PassParametersPtr passParameters);
-
-	private:
-		CM_MUTEX(mCommandBufferMutex)
-		vector<RenderCommand>::type* mRenderCommands;
-
-		PassPtr mActivePass;
-		PassParametersPtr mActiveParameters;
-
-		CM_THREAD_ID_TYPE mMyThreadId;
-
-		void throwIfInvalidThread();
-
-	private:
-		friend class RenderSystem;
-
-		/**
-		 * @brief	Executed all commands stored in the buffers, in the order in which they were added.
-		 * 			Must be called on the render thread.
-		 */
-		void playDeferredCommands();
-	};
-}

+ 8 - 8
CamelotRenderer/Include/CmRenderSystem.h

@@ -545,7 +545,7 @@ namespace CamelotEngine
 		@param magFilter The filter used when a texture is magnified
 		@param mipFilter The filter used between mipmap levels, FO_NONE disables mipmapping
 		*/
-		virtual void setTextureUnitFiltering(size_t unit, FilterOptions minFilter,
+		virtual void setTextureFiltering(size_t unit, FilterOptions minFilter,
 			FilterOptions magFilter, FilterOptions mipFilter);
 
 		/** Sets a single filter for a given texture unit.
@@ -553,16 +553,16 @@ namespace CamelotEngine
 		@param ftype The filter type
 		@param filter The filter to be used
 		*/
-		virtual void setTextureUnitFiltering(size_t unit, FilterType ftype, FilterOptions filter) = 0;
+		virtual void setTextureFiltering(size_t unit, FilterType ftype, FilterOptions filter) = 0;
 
 		/** Sets the maximal anisotropy for the specified texture unit.*/
-		virtual void setTextureLayerAnisotropy(size_t unit, unsigned int maxAnisotropy) = 0;
+		virtual void setTextureAnisotropy(size_t unit, unsigned int maxAnisotropy) = 0;
 
 		/** Sets the texture addressing mode for a texture unit.*/
 		virtual void setTextureAddressingMode(size_t unit, const SamplerState::UVWAddressingMode& uvw) = 0;
 
-		/** Sets the texture border colour for a texture unit.*/
-		virtual void setTextureBorderColour(size_t unit, const Color& colour) = 0;
+		/** Sets the texture border color for a texture unit.*/
+		virtual void setTextureBorderColor(size_t unit, const Color& colour) = 0;
 
 		/** Sets the mipmap bias value for a given texture unit.
 		@remarks
@@ -685,7 +685,7 @@ namespace CamelotEngine
 		in a rendering pass. However, the chances are that you really want to use this option
 		through the Material class.
 		@param red, green, blue, alpha Whether writing is enabled for each of the 4 colour channels. */
-		virtual void setColourBufferWriteEnabled(bool red, bool green, bool blue, bool alpha) = 0;
+		virtual void setColorBufferWriteEnabled(bool red, bool green, bool blue, bool alpha) = 0;
 		/** Sets the depth bias, NB you should use the Material version of this. 
 		@remarks
 		When polygons are coplanar, you can get problems with 'depth fighting' where
@@ -727,11 +727,11 @@ namespace CamelotEngine
 		@param colour The colour to convert
 		@param pDest Pointer to location to put the result.
 		*/
-		virtual void convertColourValue(const Color& colour, UINT32* pDest);
+		virtual void convertColorValue(const Color& colour, UINT32* pDest);
 		/** Get the native VertexElementType for a compact 32-bit colour value
 		for this rendersystem.
 		*/
-		virtual VertexElementType getColourVertexElementType(void) const = 0;
+		virtual VertexElementType getColorVertexElementType(void) const = 0;
 
 		/** Converts a uniform projection matrix to suitable for this render system.
 		@remarks

+ 344 - 0
CamelotRenderer/Source/CmDeferredGpuCommands.cpp

@@ -0,0 +1,344 @@
+#include "CmDeferredGpuCommands.h"
+#include "CmRenderSystem.h"
+
+namespace CamelotEngine
+{
+	DeferredGpuCommand::DeferredGpuCommand()
+	{ }
+
+	DfrdRenderGpuCommand::DfrdRenderGpuCommand(RenderOperation& _renderOp)
+		:renderOp(_renderOp)
+	{ }
+
+	void DfrdRenderGpuCommand::submitCommand(RenderSystem* rs)
+	{
+		rs->render(renderOp);
+	}
+
+	DfrdBindGpuProgramCommand::DfrdBindGpuProgramCommand(GpuProgramPtr _gpuProgram)
+		:gpuProgram(_gpuProgram)
+	{ }
+
+	void DfrdBindGpuProgramCommand::submitCommand(RenderSystem* rs)
+	{
+		rs->bindGpuProgram(gpuProgram.get());
+	}
+
+	DfrdBindGpuParamsCommand::DfrdBindGpuParamsCommand(GpuProgramType _type, GpuProgramParametersPtr& _progParams)
+		:type(_type), progParams(_progParams)
+	{ }
+
+	void DfrdBindGpuParamsCommand::submitCommand(RenderSystem* rs)
+	{
+		rs->bindGpuProgramParameters(type, progParams, GPV_ALL);
+	}
+
+	DfrdInvVertWindingCommand::DfrdInvVertWindingCommand(bool _invert)
+		:invert(_invert)
+	{ }
+
+	void DfrdInvVertWindingCommand::submitCommand(RenderSystem* rs)
+	{
+		rs->setInvertVertexWinding(invert);
+	}
+
+	DfrdScissorTestCommand::DfrdScissorTestCommand(bool _enabled, size_t _left, size_t _top, size_t _right, size_t _bottom)
+		:enabled(_enabled), left(_left), top(_top), right(_right), bottom(_bottom)
+	{ }
+
+	void DfrdScissorTestCommand::submitCommand(RenderSystem* rs)
+	{
+		rs->setScissorTest(enabled, left, top, right, bottom);
+	}
+
+	DfrdStencilBufferParamsCommand::DfrdStencilBufferParamsCommand(CompareFunction _func, UINT32 _refValue, UINT32 _mask, 
+		StencilOperation _stencilFailOp, StencilOperation _depthFailOp, 
+		StencilOperation _passOp, bool _twoSidedOperation)
+		:func(_func), refValue(_refValue), mask(_mask), stencilFailOp(_stencilFailOp), depthFailOp(_depthFailOp),
+		passOp(_passOp), twoSidedOperation(_twoSidedOperation)
+	{ }
+
+	void DfrdStencilBufferParamsCommand::submitCommand(RenderSystem* rs)
+	{
+		rs->setStencilBufferParams(func, refValue, mask, stencilFailOp, depthFailOp, passOp, twoSidedOperation);
+	}
+
+// TODO !
+	DfrdVertexDeclCommand::DfrdVertexDeclCommand()
+	{ }
+
+	void DfrdVertexDeclCommand::submitCommand(RenderSystem* rs)
+	{
+
+	}
+
+// TODO !
+	DfrdVertBufferBindCommand::DfrdVertBufferBindCommand()
+	{ }
+
+	void DfrdVertBufferBindCommand::submitCommand(RenderSystem* rs)
+	{
+
+	}
+
+	DfrdPolygonModeCommand::DfrdPolygonModeCommand(PolygonMode _mode)
+		:mode(_mode)
+	{ }
+
+	void DfrdPolygonModeCommand::submitCommand(RenderSystem* rs)
+	{
+		rs->setPolygonMode(mode);
+	}
+
+	DfrdStencilCheckCommand::DfrdStencilCheckCommand(bool _enabled)
+		:enabled(_enabled)
+	{ }
+
+	void DfrdStencilCheckCommand::submitCommand(RenderSystem* rs)
+	{
+		rs->setStencilCheckEnabled(enabled);
+	}
+
+	DfrdWaitForVerticalBlankCommand::DfrdWaitForVerticalBlankCommand(bool _enabled)
+		:enabled(_enabled)
+	{ }
+
+	void DfrdWaitForVerticalBlankCommand::submitCommand(RenderSystem* rs)
+	{
+		rs->setWaitForVerticalBlank(enabled);
+	}
+
+	DfrdTextureUnitSettingsCommand::DfrdTextureUnitSettingsCommand(size_t _texUnit, const TexturePtr& _tex, 
+		const SamplerState& _samplerState)
+		:texUnit(_texUnit), tex(_tex), samplerState(_samplerState)
+	{ }
+
+	void DfrdTextureUnitSettingsCommand::submitCommand(RenderSystem* rs)
+	{
+		rs->setTextureUnitSettings(texUnit, tex, samplerState);
+	}
+
+	DfrdPointParamsCommand::DfrdPointParamsCommand(float _size, bool _attenuationEnabled, 
+		float _constant, float _linear, float _quadratic, float _minSize, float _maxSize)
+		:size(_size), attenuationEnabled(_attenuationEnabled), constant(_constant), linear(_linear),
+		quadratic(_quadratic), minSize(_minSize), maxSize(_maxSize)
+	{ }
+
+	void DfrdPointParamsCommand::submitCommand(RenderSystem* rs)
+	{
+		rs->setPointParameters(size, attenuationEnabled, constant, linear, quadratic, minSize, maxSize);
+	}
+
+	DfrdTextureCommand::DfrdTextureCommand(size_t _texUnit, bool _enabled, const TexturePtr& _tex)
+		:texUnit(_texUnit), enabled(_enabled), tex(_tex)
+	{ }
+
+	void DfrdTextureCommand::submitCommand(RenderSystem* rs)
+	{
+		rs->setTexture(texUnit, enabled, tex);
+	}
+
+	DfrdVertexTextureCommand::DfrdVertexTextureCommand(size_t _texUnit, const TexturePtr& _tex)
+		:texUnit(_texUnit), tex(_tex)
+	{ }
+
+	void DfrdVertexTextureCommand::submitCommand(RenderSystem* rs)
+	{
+		rs->setVertexTexture(texUnit, tex);
+	}
+
+	DfrdTextureFilteringCommand::DfrdTextureFilteringCommand(size_t _texUnit, FilterType _ftype, FilterOptions _filter)
+		:texUnit(_texUnit), ftype(_ftype), filter(_filter)
+	{ }
+
+	void DfrdTextureFilteringCommand::submitCommand(RenderSystem* rs)
+	{
+		rs->setTextureFiltering(texUnit, ftype, filter);
+	}
+
+	DfrdTextureAnisotropyCommand::DfrdTextureAnisotropyCommand(size_t _texUnit, unsigned int _maxAnisotropy)
+		:texUnit(_texUnit), maxAnisotropy(_maxAnisotropy)
+	{ }
+
+	void DfrdTextureAnisotropyCommand::submitCommand(RenderSystem* rs)
+	{
+		rs->setTextureAnisotropy(texUnit, maxAnisotropy);
+	}
+
+	DfrdTextureAddrModeCommand::DfrdTextureAddrModeCommand(size_t _texUnit, const SamplerState::UVWAddressingMode& _uvw)
+		:texUnit(_texUnit), uvw(_uvw)
+	{ }
+
+	void DfrdTextureAddrModeCommand::submitCommand(RenderSystem* rs)
+	{
+		rs->setTextureAddressingMode(texUnit, uvw);
+	}
+
+	DfrdTextureBorderColorCommand::DfrdTextureBorderColorCommand(size_t _texUnit, const Color& _color)
+		:texUnit(_texUnit), color(_color)
+	{ }
+
+	void DfrdTextureBorderColorCommand::submitCommand(RenderSystem* rs)
+	{
+		rs->setTextureBorderColor(texUnit, color);
+	}
+
+	DfrdTextureMipBiasCommand::DfrdTextureMipBiasCommand(size_t _texUnit, float _bias)
+		:texUnit(_texUnit), bias(_bias)
+	{ }
+
+	void DfrdTextureMipBiasCommand::submitCommand(RenderSystem* rs)
+	{
+		rs->setTextureMipmapBias(texUnit, bias);
+	}
+
+	DfrdSceneBlendingCommand::DfrdSceneBlendingCommand(SceneBlendFactor _sourceFactor, 
+		SceneBlendFactor _destFactor, SceneBlendOperation _op)
+		:sourceFactor(_sourceFactor), destFactor(_destFactor), op(_op)
+	{ }
+
+	void DfrdSceneBlendingCommand::submitCommand(RenderSystem* rs)
+	{
+		rs->setSceneBlending(sourceFactor, destFactor, op);
+	}
+
+	DfrdSeparateSceneBlendingCommand::DfrdSeparateSceneBlendingCommand(SceneBlendFactor _sourceFactor, 
+		SceneBlendFactor _destFactor, SceneBlendFactor _sourceFactorAlpha, 
+		SceneBlendFactor _destFactorAlpha, SceneBlendOperation _op, 
+		SceneBlendOperation _alphaOp)
+		:sourceFactor(_sourceFactor), destFactor(_destFactor), sourceFactorAlpha(_sourceFactorAlpha),
+		destFactorAlpha(_destFactorAlpha), op(_op), alphaOp(_alphaOp)
+	{ }
+
+	void DfrdSeparateSceneBlendingCommand::submitCommand(RenderSystem* rs)
+	{
+		rs->setSeparateSceneBlending(sourceFactor, destFactor, sourceFactorAlpha, destFactorAlpha, op, alphaOp);
+	}
+
+	DfrdAlphaRejectParamsCommand::DfrdAlphaRejectParamsCommand(CompareFunction _func, 
+		unsigned char _value, bool _alphaToCoverage)
+		:func(_func), value(_value), alphaToCoverage(_alphaToCoverage)
+	{ }
+
+	void DfrdAlphaRejectParamsCommand::submitCommand(RenderSystem* rs)
+	{
+		rs->setAlphaRejectSettings(func, value, alphaToCoverage);
+	}
+
+// TODO
+	DfrdViewportCommand::DfrdViewportCommand()
+	{ }
+
+	void DfrdViewportCommand::submitCommand(RenderSystem* rs)
+	{
+
+	}
+
+	DfrdCullingCommand::DfrdCullingCommand(CullingMode _mode)
+		:mode(_mode)
+	{ }
+
+	void DfrdCullingCommand::submitCommand(RenderSystem* rs)
+	{
+		rs->setCullingMode(mode);
+	}
+
+	DfrdDepthBufferParamsCommand::DfrdDepthBufferParamsCommand(bool _depthTest, bool _depthWrite, 
+		CompareFunction _depthFunction)
+		:depthTest(_depthTest)
+	{ }
+
+	void DfrdDepthBufferParamsCommand::submitCommand(RenderSystem* rs)
+	{
+		rs->setDepthBufferParams(depthTest, depthWrite, depthFunction);
+	}
+
+	DfrdDepthBufferCheckCommand::DfrdDepthBufferCheckCommand(bool _enabled)
+		:enabled(_enabled)
+	{ }
+
+	void DfrdDepthBufferCheckCommand::submitCommand(RenderSystem* rs)
+	{
+		rs->setDepthBufferCheckEnabled(enabled);
+	}
+
+	DfrdDepthBufferWriteCommand::DfrdDepthBufferWriteCommand(bool _enabled)
+		:enabled(_enabled)
+	{ }
+
+	void DfrdDepthBufferWriteCommand::submitCommand(RenderSystem* rs)
+	{
+		rs->setDepthBufferWriteEnabled(enabled);
+	}
+
+	DfrdDepthBufferFuncCommand::DfrdDepthBufferFuncCommand(CompareFunction _func)
+		:func(_func)
+	{ }
+
+	void DfrdDepthBufferFuncCommand::submitCommand(RenderSystem* rs)
+	{
+		rs->setDepthBufferFunction(func);
+	}
+
+	DfrdDepthBiasCommand::DfrdDepthBiasCommand(float _constantBias, float _slopeScaleBias)
+		:constantBias(_constantBias), slopeScaleBias(_slopeScaleBias)
+	{ }
+
+	void DfrdDepthBiasCommand::submitCommand(RenderSystem* rs)
+	{
+		rs->setDepthBias(constantBias, slopeScaleBias);
+	}
+
+	DfrdColorBufferWriteCommand::DfrdColorBufferWriteCommand(bool _red, bool _green, bool _blue, bool _alpha)
+		:red(_red), green(_green), blue(_blue), alpha(_alpha)
+	{ }
+
+	void DfrdColorBufferWriteCommand::submitCommand(RenderSystem* rs)
+	{
+		rs->setColorBufferWriteEnabled(red, green, blue, alpha);
+	}
+
+	DfrdDisableTextureUnitCommand::DfrdDisableTextureUnitCommand(size_t _texUnit)
+		:texUnit(_texUnit)
+	{ }
+
+	void DfrdDisableTextureUnitCommand::submitCommand(RenderSystem* rs)
+	{
+		rs->disableTextureUnit(texUnit);
+	}
+
+	DfrdDisableTextureUnitsFromCommand::DfrdDisableTextureUnitsFromCommand(size_t _texUnit)
+		:texUnit(_texUnit)
+	{ }
+
+	void DfrdDisableTextureUnitsFromCommand::submitCommand(RenderSystem* rs)
+	{
+		rs->disableTextureUnitsFrom(texUnit);
+	}
+
+	DfrdBeginFrameCommand::DfrdBeginFrameCommand()
+	{ }
+
+	void DfrdBeginFrameCommand::submitCommand(RenderSystem* rs)
+	{
+		rs->beginFrame();
+	}
+
+	DfrdEndFrameCommand::DfrdEndFrameCommand()
+	{ }
+
+	void DfrdEndFrameCommand::submitCommand(RenderSystem* rs)
+	{
+		rs->endFrame();
+	}
+
+	DfrdClearFrameBufferCommand::DfrdClearFrameBufferCommand(unsigned int _buffers, 
+		const Color& _color, float _depth, unsigned short _stencil)
+		:buffers(_buffers), color(_color), depth(_depth), stencil(_stencil)
+	{ }
+
+	void DfrdClearFrameBufferCommand::submitCommand(RenderSystem* rs)
+	{
+		rs->clearFrameBuffer(buffers, color, depth, stencil);
+	}
+}

+ 375 - 1
CamelotRenderer/Source/CmDeferredRenderSystem.cpp

@@ -1,6 +1,380 @@
 #include "CmDeferredRenderSystem.h"
+#include "CmDeferredGpuCommands.h"
+#include "CmRenderSystemManager.h"
+#include "CmException.h"
 
 namespace CamelotEngine
 {
-	
+	DeferredRenderSystem::DeferredRenderSystem(CM_THREAD_ID_TYPE threadId)
+		:mMyThreadId(threadId)
+	{
+		mActiveRenderCommandBuffer = new vector<DeferredGpuCommand*>::type();
+	}
+
+	void DeferredRenderSystem::render(const RenderOperation& op)
+	{
+		throwIfInvalidThread();
+
+		RenderOperation opCopy = op;
+
+		DfrdRenderGpuCommand* newCommand = new DfrdRenderGpuCommand(opCopy);
+		mActiveRenderCommandBuffer->push_back(newCommand);
+	}
+
+	void DeferredRenderSystem::bindGpuProgram(GpuProgramPtr prg)
+	{
+		throwIfInvalidThread();
+
+		DfrdBindGpuProgramCommand* newCommand = new DfrdBindGpuProgramCommand(prg);
+		mActiveRenderCommandBuffer->push_back(newCommand);
+	}
+
+	void DeferredRenderSystem::bindGpuProgramParameters(GpuProgramType gptype, GpuProgramParametersSharedPtr params)
+	{
+		throwIfInvalidThread();
+
+		// We need to copy the constant buffers in order to prevent the user from modifying the parameters before rendering is done.
+		// Because of the way how GpuProgramParameters copy constructor works, only constants are copied and rest of the data is shared.
+		// Shared data is data that is only modified on shader change, and that should only occur on render thread, so it won't interfere
+		// with rendering.
+		GpuProgramParametersSharedPtr paramCopy = GpuProgramParametersSharedPtr(new GpuProgramParameters(*params));
+
+		DfrdBindGpuParamsCommand* newCommand = new DfrdBindGpuParamsCommand(gptype, paramCopy);
+		mActiveRenderCommandBuffer->push_back(newCommand);
+	}
+
+	void DeferredRenderSystem::setInvertVertexWinding(bool invert)
+	{
+		throwIfInvalidThread();
+
+		DfrdInvVertWindingCommand* newCommand = new DfrdInvVertWindingCommand(invert);
+		mActiveRenderCommandBuffer->push_back(newCommand);
+	}
+		
+	void DeferredRenderSystem::setScissorTest(bool enabled, size_t left, size_t top, size_t right, size_t bottom)
+	{
+		throwIfInvalidThread();
+
+		DfrdScissorTestCommand* newCommand = new DfrdScissorTestCommand(enabled, left, top, right, bottom);
+		mActiveRenderCommandBuffer->push_back(newCommand);
+	}
+		
+	void DeferredRenderSystem::setStencilBufferParams(CompareFunction func, UINT32 refValue, UINT32 mask, 
+		StencilOperation stencilFailOp, StencilOperation depthFailOp, StencilOperation passOp, bool twoSidedOperation)
+	{
+		throwIfInvalidThread();
+
+		DfrdStencilBufferParamsCommand* newCommand = new DfrdStencilBufferParamsCommand(func, refValue, mask, stencilFailOp, depthFailOp, passOp, twoSidedOperation);
+		mActiveRenderCommandBuffer->push_back(newCommand);
+	}
+
+	void DeferredRenderSystem::setVertexDeclaration(VertexDeclarationPtr decl)
+	{
+		throwIfInvalidThread();
+
+		DfrdVertexDeclCommand* newCommand = new DfrdVertexDeclCommand();
+		mActiveRenderCommandBuffer->push_back(newCommand);
+	}
+		
+	void DeferredRenderSystem::setVertexBufferBinding(VertexBufferBinding* binding)
+	{
+		throwIfInvalidThread();
+
+		DfrdVertBufferBindCommand* newCommand = new DfrdVertBufferBindCommand();
+		mActiveRenderCommandBuffer->push_back(newCommand);
+	}
+		
+	void DeferredRenderSystem::setPolygonMode(PolygonMode mode)
+	{
+		throwIfInvalidThread();
+
+		DfrdPolygonModeCommand* newCommand = new DfrdPolygonModeCommand(mode);
+		mActiveRenderCommandBuffer->push_back(newCommand);
+	}
+		
+	void DeferredRenderSystem::setStencilCheckEnabled(bool enabled)
+	{
+		throwIfInvalidThread();
+
+		DfrdStencilCheckCommand* newCommand = new DfrdStencilCheckCommand(enabled);
+		mActiveRenderCommandBuffer->push_back(newCommand);
+	}
+		
+	void DeferredRenderSystem::setWaitForVerticalBlank(bool enabled)
+	{
+		throwIfInvalidThread();
+
+		DfrdWaitForVerticalBlankCommand* newCommand = new DfrdWaitForVerticalBlankCommand(enabled);
+		mActiveRenderCommandBuffer->push_back(newCommand);
+	}
+		
+	void DeferredRenderSystem::setTextureUnitSettings(size_t texUnit, const TexturePtr& texture, const SamplerState& samplerState)
+	{
+		throwIfInvalidThread();
+
+		DfrdTextureUnitSettingsCommand* newCommand = new DfrdTextureUnitSettingsCommand(texUnit, texture, samplerState);
+		mActiveRenderCommandBuffer->push_back(newCommand);
+	}
+		
+	void DeferredRenderSystem::setPointParameters(float size, bool attenuationEnabled, 
+		float constant, float linear, float quadratic, float minSize, float maxSize)
+	{
+		throwIfInvalidThread();
+
+		DfrdPointParamsCommand* newCommand = new DfrdPointParamsCommand(size, attenuationEnabled, constant, linear, quadratic, minSize, maxSize);
+		mActiveRenderCommandBuffer->push_back(newCommand);
+	}
+		
+	void DeferredRenderSystem::setTexture(size_t unit, bool enabled, const TexturePtr &texPtr)
+	{
+		throwIfInvalidThread();
+
+		DfrdTextureCommand* newCommand = new DfrdTextureCommand(unit, enabled, texPtr);
+		mActiveRenderCommandBuffer->push_back(newCommand);
+	}
+		
+	void DeferredRenderSystem::setVertexTexture(size_t unit, const TexturePtr& tex)
+	{
+		throwIfInvalidThread();
+
+		DfrdVertexTextureCommand* newCommand = new DfrdVertexTextureCommand(unit, tex);
+		mActiveRenderCommandBuffer->push_back(newCommand);
+	}
+		
+	void DeferredRenderSystem::setTextureFiltering(size_t unit, FilterOptions minFilter,
+		FilterOptions magFilter, FilterOptions mipFilter)
+	{
+		throwIfInvalidThread();
+
+		setTextureFiltering(unit, FT_MIN, minFilter);
+		setTextureFiltering(unit, FT_MAG, magFilter);
+		setTextureFiltering(unit, FT_MIP, mipFilter);
+	}
+		
+	void DeferredRenderSystem::setTextureFiltering(size_t unit, FilterType ftype, FilterOptions filter)
+	{
+		throwIfInvalidThread();
+
+		DfrdTextureFilteringCommand* newCommand = new DfrdTextureFilteringCommand(unit, ftype, filter);
+		mActiveRenderCommandBuffer->push_back(newCommand);
+	}
+		
+	void DeferredRenderSystem::setTextureAnisotropy(size_t unit, unsigned int maxAnisotropy)
+	{
+		throwIfInvalidThread();
+
+		DfrdTextureAnisotropyCommand* newCommand = new DfrdTextureAnisotropyCommand(unit, maxAnisotropy);
+		mActiveRenderCommandBuffer->push_back(newCommand);
+	}
+		
+	void DeferredRenderSystem::setTextureAddressingMode(size_t unit, const SamplerState::UVWAddressingMode& uvw)
+	{
+		throwIfInvalidThread();
+
+		DfrdTextureAddrModeCommand* newCommand = new DfrdTextureAddrModeCommand(unit, uvw);
+		mActiveRenderCommandBuffer->push_back(newCommand);
+	}
+		
+	void DeferredRenderSystem::setTextureBorderColor(size_t unit, const Color& color)
+	{
+		throwIfInvalidThread();
+
+		DfrdTextureBorderColorCommand* newCommand = new DfrdTextureBorderColorCommand(unit, color);
+		mActiveRenderCommandBuffer->push_back(newCommand);
+	}
+		
+	void DeferredRenderSystem::setTextureMipmapBias(size_t unit, float bias)
+	{
+		throwIfInvalidThread();
+
+		DfrdTextureMipBiasCommand* newCommand = new DfrdTextureMipBiasCommand(unit, bias);
+		mActiveRenderCommandBuffer->push_back(newCommand);
+	}
+		
+	void DeferredRenderSystem::setSceneBlending(SceneBlendFactor sourceFactor, SceneBlendFactor destFactor, SceneBlendOperation op)
+	{
+		throwIfInvalidThread();
+
+		DfrdSceneBlendingCommand* newCommand = new DfrdSceneBlendingCommand(sourceFactor, destFactor, op);
+		mActiveRenderCommandBuffer->push_back(newCommand);
+	}
+		
+	void DeferredRenderSystem::setSeparateSceneBlending(SceneBlendFactor sourceFactor, SceneBlendFactor destFactor, SceneBlendFactor sourceFactorAlpha, 
+		SceneBlendFactor destFactorAlpha, SceneBlendOperation op, SceneBlendOperation alphaOp)
+	{
+		throwIfInvalidThread();
+
+		DfrdSeparateSceneBlendingCommand* newCommand = new DfrdSeparateSceneBlendingCommand(sourceFactor, destFactor, sourceFactorAlpha, destFactorAlpha, op, alphaOp);
+		mActiveRenderCommandBuffer->push_back(newCommand);
+	}
+		
+	void DeferredRenderSystem::setAlphaRejectSettings(CompareFunction func, unsigned char value, bool alphaToCoverage)
+	{
+		throwIfInvalidThread();
+
+		DfrdAlphaRejectParamsCommand* newCommand = new DfrdAlphaRejectParamsCommand(func, value, alphaToCoverage);
+		mActiveRenderCommandBuffer->push_back(newCommand);
+	}
+		
+	void DeferredRenderSystem::setViewport(Viewport *vp)
+	{
+		throwIfInvalidThread();
+
+		DfrdViewportCommand* newCommand = new DfrdViewportCommand();
+		mActiveRenderCommandBuffer->push_back(newCommand);
+	}
+		
+	void DeferredRenderSystem::setCullingMode(CullingMode mode)
+	{
+		throwIfInvalidThread();
+
+		DfrdCullingCommand* newCommand = new DfrdCullingCommand(mode);
+		mActiveRenderCommandBuffer->push_back(newCommand);
+	}
+		
+	void DeferredRenderSystem::setDepthBufferParams(bool depthTest, bool depthWrite, CompareFunction depthFunction)
+	{
+		throwIfInvalidThread();
+
+		DfrdDepthBufferParamsCommand* newCommand = new DfrdDepthBufferParamsCommand(depthTest, depthWrite, depthFunction);
+		mActiveRenderCommandBuffer->push_back(newCommand);
+	}
+		
+	void DeferredRenderSystem::setDepthBufferCheckEnabled(bool enabled)
+	{
+		throwIfInvalidThread();
+
+		DfrdDepthBufferCheckCommand* newCommand = new DfrdDepthBufferCheckCommand(enabled);
+		mActiveRenderCommandBuffer->push_back(newCommand);
+	}
+		
+	void DeferredRenderSystem::setDepthBufferWriteEnabled(bool enabled)
+	{
+		throwIfInvalidThread();
+
+		DfrdDepthBufferWriteCommand* newCommand = new DfrdDepthBufferWriteCommand(enabled);
+		mActiveRenderCommandBuffer->push_back(newCommand);
+	}
+		
+	void DeferredRenderSystem::setDepthBufferFunction(CompareFunction func)
+	{
+		throwIfInvalidThread();
+
+		DfrdDepthBufferFuncCommand* newCommand = new DfrdDepthBufferFuncCommand(func);
+		mActiveRenderCommandBuffer->push_back(newCommand);
+	}
+		
+	void DeferredRenderSystem::setDepthBias(float constantBias, float slopeScaleBias)
+	{
+		throwIfInvalidThread();
+
+		DfrdDepthBiasCommand* newCommand = new DfrdDepthBiasCommand(constantBias, slopeScaleBias);
+		mActiveRenderCommandBuffer->push_back(newCommand);
+	}
+
+	void DeferredRenderSystem::setColorBufferWriteEnabled(bool red, bool green, bool blue, bool alpha)
+	{
+		throwIfInvalidThread();
+
+		DfrdColorBufferWriteCommand* newCommand = new DfrdColorBufferWriteCommand(red, green, blue, alpha);
+		mActiveRenderCommandBuffer->push_back(newCommand);
+	}
+
+	void DeferredRenderSystem::disableTextureUnit(size_t texUnit)
+	{
+		throwIfInvalidThread();
+
+		DfrdDisableTextureUnitCommand* newCommand = new DfrdDisableTextureUnitCommand(texUnit);
+		mActiveRenderCommandBuffer->push_back(newCommand);
+	}
+		
+	void DeferredRenderSystem::disableTextureUnitsFrom(size_t texUnit)
+	{
+		throwIfInvalidThread();
+
+		DfrdDisableTextureUnitsFromCommand* newCommand = new DfrdDisableTextureUnitsFromCommand(texUnit);
+		mActiveRenderCommandBuffer->push_back(newCommand);
+	}
+
+	void DeferredRenderSystem::beginFrame(void)
+	{
+		throwIfInvalidThread();
+
+		DfrdBeginFrameCommand* newCommand = new DfrdBeginFrameCommand();
+		mActiveRenderCommandBuffer->push_back(newCommand);
+	}
+
+	void DeferredRenderSystem::endFrame(void)
+	{
+		throwIfInvalidThread();
+
+		DfrdEndFrameCommand* newCommand = new DfrdEndFrameCommand();
+		mActiveRenderCommandBuffer->push_back(newCommand);
+	}
+
+	void DeferredRenderSystem::clearFrameBuffer(unsigned int buffers, 
+		const Color& color, float depth, unsigned short stencil)
+	{
+		throwIfInvalidThread();
+
+		DfrdClearFrameBufferCommand* newCommand = new DfrdClearFrameBufferCommand(buffers, color, depth, stencil);
+		mActiveRenderCommandBuffer->push_back(newCommand);
+	}
+
+	void DeferredRenderSystem::submitToGpu()
+	{
+		throwIfInvalidThread();
+
+		{
+			CM_LOCK_MUTEX(mCommandBufferMutex)
+
+			if(mReadyRenderCommandBuffer != nullptr)
+			{
+				for(auto iter = mReadyRenderCommandBuffer->begin(); iter != mReadyRenderCommandBuffer->end(); ++iter)
+					delete *iter;
+
+				delete mReadyRenderCommandBuffer;
+				mReadyRenderCommandBuffer = nullptr;
+			}
+
+			mReadyRenderCommandBuffer = mActiveRenderCommandBuffer;
+			mActiveRenderCommandBuffer = new vector<DeferredGpuCommand*>::type();
+		}
+	}
+
+	void DeferredRenderSystem::playbackCommands()
+	{
+		// TODO - Throw exception if this is not called from render thread
+		
+		vector<DeferredGpuCommand*>::type* currentCommands = nullptr;
+		{
+			CM_LOCK_MUTEX(mCommandBufferMutex)
+
+			currentCommands = mReadyRenderCommandBuffer;
+			mReadyRenderCommandBuffer = nullptr;
+		}
+
+		if(currentCommands == nullptr)
+			return;
+
+		RenderSystem* rs = RenderSystemManager::getActive();
+
+		for(auto iter = currentCommands->begin(); iter != currentCommands->end(); ++iter)
+		{
+			(*iter)->submitCommand(rs);
+			delete *iter;
+		}
+
+		delete currentCommands;
+	}
+
+	void DeferredRenderSystem::throwIfInvalidThread()
+	{
+#if CM_THREAD_SUPPORT != 0
+		if(CM_THREAD_CURRENT_ID != mMyThreadId)
+		{
+			CM_EXCEPT(InternalErrorException, "Deferred render system method called on an invalid thread.");
+		}
+#endif
+	}
 }

+ 2 - 0
CamelotRenderer/Source/CmGpuProgramParams.cpp

@@ -105,6 +105,7 @@ namespace CamelotEngine
 		// RealConstantEntry, IntConstantEntry
 		mFloatConstants = oth.mFloatConstants;
 		mIntConstants  = oth.mIntConstants;
+		mTextures = oth.mTextures;
 		mFloatLogicalToPhysical = oth.mFloatLogicalToPhysical;
 		mIntLogicalToPhysical = oth.mIntLogicalToPhysical;
 		mSamplerLogicalToPhysical = oth.mSamplerLogicalToPhysical;
@@ -877,6 +878,7 @@ namespace CamelotEngine
 		// Pull buffers & auto constant list over directly
 		mFloatConstants = source.getFloatConstantList();
 		mIntConstants = source.getIntConstantList();
+		mTextures = source.getTextureList();
 		mCombinedVariability = source.mCombinedVariability;
 	}
 }

+ 1 - 1
CamelotRenderer/Source/CmHardwareVertexBuffer.cpp

@@ -188,7 +188,7 @@ namespace CamelotEngine {
 		// Use the current render system to determine if possible
 		if (CamelotEngine::RenderSystemManager::getActive())
 		{
-			return CamelotEngine::RenderSystemManager::getActive()->getColourVertexElementType();
+			return CamelotEngine::RenderSystemManager::getActive()->getColorVertexElementType();
 		}
 		else
 		{

+ 8 - 8
CamelotRenderer/Source/CmRenderSystem.cpp

@@ -287,13 +287,13 @@ namespace CamelotEngine {
 		}
 
         // Set texture layer filtering
-        setTextureUnitFiltering(texUnit, 
+        setTextureFiltering(texUnit, 
             tl.getTextureFiltering(FT_MIN), 
             tl.getTextureFiltering(FT_MAG), 
             tl.getTextureFiltering(FT_MIP));
 
         // Set texture layer filtering
-        setTextureLayerAnisotropy(texUnit, tl.getTextureAnisotropy());
+        setTextureAnisotropy(texUnit, tl.getTextureAnisotropy());
 
 		// Set mipmap biasing
 		setTextureMipmapBias(texUnit, tl.getTextureMipmapBias());
@@ -328,12 +328,12 @@ namespace CamelotEngine {
         }
     }
     //-----------------------------------------------------------------------
-    void RenderSystem::setTextureUnitFiltering(size_t unit, FilterOptions minFilter,
+    void RenderSystem::setTextureFiltering(size_t unit, FilterOptions minFilter,
             FilterOptions magFilter, FilterOptions mipFilter)
     {
-        setTextureUnitFiltering(unit, FT_MIN, minFilter);
-        setTextureUnitFiltering(unit, FT_MAG, magFilter);
-        setTextureUnitFiltering(unit, FT_MIP, mipFilter);
+        setTextureFiltering(unit, FT_MIN, minFilter);
+        setTextureFiltering(unit, FT_MAG, magFilter);
+        setTextureFiltering(unit, FT_MIP, mipFilter);
     }
     //-----------------------------------------------------------------------
     CullingMode RenderSystem::getCullingMode(void) const
@@ -390,9 +390,9 @@ namespace CamelotEngine {
         return static_cast< unsigned int >( mVertexCount );
     }
     //-----------------------------------------------------------------------
-	void RenderSystem::convertColourValue(const Color& colour, UINT32* pDest)
+	void RenderSystem::convertColorValue(const Color& colour, UINT32* pDest)
 	{
-		*pDest = VertexElement::convertColourValue(colour, getColourVertexElementType());
+		*pDest = VertexElement::convertColourValue(colour, getColorVertexElementType());
 
 	}
     //-----------------------------------------------------------------------

+ 1 - 1
CamelotRenderer/TODO.txt

@@ -28,7 +28,7 @@ MAYBE:
 
 Essential TODO for deferred rendering:
  - Block all calls to RenderSystem outside of Render thread (or at least warn)
- - Prevent user from accessing vertex/index buffers and similar outside of render thread as well
+ - Prevent user from accessing vertex/index buffers and similar outside of render thread as well (e.g. GpuProgram, Texture)
  - Start render thread in application
 
  - Modify resource creation so it calls RenderContext and just schedules resource creation