2
0
Эх сурвалжийг харах

Refactoring how Pass/RenderSystem and other classes handle render states. Part 1

Marko Pintera 13 жил өмнө
parent
commit
0e72046097
35 өөрчлөгдсөн 617 нэмэгдсэн , 694 устгасан
  1. 1 1
      CamelotD3D11RenderSystem/Include/CmD3D11Mappings.h
  2. 6 6
      CamelotD3D11RenderSystem/Source/CmD3D11HLSLProgram.cpp
  3. 5 5
      CamelotD3D11RenderSystem/Source/CmD3D11Mappings.cpp
  4. 1 1
      CamelotD3D9Renderer/Include/CmD3D9Mappings.h
  5. 1 2
      CamelotD3D9Renderer/Include/CmD3D9RenderSystem.h
  6. 6 3
      CamelotD3D9Renderer/Source/CmD3D9HLSLProgram.cpp
  7. 5 5
      CamelotD3D9Renderer/Source/CmD3D9Mappings.cpp
  8. 81 129
      CamelotD3D9Renderer/Source/CmD3D9RenderSystem.cpp
  9. 2 2
      CamelotGLRenderer/Include/CmGLRenderSystem.h
  10. 12 11
      CamelotGLRenderer/Source/CmGLRenderSystem.cpp
  11. 1 0
      CamelotGLRenderer/Source/GLSL/src/CmGLSLLinkProgramManager.cpp
  12. 5 0
      CamelotRenderer/CamelotRenderer.vcxproj
  13. 15 0
      CamelotRenderer/CamelotRenderer.vcxproj.filters
  14. 34 4
      CamelotRenderer/Include/CmCommon.h
  15. 2 4
      CamelotRenderer/Include/CmDeferredRenderContext.h
  16. 80 0
      CamelotRenderer/Include/CmDepthStencilState.h
  17. 5 0
      CamelotRenderer/Include/CmGpuProgram.h
  18. 23 26
      CamelotRenderer/Include/CmGpuProgramParams.h
  19. 5 12
      CamelotRenderer/Include/CmMaterialRTTI.h
  20. 7 0
      CamelotRenderer/Include/CmPrerequisites.h
  21. 35 0
      CamelotRenderer/Include/CmRenderStateManager.h
  22. 5 18
      CamelotRenderer/Include/CmRenderSystem.h
  23. 84 216
      CamelotRenderer/Include/CmSamplerState.h
  24. 53 0
      CamelotRenderer/Include/CmSamplerStateRTTI.h
  25. 9 6
      CamelotRenderer/Source/CmCgProgram.cpp
  26. 3 8
      CamelotRenderer/Source/CmDeferredRenderContext.cpp
  27. 23 0
      CamelotRenderer/Source/CmDepthStencilState.cpp
  28. 3 1
      CamelotRenderer/Source/CmGpuProgram.cpp
  29. 32 32
      CamelotRenderer/Source/CmGpuProgramParams.cpp
  30. 1 1
      CamelotRenderer/Source/CmHighLevelGpuProgram.cpp
  31. 1 1
      CamelotRenderer/Source/CmMaterialRTTI.cpp
  32. 32 0
      CamelotRenderer/Source/CmRenderStateManager.cpp
  33. 2 38
      CamelotRenderer/Source/CmRenderSystem.cpp
  34. 3 0
      CamelotRenderer/Source/CmResources.cpp
  35. 34 162
      CamelotRenderer/Source/CmSamplerState.cpp

+ 1 - 1
CamelotD3D11RenderSystem/Include/CmD3D11Mappings.h

@@ -26,7 +26,7 @@ namespace CamelotEngine
 		};
 		};
 
 
 		/// return a D3D11 equivalent for a Ogre TextureAddressingMode value
 		/// return a D3D11 equivalent for a Ogre TextureAddressingMode value
-		static D3D11_TEXTURE_ADDRESS_MODE get(SamplerState::TextureAddressingMode tam);
+		static D3D11_TEXTURE_ADDRESS_MODE get(TextureAddressingMode tam);
 		/// return a D3D11 equivalent for a Ogre SceneBlendFactor value
 		/// return a D3D11 equivalent for a Ogre SceneBlendFactor value
 		static D3D11_BLEND get(SceneBlendFactor sbf);
 		static D3D11_BLEND get(SceneBlendFactor sbf);
 		/// return a D3D11 equivalent for a Ogre SceneBlendOperation value
 		/// return a D3D11 equivalent for a Ogre SceneBlendOperation value

+ 6 - 6
CamelotD3D11RenderSystem/Source/CmD3D11HLSLProgram.cpp

@@ -232,20 +232,21 @@ namespace CamelotEngine
 					if(def.isSampler())
 					if(def.isSampler())
 					{
 					{
 						def.physicalIndex = variableDesc.StartSampler;
 						def.physicalIndex = variableDesc.StartSampler;
-						CM_LOCK_MUTEX(mSamplerLogicalToPhysical->mutex)
-							mSamplerLogicalToPhysical->map.insert(
+						mSamplerLogicalToPhysical->map.insert(
 							GpuLogicalIndexUseMap::value_type(paramIndex, 
 							GpuLogicalIndexUseMap::value_type(paramIndex, 
 							GpuLogicalIndexUse(def.physicalIndex, def.arraySize, GPV_GLOBAL)));
 							GpuLogicalIndexUse(def.physicalIndex, def.arraySize, GPV_GLOBAL)));
 						mSamplerLogicalToPhysical->bufferSize = std::max(mSamplerLogicalToPhysical->bufferSize, def.physicalIndex + def.arraySize);
 						mSamplerLogicalToPhysical->bufferSize = std::max(mSamplerLogicalToPhysical->bufferSize, def.physicalIndex + def.arraySize);
 						mConstantDefs->samplerCount = mSamplerLogicalToPhysical->bufferSize;
 						mConstantDefs->samplerCount = mSamplerLogicalToPhysical->bufferSize;
+
+						// TODO - Add textures!
+						CM_EXCEPT(NotImplementedException, "Add support for texture parameters!");
 					}
 					}
 					else
 					else
 					{
 					{
 						if (def.isFloat())
 						if (def.isFloat())
 						{
 						{
 							def.physicalIndex = variableDesc.StartOffset;
 							def.physicalIndex = variableDesc.StartOffset;
-							CM_LOCK_MUTEX(mFloatLogicalToPhysical->mutex)
-								mFloatLogicalToPhysical->map.insert(
+							mFloatLogicalToPhysical->map.insert(
 								GpuLogicalIndexUseMap::value_type(paramIndex, 
 								GpuLogicalIndexUseMap::value_type(paramIndex, 
 								GpuLogicalIndexUse(def.physicalIndex, def.arraySize * def.elementSize, GPV_GLOBAL)));
 								GpuLogicalIndexUse(def.physicalIndex, def.arraySize * def.elementSize, GPV_GLOBAL)));
 							mFloatLogicalToPhysical->bufferSize = std::max(mFloatLogicalToPhysical->bufferSize, def.physicalIndex + def.arraySize);
 							mFloatLogicalToPhysical->bufferSize = std::max(mFloatLogicalToPhysical->bufferSize, def.physicalIndex + def.arraySize);
@@ -254,8 +255,7 @@ namespace CamelotEngine
 						else
 						else
 						{
 						{
 							def.physicalIndex = variableDesc.StartOffset;
 							def.physicalIndex = variableDesc.StartOffset;
-							CM_LOCK_MUTEX(mIntLogicalToPhysical->mutex)
-								mIntLogicalToPhysical->map.insert(
+							mIntLogicalToPhysical->map.insert(
 								GpuLogicalIndexUseMap::value_type(paramIndex, 
 								GpuLogicalIndexUseMap::value_type(paramIndex, 
 								GpuLogicalIndexUse(def.physicalIndex, def.arraySize * def.elementSize, GPV_GLOBAL)));
 								GpuLogicalIndexUse(def.physicalIndex, def.arraySize * def.elementSize, GPV_GLOBAL)));
 							mIntLogicalToPhysical->bufferSize = std::max(mIntLogicalToPhysical->bufferSize, def.physicalIndex + def.arraySize);
 							mIntLogicalToPhysical->bufferSize = std::max(mIntLogicalToPhysical->bufferSize, def.physicalIndex + def.arraySize);

+ 5 - 5
CamelotD3D11RenderSystem/Source/CmD3D11Mappings.cpp

@@ -4,17 +4,17 @@
 
 
 namespace CamelotEngine
 namespace CamelotEngine
 {
 {
-	D3D11_TEXTURE_ADDRESS_MODE D3D11Mappings::get(SamplerState::TextureAddressingMode tam)
+	D3D11_TEXTURE_ADDRESS_MODE D3D11Mappings::get(TextureAddressingMode tam)
 	{
 	{
 		switch( tam )
 		switch( tam )
 		{
 		{
-		case SamplerState::TAM_WRAP:
+		case TAM_WRAP:
 			return D3D11_TEXTURE_ADDRESS_WRAP;
 			return D3D11_TEXTURE_ADDRESS_WRAP;
-		case SamplerState::TAM_MIRROR:
+		case TAM_MIRROR:
 			return D3D11_TEXTURE_ADDRESS_MIRROR;
 			return D3D11_TEXTURE_ADDRESS_MIRROR;
-		case SamplerState::TAM_CLAMP:
+		case TAM_CLAMP:
 			return D3D11_TEXTURE_ADDRESS_CLAMP;
 			return D3D11_TEXTURE_ADDRESS_CLAMP;
-		case SamplerState::TAM_BORDER:
+		case TAM_BORDER:
 			return D3D11_TEXTURE_ADDRESS_BORDER;
 			return D3D11_TEXTURE_ADDRESS_BORDER;
 		}
 		}
 		return D3D11_TEXTURE_ADDRESS_MIRROR_ONCE;
 		return D3D11_TEXTURE_ADDRESS_MIRROR_ONCE;

+ 1 - 1
CamelotD3D9Renderer/Include/CmD3D9Mappings.h

@@ -64,7 +64,7 @@ namespace CamelotEngine
 		};
 		};
 
 
 		/// return a D3D9 equivalent for a Ogre TextureAddressingMode value
 		/// return a D3D9 equivalent for a Ogre TextureAddressingMode value
-		static D3DTEXTUREADDRESS get(SamplerState::TextureAddressingMode tam, const D3DCAPS9& devCaps);
+		static D3DTEXTUREADDRESS get(TextureAddressingMode tam, const D3DCAPS9& devCaps);
 		/// return a D3D9 equivalent for a Ogre SceneBlendFactor value
 		/// return a D3D9 equivalent for a Ogre SceneBlendFactor value
 		static D3DBLEND get(SceneBlendFactor sbf);
 		static D3DBLEND get(SceneBlendFactor sbf);
 		/// return a D3D9 equivlalent for a Ogre SceneBlendOperation value
 		/// return a D3D9 equivlalent for a Ogre SceneBlendOperation value

+ 1 - 2
CamelotD3D9Renderer/Include/CmD3D9RenderSystem.h

@@ -248,9 +248,8 @@ namespace CamelotEngine
 		void setPointParameters(float size, bool attenuationEnabled, 
 		void setPointParameters(float size, bool attenuationEnabled, 
 			float constant, float linear, float quadratic, float minSize, float maxSize);
 			float constant, float linear, float quadratic, float minSize, float maxSize);
 		void setTexture(UINT16 unit, bool enabled, const TexturePtr &texPtr);
 		void setTexture(UINT16 unit, bool enabled, const TexturePtr &texPtr);
-		void setVertexTexture(UINT16 unit, const TexturePtr& tex);
 		void disableTextureUnit(UINT16 texUnit);
 		void disableTextureUnit(UINT16 texUnit);
-        void setTextureAddressingMode(UINT16 stage, const SamplerState::UVWAddressingMode& uvw);
+        void setTextureAddressingMode(UINT16 stage, const UVWAddressingMode& uvw);
         void setTextureBorderColor(UINT16 stage, const Color& colour);
         void setTextureBorderColor(UINT16 stage, const Color& colour);
 		void setTextureMipmapBias(UINT16 unit, float bias);
 		void setTextureMipmapBias(UINT16 unit, float bias);
 		void setSceneBlending( SceneBlendFactor sourceFactor, SceneBlendFactor destFactor, SceneBlendOperation op );
 		void setSceneBlending( SceneBlendFactor sourceFactor, SceneBlendFactor destFactor, SceneBlendOperation op );

+ 6 - 3
CamelotD3D9Renderer/Source/CmD3D9HLSLProgram.cpp

@@ -329,19 +329,23 @@ namespace CamelotEngine {
 				if(def.isSampler())
 				if(def.isSampler())
 				{
 				{
 					def.physicalIndex = mSamplerLogicalToPhysical->bufferSize;
 					def.physicalIndex = mSamplerLogicalToPhysical->bufferSize;
-					CM_LOCK_MUTEX(mSamplerLogicalToPhysical->mutex)
 						mSamplerLogicalToPhysical->map.insert(
 						mSamplerLogicalToPhysical->map.insert(
 						GpuLogicalIndexUseMap::value_type(paramIndex, 
 						GpuLogicalIndexUseMap::value_type(paramIndex, 
 						GpuLogicalIndexUse(def.physicalIndex, def.arraySize, GPV_GLOBAL)));
 						GpuLogicalIndexUse(def.physicalIndex, def.arraySize, GPV_GLOBAL)));
 					mSamplerLogicalToPhysical->bufferSize += def.arraySize;
 					mSamplerLogicalToPhysical->bufferSize += def.arraySize;
 					mConstantDefs->samplerCount = mSamplerLogicalToPhysical->bufferSize;
 					mConstantDefs->samplerCount = mSamplerLogicalToPhysical->bufferSize;
+
+						mTextureLogicalToPhysical->map.insert(
+						GpuLogicalIndexUseMap::value_type(paramIndex, 
+						GpuLogicalIndexUse(def.physicalIndex, def.arraySize, GPV_GLOBAL)));
+					mTextureLogicalToPhysical->bufferSize += def.arraySize;
+					mConstantDefs->textureCount = mTextureLogicalToPhysical->bufferSize;
 				}
 				}
 				else
 				else
 				{
 				{
 					if (def.isFloat())
 					if (def.isFloat())
 					{
 					{
 						def.physicalIndex = mFloatLogicalToPhysical->bufferSize;
 						def.physicalIndex = mFloatLogicalToPhysical->bufferSize;
-						CM_LOCK_MUTEX(mFloatLogicalToPhysical->mutex)
 							mFloatLogicalToPhysical->map.insert(
 							mFloatLogicalToPhysical->map.insert(
 							GpuLogicalIndexUseMap::value_type(paramIndex, 
 							GpuLogicalIndexUseMap::value_type(paramIndex, 
 							GpuLogicalIndexUse(def.physicalIndex, def.arraySize * def.elementSize, GPV_GLOBAL)));
 							GpuLogicalIndexUse(def.physicalIndex, def.arraySize * def.elementSize, GPV_GLOBAL)));
@@ -351,7 +355,6 @@ namespace CamelotEngine {
 					else
 					else
 					{
 					{
 						def.physicalIndex = mIntLogicalToPhysical->bufferSize;
 						def.physicalIndex = mIntLogicalToPhysical->bufferSize;
-						CM_LOCK_MUTEX(mIntLogicalToPhysical->mutex)
 							mIntLogicalToPhysical->map.insert(
 							mIntLogicalToPhysical->map.insert(
 							GpuLogicalIndexUseMap::value_type(paramIndex, 
 							GpuLogicalIndexUseMap::value_type(paramIndex, 
 							GpuLogicalIndexUse(def.physicalIndex, def.arraySize * def.elementSize, GPV_GLOBAL)));
 							GpuLogicalIndexUse(def.physicalIndex, def.arraySize * def.elementSize, GPV_GLOBAL)));

+ 5 - 5
CamelotD3D9Renderer/Source/CmD3D9Mappings.cpp

@@ -33,17 +33,17 @@ THE SOFTWARE.
 namespace CamelotEngine 
 namespace CamelotEngine 
 {
 {
 	//---------------------------------------------------------------------
 	//---------------------------------------------------------------------
-	D3DTEXTUREADDRESS D3D9Mappings::get(SamplerState::TextureAddressingMode tam, const D3DCAPS9& devCaps)
+	D3DTEXTUREADDRESS D3D9Mappings::get(TextureAddressingMode tam, const D3DCAPS9& devCaps)
 	{
 	{
 		switch( tam )
 		switch( tam )
 		{
 		{
-		case SamplerState::TAM_WRAP:
+		case TAM_WRAP:
 			return D3DTADDRESS_WRAP;
 			return D3DTADDRESS_WRAP;
-		case SamplerState::TAM_MIRROR:
+		case TAM_MIRROR:
 			return D3DTADDRESS_MIRROR;
 			return D3DTADDRESS_MIRROR;
-		case SamplerState::TAM_CLAMP:
+		case TAM_CLAMP:
 			return D3DTADDRESS_CLAMP;
 			return D3DTADDRESS_CLAMP;
-        case SamplerState::TAM_BORDER:
+        case TAM_BORDER:
             if (devCaps.TextureAddressCaps & D3DPTADDRESSCAPS_BORDER)
             if (devCaps.TextureAddressCaps & D3DPTADDRESSCAPS_BORDER)
                 return D3DTADDRESS_BORDER;
                 return D3DTADDRESS_BORDER;
             else
             else

+ 81 - 129
CamelotD3D9Renderer/Source/CmD3D9RenderSystem.cpp

@@ -335,27 +335,37 @@ namespace CamelotEngine
 		GpuLogicalBufferStructPtr intLogical = params->getIntLogicalBufferStruct();
 		GpuLogicalBufferStructPtr intLogical = params->getIntLogicalBufferStruct();
 
 
 		GpuLogicalBufferStructPtr samplerLogical = params->getSamplerLogicalBufferStruct();
 		GpuLogicalBufferStructPtr samplerLogical = params->getSamplerLogicalBufferStruct();
+		GpuLogicalBufferStructPtr textureLogical = params->getTextureLogicalBufferStruct();
 
 
-		// Set texture sampler
+		// Set texture & sampler
 		{
 		{
-			CM_LOCK_MUTEX(samplerLogical->mutex)
-
-				for (GpuLogicalIndexUseMap::const_iterator i = samplerLogical->map.begin();
-					i != samplerLogical->map.end(); ++i)
+			for (GpuLogicalIndexUseMap::const_iterator i = samplerLogical->map.begin(); i != samplerLogical->map.end(); ++i)
+			{
+				if (i->second.variability & variability)
 				{
 				{
-					if (i->second.variability & variability)
-					{
-						UINT32 logicalIndex = i->first;
-						TextureHandle texture = params->getTexture(i->second.physicalIndex);
+					UINT32 logicalIndex = i->first;
+
+					SamplerStatePtr samplerState = params->getSamplerState(i->second.physicalIndex);
+					if(samplerState == nullptr)
+						setSamplerState(logicalIndex, SamplerState::DEFAULT);
+					else
+						setSamplerState(logicalIndex, *samplerState);
+				}
+			}
 
 
-						if(!texture.isLoaded())
-							continue;
+			for (GpuLogicalIndexUseMap::const_iterator i = textureLogical->map.begin(); i != textureLogical->map.end(); ++i)
+			{
+				if (i->second.variability & variability)
+				{
+					UINT32 logicalIndex = i->first;
+					TextureHandle texture = params->getTexture(i->second.physicalIndex);
 
 
-						const SamplerState& samplerState = params->getSamplerState(i->second.physicalIndex);
+					if(!texture.isLoaded())
+						continue;
 
 
-						setTextureUnitSettings(logicalIndex, texture.getInternalPtr(), samplerState);
-					}
+					setTexture(logicalIndex, true, texture.getInternalPtr());
 				}
 				}
+			}
 		}
 		}
 
 
 		switch(gptype)
 		switch(gptype)
@@ -363,104 +373,92 @@ namespace CamelotEngine
 		case GPT_VERTEX_PROGRAM:
 		case GPT_VERTEX_PROGRAM:
 			mActiveVertexGpuProgramParameters = params;
 			mActiveVertexGpuProgramParameters = params;
 			{
 			{
-				CM_LOCK_MUTEX(floatLogical->mutex)
-
-					for (GpuLogicalIndexUseMap::const_iterator i = floatLogical->map.begin();
-						i != floatLogical->map.end(); ++i)
+				for (GpuLogicalIndexUseMap::const_iterator i = floatLogical->map.begin();
+					i != floatLogical->map.end(); ++i)
+				{
+					if (i->second.variability & variability)
 					{
 					{
-						if (i->second.variability & variability)
+						UINT32 logicalIndex = i->first;
+						const float* pFloat = params->getFloatPointer(i->second.physicalIndex);
+						UINT32 slotCount = i->second.currentSize / 4;
+						assert (i->second.currentSize % 4 == 0 && "Should not have any "
+							"elements less than 4 wide for D3D9");
+
+						if (FAILED(hr = getActiveD3D9Device()->SetVertexShaderConstantF( // TODO Low priority. Binding parameters 1 by 1 is slow. It would be better to keep them in a sequential
+							(UINT)logicalIndex, pFloat, (UINT)slotCount)))               // buffer and then only call this method once
 						{
 						{
-							UINT32 logicalIndex = i->first;
-							const float* pFloat = params->getFloatPointer(i->second.physicalIndex);
-							UINT32 slotCount = i->second.currentSize / 4;
-							assert (i->second.currentSize % 4 == 0 && "Should not have any "
-								"elements less than 4 wide for D3D9");
-
-							if (FAILED(hr = getActiveD3D9Device()->SetVertexShaderConstantF( // TODO Low priority. Binding parameters 1 by 1 is slow. It would be better to keep them in a sequential
-								(UINT)logicalIndex, pFloat, (UINT)slotCount)))               // buffer and then only call this method once
-							{
-								CM_EXCEPT(RenderingAPIException, "Unable to upload vertex shader float parameters");
-							}
+							CM_EXCEPT(RenderingAPIException, "Unable to upload vertex shader float parameters");
 						}
 						}
-
 					}
 					}
 
 
+				}
 			}
 			}
 			// bind ints
 			// bind ints
 			{
 			{
-				CM_LOCK_MUTEX(intLogical->mutex)
-
-					for (GpuLogicalIndexUseMap::const_iterator i = intLogical->map.begin();
-						i != intLogical->map.end(); ++i)
+				for (GpuLogicalIndexUseMap::const_iterator i = intLogical->map.begin();
+					i != intLogical->map.end(); ++i)
+				{
+					if (i->second.variability & variability)
 					{
 					{
-						if (i->second.variability & variability)
+						UINT32 logicalIndex = i->first;
+						const int* pInt = params->getIntPointer(i->second.physicalIndex);
+						UINT32 slotCount = i->second.currentSize / 4;
+						assert (i->second.currentSize % 4 == 0 && "Should not have any "
+							"elements less than 4 wide for D3D9");
+
+						if (FAILED(hr = getActiveD3D9Device()->SetVertexShaderConstantI(
+							static_cast<UINT>(logicalIndex), pInt, static_cast<UINT>(slotCount))))
 						{
 						{
-							UINT32 logicalIndex = i->first;
-							const int* pInt = params->getIntPointer(i->second.physicalIndex);
-							UINT32 slotCount = i->second.currentSize / 4;
-							assert (i->second.currentSize % 4 == 0 && "Should not have any "
-								"elements less than 4 wide for D3D9");
-
-							if (FAILED(hr = getActiveD3D9Device()->SetVertexShaderConstantI(
-								static_cast<UINT>(logicalIndex), pInt, static_cast<UINT>(slotCount))))
-							{
-								CM_EXCEPT(RenderingAPIException, "Unable to upload vertex shader int parameters");
-							}
+							CM_EXCEPT(RenderingAPIException, "Unable to upload vertex shader int parameters");
 						}
 						}
 					}
 					}
-
+				}
 			}
 			}
 
 
 			break;
 			break;
 		case GPT_FRAGMENT_PROGRAM:
 		case GPT_FRAGMENT_PROGRAM:
 			mActiveFragmentGpuProgramParameters = params;
 			mActiveFragmentGpuProgramParameters = params;
 			{
 			{
-				CM_LOCK_MUTEX(floatLogical->mutex)
-
-					for (GpuLogicalIndexUseMap::const_iterator i = floatLogical->map.begin();
-						i != floatLogical->map.end(); ++i)
+				for (GpuLogicalIndexUseMap::const_iterator i = floatLogical->map.begin();
+					i != floatLogical->map.end(); ++i)
+				{
+					if (i->second.variability & variability)
 					{
 					{
-						if (i->second.variability & variability)
+						UINT32 logicalIndex = i->first;
+						const float* pFloat = params->getFloatPointer(i->second.physicalIndex);
+						UINT32 slotCount = i->second.currentSize / 4;
+						assert (i->second.currentSize % 4 == 0 && "Should not have any "
+							"elements less than 4 wide for D3D9");
+
+						if (FAILED(hr = getActiveD3D9Device()->SetPixelShaderConstantF(
+							static_cast<UINT>(logicalIndex), pFloat, static_cast<UINT>(slotCount))))
 						{
 						{
-							UINT32 logicalIndex = i->first;
-							const float* pFloat = params->getFloatPointer(i->second.physicalIndex);
-							UINT32 slotCount = i->second.currentSize / 4;
-							assert (i->second.currentSize % 4 == 0 && "Should not have any "
-								"elements less than 4 wide for D3D9");
-
-							if (FAILED(hr = getActiveD3D9Device()->SetPixelShaderConstantF(
-								static_cast<UINT>(logicalIndex), pFloat, static_cast<UINT>(slotCount))))
-							{
-								CM_EXCEPT(RenderingAPIException, "Unable to upload pixel shader float parameters");
-							}
+							CM_EXCEPT(RenderingAPIException, "Unable to upload pixel shader float parameters");
 						}
 						}
 					}
 					}
-
+				}
 			}
 			}
 			// bind ints
 			// bind ints
 			{
 			{
-				CM_LOCK_MUTEX(intLogical->mutex)
-
-					for (GpuLogicalIndexUseMap::const_iterator i = intLogical->map.begin();
-						i != intLogical->map.end(); ++i)
+				for (GpuLogicalIndexUseMap::const_iterator i = intLogical->map.begin();
+					i != intLogical->map.end(); ++i)
+				{
+					if (i->second.variability & variability)
 					{
 					{
-						if (i->second.variability & variability)
+						UINT32 logicalIndex = i->first;
+						const int* pInt = params->getIntPointer(i->second.physicalIndex);
+						UINT32 slotCount = i->second.currentSize / 4;
+						assert (i->second.currentSize % 4 == 0 && "Should not have any "
+							"elements less than 4 wide for D3D9");
+
+						if (FAILED(hr = getActiveD3D9Device()->SetPixelShaderConstantI(
+							static_cast<UINT>(logicalIndex), pInt, static_cast<UINT>(slotCount))))
 						{
 						{
-							UINT32 logicalIndex = i->first;
-							const int* pInt = params->getIntPointer(i->second.physicalIndex);
-							UINT32 slotCount = i->second.currentSize / 4;
-							assert (i->second.currentSize % 4 == 0 && "Should not have any "
-								"elements less than 4 wide for D3D9");
-
-							if (FAILED(hr = getActiveD3D9Device()->SetPixelShaderConstantI(
-								static_cast<UINT>(logicalIndex), pInt, static_cast<UINT>(slotCount))))
-							{
-								CM_EXCEPT(RenderingAPIException, "Unable to upload pixel shader int parameters");
-							}
+							CM_EXCEPT(RenderingAPIException, "Unable to upload pixel shader int parameters");
 						}
 						}
-
 					}
 					}
 
 
+				}
 			}
 			}
 			break;
 			break;
 		};
 		};
@@ -577,57 +575,11 @@ namespace CamelotEngine
 		}
 		}
 	}
 	}
 	//---------------------------------------------------------------------
 	//---------------------------------------------------------------------
-	void D3D9RenderSystem::setVertexTexture(UINT16 stage, const TexturePtr& tex)
-	{
-		THROW_IF_NOT_RENDER_THREAD;
-
-		if (tex == nullptr)
-		{
-
-			if (mTexStageDesc[stage].pVertexTex != 0)
-			{
-				HRESULT hr = getActiveD3D9Device()->SetTexture(D3DVERTEXTEXTURESAMPLER0 + static_cast<DWORD>(stage), 0);
-				if( hr != S_OK )
-				{
-					String str = "Unable to disable vertex texture '" 
-						+ toString(stage) + "' in D3D9";
-					CM_EXCEPT(RenderingAPIException, str);
-				}
-			}
-
-			// set stage desc. to defaults
-			mTexStageDesc[stage].pVertexTex = 0;
-		}
-		else
-		{
-			D3D9TexturePtr dt = std::static_pointer_cast<D3D9Texture>(tex);
-
-			IDirect3DBaseTexture9 *pTex = dt->getTexture_internal();
-			if (mTexStageDesc[stage].pVertexTex != pTex)
-			{
-				HRESULT hr = getActiveD3D9Device()->SetTexture(D3DVERTEXTEXTURESAMPLER0 + static_cast<DWORD>(stage), pTex);
-				if( hr != S_OK )
-				{
-					String str = "Unable to set vertex texture in D3D9";
-					CM_EXCEPT(RenderingAPIException, str);
-				}
-
-				// set stage desc.
-				mTexStageDesc[stage].pVertexTex = pTex;
-			}
-
-		}
-
-	}
-	//---------------------------------------------------------------------
 	void D3D9RenderSystem::disableTextureUnit(UINT16 texUnit)
 	void D3D9RenderSystem::disableTextureUnit(UINT16 texUnit)
 	{
 	{
 		THROW_IF_NOT_RENDER_THREAD;
 		THROW_IF_NOT_RENDER_THREAD;
 
 
 		RenderSystem::disableTextureUnit(texUnit);
 		RenderSystem::disableTextureUnit(texUnit);
-		// also disable vertex texture unit
-		static TexturePtr nullPtr;
-		setVertexTexture(texUnit, nullPtr);
 	}
 	}
 	//---------------------------------------------------------------------
 	//---------------------------------------------------------------------
 	void D3D9RenderSystem::setTextureMipmapBias(UINT16 unit, float bias)
 	void D3D9RenderSystem::setTextureMipmapBias(UINT16 unit, float bias)
@@ -646,7 +598,7 @@ namespace CamelotEngine
 	}
 	}
 	//---------------------------------------------------------------------
 	//---------------------------------------------------------------------
 	void D3D9RenderSystem::setTextureAddressingMode( UINT16 stage, 
 	void D3D9RenderSystem::setTextureAddressingMode( UINT16 stage, 
-		const SamplerState::UVWAddressingMode& uvw )
+		const UVWAddressingMode& uvw )
 	{
 	{
 		THROW_IF_NOT_RENDER_THREAD;
 		THROW_IF_NOT_RENDER_THREAD;
 
 

+ 2 - 2
CamelotGLRenderer/Include/CmGLRenderSystem.h

@@ -72,7 +72,7 @@ namespace CamelotEngine {
         void makeGLMatrix(GLfloat gl_matrix[16], const Matrix4& m);
         void makeGLMatrix(GLfloat gl_matrix[16], const Matrix4& m);
  
  
         GLint getBlendMode(SceneBlendFactor ogreBlend) const;
         GLint getBlendMode(SceneBlendFactor ogreBlend) const;
-		GLint getTextureAddressingMode(SamplerState::TextureAddressingMode tam) const;
+		GLint getTextureAddressingMode(TextureAddressingMode tam) const;
 		void initialiseContext(RenderWindow* primary);
 		void initialiseContext(RenderWindow* primary);
 
 
 		/** See
 		/** See
@@ -227,7 +227,7 @@ namespace CamelotEngine {
         /** See
         /** See
           RenderSystem
           RenderSystem
          */
          */
-        void setTextureAddressingMode(UINT16 stage, const SamplerState::UVWAddressingMode& uvw);
+        void setTextureAddressingMode(UINT16 stage, const UVWAddressingMode& uvw);
         /** See
         /** See
           RenderSystem
           RenderSystem
          */
          */

+ 12 - 11
CamelotGLRenderer/Source/CmGLRenderSystem.cpp

@@ -342,8 +342,7 @@ namespace CamelotEngine {
 
 
 			if(def.variability & mask)
 			if(def.variability & mask)
 			{
 			{
-				if(def.constType == GCT_SAMPLER2D || def.constType == GCT_SAMPLERCUBE || def.constType == GCT_SAMPLER1D 
-					|| def.constType == GCT_SAMPLER2DSHADOW || def.constType == GCT_SAMPLER3D || def.constType == GCT_SAMPLER1DSHADOW)
+				if(def.isSampler())
 				{
 				{
 					TextureHandle curTexture = params->getTexture(def.physicalIndex);
 					TextureHandle curTexture = params->getTexture(def.physicalIndex);
 
 
@@ -352,9 +351,11 @@ namespace CamelotEngine {
 
 
 					setTexture(def.physicalIndex, true, curTexture.getInternalPtr());
 					setTexture(def.physicalIndex, true, curTexture.getInternalPtr());
 
 
-					const SamplerState& samplerState = params->getSamplerState(def.physicalIndex);
-
-					setTextureUnitSettings(def.physicalIndex, curTexture.getInternalPtr(), samplerState);
+					SamplerStatePtr samplerState = params->getSamplerState(def.physicalIndex);
+					if(samplerState == nullptr)
+						setSamplerState(def.physicalIndex, SamplerState::DEFAULT);
+					else
+						setSamplerState(def.physicalIndex, *samplerState);
 				}
 				}
 			}
 			}
 		}
 		}
@@ -503,7 +504,7 @@ namespace CamelotEngine {
 		activateGLTextureUnit(0);
 		activateGLTextureUnit(0);
 	}
 	}
 	//-----------------------------------------------------------------------------
 	//-----------------------------------------------------------------------------
-	void GLRenderSystem::setTextureAddressingMode(UINT16 stage, const SamplerState::UVWAddressingMode& uvw)
+	void GLRenderSystem::setTextureAddressingMode(UINT16 stage, const UVWAddressingMode& uvw)
 	{
 	{
 		THROW_IF_NOT_RENDER_THREAD;
 		THROW_IF_NOT_RENDER_THREAD;
 
 
@@ -1781,18 +1782,18 @@ namespace CamelotEngine {
 	}
 	}
 	//-----------------------------------------------------------------------------
 	//-----------------------------------------------------------------------------
 	GLint GLRenderSystem::getTextureAddressingMode(
 	GLint GLRenderSystem::getTextureAddressingMode(
-		SamplerState::TextureAddressingMode tam) const
+		TextureAddressingMode tam) const
 	{
 	{
 		switch(tam)
 		switch(tam)
 		{
 		{
 		default:
 		default:
-		case SamplerState::TAM_WRAP:
+		case TAM_WRAP:
 			return GL_REPEAT;
 			return GL_REPEAT;
-		case SamplerState::TAM_MIRROR:
+		case TAM_MIRROR:
 			return GL_MIRRORED_REPEAT;
 			return GL_MIRRORED_REPEAT;
-		case SamplerState::TAM_CLAMP:
+		case TAM_CLAMP:
 			return GL_CLAMP_TO_EDGE;
 			return GL_CLAMP_TO_EDGE;
-		case SamplerState::TAM_BORDER:
+		case TAM_BORDER:
 			return GL_CLAMP_TO_BORDER;
 			return GL_CLAMP_TO_BORDER;
 		}
 		}
 
 

+ 1 - 0
CamelotGLRenderer/Source/GLSL/src/CmGLSLLinkProgramManager.cpp

@@ -482,6 +482,7 @@ namespace CamelotEngine {
 						{
 						{
 							def.physicalIndex = defs.samplerCount;
 							def.physicalIndex = defs.samplerCount;
 							defs.samplerCount++;
 							defs.samplerCount++;
+							defs.textureCount++;
 						}
 						}
 						else
 						else
 						{
 						{

+ 5 - 0
CamelotRenderer/CamelotRenderer.vcxproj

@@ -188,6 +188,7 @@
     <ClInclude Include="Include\CmConfigOptionMap.h" />
     <ClInclude Include="Include\CmConfigOptionMap.h" />
     <ClInclude Include="Include\CmDefaultHardwareBufferManager.h" />
     <ClInclude Include="Include\CmDefaultHardwareBufferManager.h" />
     <ClInclude Include="Include\CmDeferredRenderContext.h" />
     <ClInclude Include="Include\CmDeferredRenderContext.h" />
+    <ClInclude Include="Include\CmDepthStencilState.h" />
     <ClInclude Include="Include\CmGpuProgram.h" />
     <ClInclude Include="Include\CmGpuProgram.h" />
     <ClInclude Include="Include\CmGpuProgramManager.h" />
     <ClInclude Include="Include\CmGpuProgramManager.h" />
     <ClInclude Include="Include\CmGpuProgramParams.h" />
     <ClInclude Include="Include\CmGpuProgramParams.h" />
@@ -219,6 +220,7 @@
     <ClInclude Include="Include\CmRendererFactory.h" />
     <ClInclude Include="Include\CmRendererFactory.h" />
     <ClInclude Include="Include\CmRendererManager.h" />
     <ClInclude Include="Include\CmRendererManager.h" />
     <ClInclude Include="Include\CmRenderOperation.h" />
     <ClInclude Include="Include\CmRenderOperation.h" />
+    <ClInclude Include="Include\CmRenderStateManager.h" />
     <ClInclude Include="Include\CmRenderSystem.h" />
     <ClInclude Include="Include\CmRenderSystem.h" />
     <ClInclude Include="Include\CmRenderSystemCapabilities.h" />
     <ClInclude Include="Include\CmRenderSystemCapabilities.h" />
     <ClInclude Include="Include\CmRenderSystemFactory.h" />
     <ClInclude Include="Include\CmRenderSystemFactory.h" />
@@ -231,6 +233,7 @@
     <ClInclude Include="Include\CmResourceHandleRTTI.h" />
     <ClInclude Include="Include\CmResourceHandleRTTI.h" />
     <ClInclude Include="Include\CmResources.h" />
     <ClInclude Include="Include\CmResources.h" />
     <ClInclude Include="Include\CmResourcesRTTI.h" />
     <ClInclude Include="Include\CmResourcesRTTI.h" />
+    <ClInclude Include="Include\CmSamplerStateRTTI.h" />
     <ClInclude Include="Include\CmSceneManager.h" />
     <ClInclude Include="Include\CmSceneManager.h" />
     <ClInclude Include="Include\CmShaderRTTI.h" />
     <ClInclude Include="Include\CmShaderRTTI.h" />
     <ClInclude Include="Include\CmSpecificImporter.h" />
     <ClInclude Include="Include\CmSpecificImporter.h" />
@@ -262,6 +265,7 @@
     <ClCompile Include="Source\CmCommandQueue.cpp" />
     <ClCompile Include="Source\CmCommandQueue.cpp" />
     <ClCompile Include="Source\CmDefaultHardwareBufferManager.cpp" />
     <ClCompile Include="Source\CmDefaultHardwareBufferManager.cpp" />
     <ClCompile Include="Source\CmDeferredRenderContext.cpp" />
     <ClCompile Include="Source\CmDeferredRenderContext.cpp" />
+    <ClCompile Include="Source\CmDepthStencilState.cpp" />
     <ClCompile Include="Source\CmGpuProgram.cpp" />
     <ClCompile Include="Source\CmGpuProgram.cpp" />
     <ClCompile Include="Source\CmGpuProgramManager.cpp" />
     <ClCompile Include="Source\CmGpuProgramManager.cpp" />
     <ClCompile Include="Source\CmGpuProgramParams.cpp" />
     <ClCompile Include="Source\CmGpuProgramParams.cpp" />
@@ -291,6 +295,7 @@
     <ClCompile Include="Source\CmResource.cpp" />
     <ClCompile Include="Source\CmResource.cpp" />
     <ClCompile Include="Source\CmResourceHandle.cpp" />
     <ClCompile Include="Source\CmResourceHandle.cpp" />
     <ClCompile Include="Source\CmResources.cpp" />
     <ClCompile Include="Source\CmResources.cpp" />
+    <ClCompile Include="Source\CmRenderStateManager.cpp" />
     <ClCompile Include="Source\CmSceneManager.cpp" />
     <ClCompile Include="Source\CmSceneManager.cpp" />
     <ClCompile Include="Source\CmShader.cpp" />
     <ClCompile Include="Source\CmShader.cpp" />
     <ClCompile Include="Source\CmSpecificImporter.cpp" />
     <ClCompile Include="Source\CmSpecificImporter.cpp" />

+ 15 - 0
CamelotRenderer/CamelotRenderer.vcxproj.filters

@@ -317,6 +317,15 @@
     <ClInclude Include="Include\CmDeferredRenderContext.h">
     <ClInclude Include="Include\CmDeferredRenderContext.h">
       <Filter>Header Files\RenderSystem</Filter>
       <Filter>Header Files\RenderSystem</Filter>
     </ClInclude>
     </ClInclude>
+    <ClInclude Include="Include\CmDepthStencilState.h">
+      <Filter>Header Files\RenderSystem</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\CmRenderStateManager.h">
+      <Filter>Header Files\RenderSystem</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\CmSamplerStateRTTI.h">
+      <Filter>Header Files\RTTI</Filter>
+    </ClInclude>
   </ItemGroup>
   </ItemGroup>
   <ItemGroup>
   <ItemGroup>
     <ClCompile Include="Source\CamelotRenderer.cpp">
     <ClCompile Include="Source\CamelotRenderer.cpp">
@@ -472,5 +481,11 @@
     <ClCompile Include="Source\CmDeferredRenderContext.cpp">
     <ClCompile Include="Source\CmDeferredRenderContext.cpp">
       <Filter>Source Files\RenderSystem</Filter>
       <Filter>Source Files\RenderSystem</Filter>
     </ClCompile>
     </ClCompile>
+    <ClCompile Include="Source\CmDepthStencilState.cpp">
+      <Filter>Source Files\RenderSystem</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\CmRenderStateManager.cpp">
+      <Filter>Source Files\RenderSystem</Filter>
+    </ClCompile>
   </ItemGroup>
   </ItemGroup>
 </Project>
 </Project>

+ 34 - 4
CamelotRenderer/Include/CmCommon.h

@@ -96,6 +96,23 @@ namespace CamelotEngine {
         CMPF_GREATER
         CMPF_GREATER
     };
     };
 
 
+    /** Texture addressing modes - default is TAM_WRAP.
+    @note
+        These settings are relevant in both the fixed-function and the
+        programmable pipeline.
+    */
+    enum TextureAddressingMode
+    {
+        /// Texture wraps at values over 1.0
+        TAM_WRAP,
+        /// Texture mirrors (flips) at joins over 1.0
+        TAM_MIRROR,
+        /// Texture clamps at 1.0
+        TAM_CLAMP,
+        /// Texture coordinates outside the range [0.0, 1.0] are set to the border colour
+        TAM_BORDER
+    };
+
     /** High-level filtering options providing shortcuts to settings the
     /** High-level filtering options providing shortcuts to settings the
         minification, magnification and mip filters. */
         minification, magnification and mip filters. */
     enum TextureFilterOptions
     enum TextureFilterOptions
@@ -123,13 +140,16 @@ namespace CamelotEngine {
     enum FilterOptions
     enum FilterOptions
     {
     {
         /// No filtering, used for FILT_MIP to turn off mipmapping
         /// No filtering, used for FILT_MIP to turn off mipmapping
-        FO_NONE,
+        FO_NONE = 0,
         /// Use the closest pixel
         /// Use the closest pixel
-        FO_POINT,
+        FO_POINT = 1,
         /// Average of a 2x2 pixel area, denotes bilinear for MIN and MAG, trilinear for MIP
         /// Average of a 2x2 pixel area, denotes bilinear for MIN and MAG, trilinear for MIP
-        FO_LINEAR,
+        FO_LINEAR = 2,
         /// Similar to FO_LINEAR, but compensates for the angle of the texture plane
         /// Similar to FO_LINEAR, but compensates for the angle of the texture plane
-        FO_ANISOTROPIC
+        FO_ANISOTROPIC = 3,
+		/// Specifies that the sampled values will be compared against existing sampled data. 
+		/// Should be OR-ed with other filtering options.
+		FO_USE_COMPARISON = 4
     };
     };
 
 
     /** Hardware culling modes based on vertex winding.
     /** Hardware culling modes based on vertex winding.
@@ -182,6 +202,16 @@ namespace CamelotEngine {
 		/// Invert the bits of the stencil buffer
 		/// Invert the bits of the stencil buffer
 		SOP_INVERT
 		SOP_INVERT
 	};
 	};
+
+	/** Texture addressing mode for each texture coordinate. */
+	struct UVWAddressingMode
+	{
+		UVWAddressingMode()
+			:u(TAM_WRAP), v(TAM_WRAP), w(TAM_WRAP)
+		{ }
+
+		TextureAddressingMode u, v, w;
+	};
     
     
 	/// Name / value parameter pair (first = name, second = value)
 	/// Name / value parameter pair (first = name, second = value)
 	typedef map<String, String>::type NameValuePairList;
 	typedef map<String, String>::type NameValuePairList;

+ 2 - 4
CamelotRenderer/Include/CmDeferredRenderContext.h

@@ -27,7 +27,7 @@ namespace CamelotEngine
 
 
 
 
 		/** @copydoc RenderSystem::setTextureUnitSettings() */
 		/** @copydoc RenderSystem::setTextureUnitSettings() */
-		void setTextureUnitSettings(UINT16 texUnit, const TexturePtr& texture, const SamplerState& samplerState);
+		void setSamplerState(UINT16 texUnit, const SamplerState& samplerState);
 		/** @copydoc RenderSystem::disableTextureUnit() */
 		/** @copydoc RenderSystem::disableTextureUnit() */
 		void disableTextureUnit(UINT16 texUnit);
 		void disableTextureUnit(UINT16 texUnit);
 		/** @copydoc RenderSystem::disableTextureUnitsFrom() */
 		/** @copydoc RenderSystem::disableTextureUnitsFrom() */
@@ -38,8 +38,6 @@ namespace CamelotEngine
 
 
 		/** @copydoc RenderSystem::setTexture() */
 		/** @copydoc RenderSystem::setTexture() */
 		void setTexture(UINT16 unit, bool enabled, const TexturePtr &texPtr);
 		void setTexture(UINT16 unit, bool enabled, const TexturePtr &texPtr);
-		/** @copydoc RenderSystem::setVertexTexture() */
-		void setVertexTexture(UINT16 unit, const TexturePtr& tex);
 
 
 		/** @copydoc RenderSystem::setTextureFiltering() */
 		/** @copydoc RenderSystem::setTextureFiltering() */
 		void setTextureFiltering(UINT16 unit, FilterOptions minFilter, FilterOptions magFilter, FilterOptions mipFilter);
 		void setTextureFiltering(UINT16 unit, FilterOptions minFilter, FilterOptions magFilter, FilterOptions mipFilter);
@@ -48,7 +46,7 @@ namespace CamelotEngine
 		/** @copydoc RenderSystem::setTextureAnisotropy() */
 		/** @copydoc RenderSystem::setTextureAnisotropy() */
 		void setTextureAnisotropy(UINT16 unit, unsigned int maxAnisotropy);
 		void setTextureAnisotropy(UINT16 unit, unsigned int maxAnisotropy);
 		/** @copydoc RenderSystem::setTextureAddressingMode() */
 		/** @copydoc RenderSystem::setTextureAddressingMode() */
-		void setTextureAddressingMode(UINT16 unit, const SamplerState::UVWAddressingMode& uvw);
+		void setTextureAddressingMode(UINT16 unit, const UVWAddressingMode& uvw);
 		/** @copydoc RenderSystem::setTextureBorderColor() */
 		/** @copydoc RenderSystem::setTextureBorderColor() */
 		void setTextureBorderColor(UINT16 unit, const Color& color);
 		void setTextureBorderColor(UINT16 unit, const Color& color);
 		/** @copydoc RenderSystem::setTextureMipmapBias() */
 		/** @copydoc RenderSystem::setTextureMipmapBias() */

+ 80 - 0
CamelotRenderer/Include/CmDepthStencilState.h

@@ -0,0 +1,80 @@
+#pragma once
+
+#include "CmPrerequisites.h"
+#include "CmCommon.h"
+
+namespace CamelotEngine
+{
+	struct DEPTH_STENCIL_DESC
+	{
+		DEPTH_STENCIL_DESC()
+			: depthReadEnable(true)
+			, depthWriteEnable(true)
+			, depthComparisonFunc(CMPF_LESS)
+			, stencilEnable(false)
+			, stencilReadMask(0xFF)
+			, stencilWriteMask(0xFF)
+			, frontStencilFailOp(SOP_KEEP)
+			, frontStencilZFailOp(SOP_KEEP)
+			, frontStencilPassOp(SOP_KEEP)
+			, frontStencilComparisonFunc(CMPF_ALWAYS_PASS)
+			, backStencilFailOp(SOP_KEEP)
+			, backStencilZFailOp(SOP_KEEP)
+			, backStencilPassOp(SOP_KEEP)
+			, backStencilComparisonFunc(CMPF_ALWAYS_PASS)
+		{ }
+
+		bool depthReadEnable;
+		bool depthWriteEnable;
+		CompareFunction depthComparisonFunc;
+
+		bool stencilEnable;
+		UINT8 stencilReadMask;
+		UINT8 stencilWriteMask;
+
+		StencilOperation frontStencilFailOp;
+		StencilOperation frontStencilZFailOp;
+		StencilOperation frontStencilPassOp;
+		CompareFunction frontStencilComparisonFunc;
+
+		StencilOperation backStencilFailOp;
+		StencilOperation backStencilZFailOp;
+		StencilOperation backStencilPassOp;
+		CompareFunction backStencilComparisonFunc;
+	};
+
+	class CM_EXPORT DepthStencilState
+	{
+	public:
+		bool getDepthReadEnable() const { return mData.depthReadEnable; }
+		bool getDepthWriteEnable() const { return mData.depthWriteEnable; }
+		CompareFunction getDepthComparisonFunc() const { return mData.depthComparisonFunc; }
+
+		bool getStencilEnable() const { return mData.stencilEnable; }
+		UINT8 getStencilReadMask() const { return mData.stencilReadMask; }
+		UINT8 getStencilWriteMask() const { return mData.stencilWriteMask; }
+
+		StencilOperation getStencilFrontFailOp() const { return mData.frontStencilFailOp; }
+		StencilOperation getStencilFrontZFailOp() const { return mData.frontStencilZFailOp; }
+		StencilOperation getStencilFrontPassOp() const { return mData.frontStencilPassOp; }
+		CompareFunction getStencilFrontCompFunc() const { return mData.frontStencilComparisonFunc; }
+
+		StencilOperation getStencilBackFailOp() const { return mData.backStencilFailOp; }
+		StencilOperation getStencilBackZFailOp() const { return mData.backStencilZFailOp; }
+		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_DESC& desc);
+	private:
+		friend class RenderStateManager;
+		DepthStencilState();
+
+		virtual void initialize(const DEPTH_STENCIL_DESC& desc);
+
+		DEPTH_STENCIL_DESC mData;
+		UINT32 mStencilRefValue;
+	};
+}

+ 5 - 0
CamelotRenderer/Include/CmGpuProgram.h

@@ -95,6 +95,11 @@ namespace CamelotEngine {
 			This is a shared pointer because if the program is recompiled and the parameters
 			This is a shared pointer because if the program is recompiled and the parameters
 			change, this definition will alter, but previous params may reference the old def.*/
 			change, this definition will alter, but previous params may reference the old def.*/
 		mutable GpuLogicalBufferStructPtr mSamplerLogicalToPhysical;
 		mutable GpuLogicalBufferStructPtr mSamplerLogicalToPhysical;
+		/** Record of logical to physical buffer maps. Mandatory for low-level
+			programs or high-level programs which set their params the same way. 
+			This is a shared pointer because if the program is recompiled and the parameters
+			change, this definition will alter, but previous params may reference the old def.*/
+		mutable GpuLogicalBufferStructPtr mTextureLogicalToPhysical;
 		/** Parameter name -> ConstantDefinition map, shared instance used by all parameter objects.
 		/** Parameter name -> ConstantDefinition map, shared instance used by all parameter objects.
 		This is a shared pointer because if the program is recompiled and the parameters
 		This is a shared pointer because if the program is recompiled and the parameters
 		change, this definition will alter, but previous params may reference the old def.
 		change, this definition will alter, but previous params may reference the old def.

+ 23 - 26
CamelotRenderer/Include/CmGpuProgramParams.h

@@ -264,10 +264,13 @@ namespace CamelotEngine {
 		UINT32 intBufferSize;
 		UINT32 intBufferSize;
 		/// Total number of samplers referenced
 		/// Total number of samplers referenced
 		UINT32 samplerCount;
 		UINT32 samplerCount;
+		/// Total number of textures references
+		UINT32 textureCount;
 		/// Map of parameter names to GpuConstantDefinition
 		/// Map of parameter names to GpuConstantDefinition
 		GpuConstantDefinitionMap map;
 		GpuConstantDefinitionMap map;
 
 
-		GpuNamedConstants() : floatBufferSize(0), intBufferSize(0), samplerCount(0) {}
+		GpuNamedConstants() : floatBufferSize(0), intBufferSize(0), 
+			samplerCount(0), textureCount(0) {}
 
 
 		/** Generate additional constant entries for arrays based on a base definition.
 		/** Generate additional constant entries for arrays based on a base definition.
 		@remarks
 		@remarks
@@ -326,26 +329,14 @@ namespace CamelotEngine {
 	/// Container struct to allow params to safely & update shared list of logical buffer assignments
 	/// Container struct to allow params to safely & update shared list of logical buffer assignments
 	struct CM_EXPORT GpuLogicalBufferStruct
 	struct CM_EXPORT GpuLogicalBufferStruct
 	{
 	{
-		CM_MUTEX(mutex)
-			/// Map from logical index to physical buffer location
-			GpuLogicalIndexUseMap map;
+		/// Map from logical index to physical buffer location
+		GpuLogicalIndexUseMap map;
 		/// Shortcut to know the buffer size needs
 		/// Shortcut to know the buffer size needs
 		UINT32 bufferSize;
 		UINT32 bufferSize;
 		GpuLogicalBufferStruct() : bufferSize(0) {}
 		GpuLogicalBufferStruct() : bufferSize(0) {}
 	};
 	};
 	typedef std::shared_ptr<GpuLogicalBufferStruct> GpuLogicalBufferStructPtr;
 	typedef std::shared_ptr<GpuLogicalBufferStruct> GpuLogicalBufferStructPtr;
 
 
-	/**
-	 * @brief	Contains a reference to a texture together with it's sampler properties
-	 */
-	struct GpuTextureEntry
-	{
-		TextureHandle texture;
-		SamplerState samplerState;
-	};
-
-	typedef std::shared_ptr<GpuTextureEntry> GpuTextureEntryPtr;
-
 	/** Definition of container that holds the current float constants.
 	/** Definition of container that holds the current float constants.
 	@note Not necessarily in direct index order to constant indexes, logical
 	@note Not necessarily in direct index order to constant indexes, logical
 	to physical index map is derived from GpuProgram
 	to physical index map is derived from GpuProgram
@@ -356,11 +347,6 @@ namespace CamelotEngine {
 	to physical index map is derived from GpuProgram
 	to physical index map is derived from GpuProgram
 	*/
 	*/
 	typedef vector<int>::type IntConstantList;
 	typedef vector<int>::type IntConstantList;
-	/** Definition of container that holds the current float constants.
-	@note Not necessarily in direct index order to constant indexes, logical
-	to physical index map is derived from GpuProgram
-	*/
-	typedef vector<GpuTextureEntryPtr>::type TextureList;
 
 
 	/** Collects together the program parameters used for a GpuProgram.
 	/** Collects together the program parameters used for a GpuProgram.
 	@remarks
 	@remarks
@@ -420,7 +406,9 @@ namespace CamelotEngine {
 		/// Packed list of integer constants (physical indexing)
 		/// Packed list of integer constants (physical indexing)
 		IntConstantList mIntConstants;
 		IntConstantList mIntConstants;
 		/// List of all texture parameters
 		/// List of all texture parameters
-		TextureList mTextures;
+		vector<TextureHandle>::type mTextures;
+		// List of all sampler states
+		vector<SamplerStatePtr>::type mSamplerStates;
 		/** Logical index to physical index map - for low-level programs
 		/** Logical index to physical index map - for low-level programs
 		or high-level programs which pass params this way. */
 		or high-level programs which pass params this way. */
 		GpuLogicalBufferStructPtr mFloatLogicalToPhysical;
 		GpuLogicalBufferStructPtr mFloatLogicalToPhysical;
@@ -429,6 +417,9 @@ namespace CamelotEngine {
 		GpuLogicalBufferStructPtr mIntLogicalToPhysical;
 		GpuLogicalBufferStructPtr mIntLogicalToPhysical;
 		/** Logical index to physical index map - for low-level programs
 		/** Logical index to physical index map - for low-level programs
 		or high-level programs which pass params this way. */
 		or high-level programs which pass params this way. */
+		GpuLogicalBufferStructPtr mTextureLogicalToPhysical;
+		/** Logical index to physical index map - for low-level programs
+		or high-level programs which pass params this way. */
 		GpuLogicalBufferStructPtr mSamplerLogicalToPhysical;
 		GpuLogicalBufferStructPtr mSamplerLogicalToPhysical;
 		/// Mapping from parameter names to def - high-level programs are expected to populate this
 		/// Mapping from parameter names to def - high-level programs are expected to populate this
 		GpuNamedConstantsPtr mNamedConstants;
 		GpuNamedConstantsPtr mNamedConstants;
@@ -460,7 +451,10 @@ namespace CamelotEngine {
 
 
 		/** Internal method for providing a link to a logical index->physical index map for parameters. */
 		/** Internal method for providing a link to a logical index->physical index map for parameters. */
 		void _setLogicalIndexes(const GpuLogicalBufferStructPtr& floatIndexMap, 
 		void _setLogicalIndexes(const GpuLogicalBufferStructPtr& floatIndexMap, 
-			const GpuLogicalBufferStructPtr&  intIndexMap, const GpuLogicalBufferStructPtr& samplerIndexMap);
+			const GpuLogicalBufferStructPtr& intIndexMap, 
+			const GpuLogicalBufferStructPtr& samplerIndexMap,
+			const GpuLogicalBufferStructPtr& textureIndexMap
+			);
 
 
 
 
 		/// Does this parameter set include named parameters?
 		/// Does this parameter set include named parameters?
@@ -727,12 +721,15 @@ namespace CamelotEngine {
 		int* getIntPointer(UINT32 pos) { return &mIntConstants[pos]; }
 		int* getIntPointer(UINT32 pos) { return &mIntConstants[pos]; }
 		/// Get a pointer to the 'nth' item in the int buffer
 		/// Get a pointer to the 'nth' item in the int buffer
 		const int* getIntPointer(UINT32 pos) const { return &mIntConstants[pos]; }
 		const int* getIntPointer(UINT32 pos) const { return &mIntConstants[pos]; }
-		const GpuLogicalBufferStructPtr& getSamplerLogicalBufferStruct() const { return mSamplerLogicalToPhysical; }
+		const GpuLogicalBufferStructPtr& getTextureLogicalBufferStruct() const { return mTextureLogicalToPhysical; }
 		TextureHandle getTexture(UINT32 pos) const;
 		TextureHandle getTexture(UINT32 pos) const;
-		const SamplerState& getSamplerState(UINT32 pos) const;
+		const GpuLogicalBufferStructPtr& getSamplerLogicalBufferStruct() const { return mSamplerLogicalToPhysical; }
+		SamplerStatePtr getSamplerState(UINT32 pos) const;
 		/// Get a reference to the list of textures
 		/// Get a reference to the list of textures
-		const TextureList& getTextureList() const { return mTextures; }
+		const vector<TextureHandle>::type& getTextureList() const { return mTextures; }
 		UINT32 getNumTextures() const { return (UINT32)mTextures.size(); }
 		UINT32 getNumTextures() const { return (UINT32)mTextures.size(); }
+		const vector<SamplerStatePtr>::type& getSamplerStateList() const { return mSamplerStates; }
+		UINT32 getNumSamplerStates() const { return (UINT32)mSamplerStates.size(); }
 
 
 		/** Tells the program whether to ignore missing parameters or not.
 		/** Tells the program whether to ignore missing parameters or not.
 		*/
 		*/
@@ -779,7 +776,7 @@ namespace CamelotEngine {
 		@param name The name of the parameter
 		@param name The name of the parameter
 		@param val The value to set
 		@param val The value to set
 		*/
 		*/
-		void setNamedConstant(const String& name, const SamplerState& val);
+		void setNamedConstant(const String& name, SamplerStatePtr val);
 
 
 		/** Sets a single value constant floating-point parameter to the program.
 		/** Sets a single value constant floating-point parameter to the program.
 		@remarks
 		@remarks

+ 5 - 12
CamelotRenderer/Include/CmMaterialRTTI.h

@@ -19,13 +19,6 @@ namespace CamelotEngine
 	class CM_EXPORT MaterialRTTI : public RTTIType<Material, Resource, MaterialRTTI>
 	class CM_EXPORT MaterialRTTI : public RTTIType<Material, Resource, MaterialRTTI>
 	{
 	{
 	private:
 	private:
-		enum MaterialParamType
-		{
-			MPT_FLOAT,
-			MPT_INT,
-			MPT_TEX
-		};
-
 		struct FloatParam
 		struct FloatParam
 		{
 		{
 			FloatParam() {}
 			FloatParam() {}
@@ -114,7 +107,7 @@ namespace CamelotEngine
 		};
 		};
 
 
 		class SamplerStateParamKVPRTTI;
 		class SamplerStateParamKVPRTTI;
-		typedef KeyValuePair<String, SamplerState, SamplerStateParamKVPRTTI> SamplerStateKVP;
+		typedef KeyValuePair<String, SamplerStatePtr, SamplerStateParamKVPRTTI> SamplerStateKVP;
 
 
 		class SamplerStateParamKVPRTTI : public RTTIType<SamplerStateKVP, IReflectable, SamplerStateParamKVPRTTI>
 		class SamplerStateParamKVPRTTI : public RTTIType<SamplerStateKVP, IReflectable, SamplerStateParamKVPRTTI>
 		{
 		{
@@ -122,14 +115,14 @@ namespace CamelotEngine
 			String& getKey(SamplerStateKVP* obj) { return obj->mKey; }
 			String& getKey(SamplerStateKVP* obj) { return obj->mKey; }
 			void setKey(SamplerStateKVP* obj,  String& val) { obj->mKey = val; }
 			void setKey(SamplerStateKVP* obj,  String& val) { obj->mKey = val; }
 
 
-			SamplerState& getValue(SamplerStateKVP* obj) { return obj->mValue; }
-			void setValue(SamplerStateKVP* obj,  SamplerState& val) { obj->mValue = val; }
+			SamplerStatePtr getValue(SamplerStateKVP* obj) { return obj->mValue; }
+			void setValue(SamplerStateKVP* obj,  SamplerStatePtr val) { obj->mValue = val; }
 
 
 		public:
 		public:
 			SamplerStateParamKVPRTTI()
 			SamplerStateParamKVPRTTI()
 			{
 			{
 				addPlainField("mKey", 0, &SamplerStateParamKVPRTTI::getKey, &SamplerStateParamKVPRTTI::setKey);
 				addPlainField("mKey", 0, &SamplerStateParamKVPRTTI::getKey, &SamplerStateParamKVPRTTI::setKey);
-				addPlainField("mValue", 1, &SamplerStateParamKVPRTTI::getValue, &SamplerStateParamKVPRTTI::setValue);
+				addReflectablePtrField("mValue", 1, &SamplerStateParamKVPRTTI::getValue, &SamplerStateParamKVPRTTI::setValue);
 			}
 			}
 
 
 		public:
 		public:
@@ -156,7 +149,7 @@ namespace CamelotEngine
 		{
 		{
 			map<String, FloatParam>::type mFloatParams;
 			map<String, FloatParam>::type mFloatParams;
 			map<String, TextureHandle>::type mTextureParams;
 			map<String, TextureHandle>::type mTextureParams;
-			map<String, SamplerState>::type mSamplerStateParams;
+			map<String, SamplerStatePtr>::type mSamplerStateParams;
 
 
 			vector<float>::type mFloatBuffer;
 			vector<float>::type mFloatBuffer;
 
 

+ 7 - 0
CamelotRenderer/Include/CmPrerequisites.h

@@ -110,6 +110,8 @@ namespace CamelotEngine {
 	class HardwareConstantBuffer;
 	class HardwareConstantBuffer;
 	class CommandQueue;
 	class CommandQueue;
 	class DeferredRenderContext;
 	class DeferredRenderContext;
+	class DepthStencilState;
+	class RenderStateManager;
 	// Asset import
 	// Asset import
 	class SpecificImporter;
 	class SpecificImporter;
 	class Importer;
 	class Importer;
@@ -124,6 +126,9 @@ namespace CamelotEngine {
 	class SceneManager;
 	class SceneManager;
 	// RTTI
 	// RTTI
 	class MeshRTTI;
 	class MeshRTTI;
+	// Desc structs
+	struct SAMPLER_STATE_DESC;
+	struct DEPTH_STENCIL_DESC;
 }
 }
 
 
 /* Shared pointer typedefs*/
 /* Shared pointer typedefs*/
@@ -151,6 +156,8 @@ namespace CamelotEngine
 	typedef std::shared_ptr<GameObject> GameObjectPtr;
 	typedef std::shared_ptr<GameObject> GameObjectPtr;
 	typedef std::shared_ptr<HardwareConstantBuffer> HardwareConstantBufferPtr;
 	typedef std::shared_ptr<HardwareConstantBuffer> HardwareConstantBufferPtr;
 	typedef std::shared_ptr<DeferredRenderContext> DeferredRenderContextPtr;
 	typedef std::shared_ptr<DeferredRenderContext> DeferredRenderContextPtr;
+	typedef std::shared_ptr<SamplerState> SamplerStatePtr;
+	typedef std::shared_ptr<DepthStencilState> DepthStencilStatePtr;
 }
 }
 
 
 // All type IDs
 // All type IDs

+ 35 - 0
CamelotRenderer/Include/CmRenderStateManager.h

@@ -0,0 +1,35 @@
+#pragma once
+
+#include "CmPrerequisites.h"
+#include "CmModule.h"
+
+namespace CamelotEngine
+{
+	class CM_EXPORT RenderStateManager : public Module<RenderStateManager>
+	{
+	public:
+		/**
+		 * @brief	Creates and initializes a new SamplerState.
+		 */
+		virtual SamplerStatePtr createSamplerState(const SAMPLER_STATE_DESC& desc) const;
+
+		/**
+		 * @brief	Creates and initializes a new DepthStencilState.
+		 */
+		virtual DepthStencilStatePtr createDepthStencilState(const DEPTH_STENCIL_DESC& desc) const;
+
+		/**
+		 * @brief	Creates a completely empty and uninitialized SamplerState.
+		 * 			Should only be used for VERY specific purposes, like deserialization,
+		 * 			as it requires additional manual initialization that is not required normally.
+		 */
+		virtual SamplerStatePtr createEmptySamplerState() const;
+
+		/**
+		 * @brief	Creates a completely empty and uninitialized DepthStencilState.
+		 * 			Should only be used for VERY specific purposes, like deserialization,
+		 * 			as it requires additional manual initialization that is not required normally.
+		 */
+		virtual DepthStencilStatePtr createEmptyDepthStencilState() const;
+	};
+}

+ 5 - 18
CamelotRenderer/Include/CmRenderSystem.h

@@ -357,12 +357,10 @@ namespace CamelotEngine
 		// They can be called by library user if required
 		// They can be called by library user if required
 		// ------------------------------------------------------------------------
 		// ------------------------------------------------------------------------
 
 
-		/** Utility function for setting all the properties of a texture unit at once.
-		This method is also worth using over the individual texture unit settings because it
-		only sets those settings which are different from the current settings for this
-		unit, thus minimising render state changes.
-		*/
-		virtual void setTextureUnitSettings(UINT16 texUnit, const TexturePtr& texture, const SamplerState& samplerState);
+		/**
+		 * @brief	Sets a sampler state for the specified texture unit.
+		 */
+		virtual void setSamplerState(UINT16 texUnit, const SamplerState& samplerState);
 		/** Turns off a texture unit. */
 		/** Turns off a texture unit. */
 		virtual void disableTextureUnit(UINT16 texUnit);
 		virtual void disableTextureUnit(UINT16 texUnit);
 		/** Disables all texture units from the given unit upwards */
 		/** Disables all texture units from the given unit upwards */
@@ -397,17 +395,6 @@ namespace CamelotEngine
 		virtual void setTexture(UINT16 unit, bool enabled, 
 		virtual void setTexture(UINT16 unit, bool enabled, 
 			const TexturePtr &texPtr) = 0;
 			const TexturePtr &texPtr) = 0;
 
 
-		/** Binds a texture to a vertex sampler.
-		@remarks
-		Not all rendersystems support separate vertex samplers. For those that
-		do, you can set a texture for them, separate to the regular texture
-		samplers, using this method. For those that don't, you should use the
-		regular texture samplers which are shared between the vertex and
-		fragment units; calling this method will throw an exception.
-		@see RenderSystemCapabilites::getVertexTextureUnitsShared
-		*/
-		virtual void setVertexTexture(UINT16 unit, const TexturePtr& tex);
-
 		/** Sets the filtering options for a given texture unit.
 		/** Sets the filtering options for a given texture unit.
 		@param unit The texture unit to set the filtering options for
 		@param unit The texture unit to set the filtering options for
 		@param minFilter The filter used when a texture is reduced in size
 		@param minFilter The filter used when a texture is reduced in size
@@ -428,7 +415,7 @@ namespace CamelotEngine
 		virtual void setTextureAnisotropy(UINT16 unit, unsigned int maxAnisotropy) = 0;
 		virtual void setTextureAnisotropy(UINT16 unit, unsigned int maxAnisotropy) = 0;
 
 
 		/** Sets the texture addressing mode for a texture unit.*/
 		/** Sets the texture addressing mode for a texture unit.*/
-		virtual void setTextureAddressingMode(UINT16 unit, const SamplerState::UVWAddressingMode& uvw) = 0;
+		virtual void setTextureAddressingMode(UINT16 unit, const UVWAddressingMode& uvw) = 0;
 
 
 		/** Sets the texture border color for a texture unit.*/
 		/** Sets the texture border color for a texture unit.*/
 		virtual void setTextureBorderColor(UINT16 unit, const Color& color) = 0;
 		virtual void setTextureBorderColor(UINT16 unit, const Color& color) = 0;

+ 84 - 216
CamelotRenderer/Include/CmSamplerState.h

@@ -1,30 +1,3 @@
-/*
------------------------------------------------------------------------------
-This source file is part of OGRE
-(Object-oriented Graphics Rendering Engine)
-For the latest info, see http://www.ogre3d.org
-
-Copyright (c) 2000-2011 Torus Knot Software Ltd
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
------------------------------------------------------------------------------
-*/
 #pragma once
 #pragma once
 
 
 #include "CmPrerequisites.h"
 #include "CmPrerequisites.h"
@@ -33,213 +6,108 @@ THE SOFTWARE.
 #include "CmString.h"
 #include "CmString.h"
 #include "CmPixelUtil.h"
 #include "CmPixelUtil.h"
 #include "CmTexture.h"
 #include "CmTexture.h"
-
-namespace CamelotEngine {
-	/** \addtogroup Core
-	*  @{
-	*/
-	/** \addtogroup Materials
-	*  @{
+#include "CmColor.h"
+#include "CmIReflectable.h"
+
+namespace CamelotEngine 
+{
+	struct SAMPLER_STATE_DESC
+	{
+		SAMPLER_STATE_DESC()
+			: minFilter(FO_LINEAR)
+			, magFilter(FO_LINEAR)
+			, mipFilter(FO_POINT)
+			, maxAniso(0)
+			, mipmapBias(0)
+			, comparisonFunc(CMPF_ALWAYS_FAIL)
+			, mipMin(-FLT_MAX)
+			, mipMax(FLT_MAX)
+		{
+			for(int i = 0; i < 4; i++)
+				borderColor[i] = Color::White;
+		}
+
+		UVWAddressingMode addressMode;
+		FilterOptions minFilter;
+		FilterOptions magFilter;
+		FilterOptions mipFilter;
+		unsigned int maxAniso;
+		float mipmapBias;
+		float mipMin;
+		float mipMax;
+		Color borderColor[4];
+		CompareFunction comparisonFunc;
+	};
+
+	/**
+	* @brief	Class representing the state of a single sampler unit during a Pass of a Technique, of a Material.
+	*	
+	* @note		Sampler units are pipelines for retrieving texture data for rendering onto
+	*			your objects in the world.
+	*
+	*			Try not to make modifications to a created sampler state. Any modification will require the sampler state to
+	*			be recreated internally (depending on used render system). It is better to have multiple SamplerState objects with different
+	*			configurations and re-use them.
 	*/
 	*/
-	/** Class representing the state of a single sampler unit during a Pass of a
-        Technique, of a Material.
-    @remarks
-        Sampler units are pipelines for retrieving texture data for rendering onto
-        your objects in the world. 
-    */
-	class CM_EXPORT SamplerState
+	class CM_EXPORT SamplerState : public IReflectable
     {
     {
     public:
     public:
+		static SamplerState DEFAULT;
 
 
-		static SamplerState EMPTY;
-
-        /** Texture addressing modes - default is TAM_WRAP.
+        /** Gets the texture addressing mode for a given coordinate, 
+		 	i.e. what happens at uv values above 1.0.
         @note
         @note
-            These settings are relevant in both the fixed-function and the
-            programmable pipeline.
-        */
-        enum TextureAddressingMode
-        {
-            /// Texture wraps at values over 1.0
-            TAM_WRAP,
-            /// Texture mirrors (flips) at joins over 1.0
-            TAM_MIRROR,
-            /// Texture clamps at 1.0
-            TAM_CLAMP,
-            /// Texture coordinates outside the range [0.0, 1.0] are set to the border colour
-            TAM_BORDER
-        };
-
-		/** Texture addressing mode for each texture coordinate. */
-		struct UVWAddressingMode
-		{
-			TextureAddressingMode u, v, w;
-		};
-
-        /** Enum identifying the frame indexes for faces of a cube map (not the composite 3D type.
-        */
-        enum TextureCubeFace
-        {
-            CUBE_FRONT = 0,
-            CUBE_BACK = 1,
-            CUBE_LEFT = 2,
-            CUBE_RIGHT = 3,
-            CUBE_UP = 4,
-            CUBE_DOWN = 5
-        };
-
-        /** Default constructor.
+        	The default is TAM_WRAP i.e. the texture repeats over values of 1.0.
         */
         */
-        SamplerState();
+		const UVWAddressingMode& getTextureAddressingMode() const { return mData.addressMode; }
 
 
-        SamplerState(const SamplerState& oth );
+        // get the texture filtering for the given type
+        FilterOptions getTextureFiltering(FilterType ftpye) const;
 
 
-        SamplerState & operator = ( const SamplerState& oth );
+        // get this layer texture anisotropy level
+		unsigned int getTextureAnisotropy() const { return mData.maxAniso; }
 
 
-        /** Default destructor.
-        */
-        ~SamplerState();
+		/**
+		 * @brief	Gets a function that compares sampled data with existing sampled data.
+		 */
+		CompareFunction getComparisonFunction() const { return mData.comparisonFunc; }
 
 
-		/** The type of unit to bind the texture settings to. */
-		enum BindingType
-		{
-			/** Regular fragment processing unit - the default. */
-			BT_FRAGMENT = 0,
-			/** Vertex processing unit - indicates this unit will be used for 
-				a vertex texture fetch.
-			*/
-			BT_VERTEX = 1
-		};
-
-		/** Sets the type of unit these texture settings should be bound to. 
-		@remarks
-			Some render systems, when implementing vertex texture fetch, separate
-			the binding of textures for use in the vertex program versus those
-			used in fragment programs. This setting allows you to target the
-			vertex processing unit with a texture binding, in those cases. For
-			rendersystems which have a unified binding for the vertex and fragment
-			units, this setting makes no difference.
+		/** Gets the bias value applied to the mipmap calculation.
+		@see TextureUnitState::setTextureMipmapBias
 		*/
 		*/
-		void setBindingType(BindingType bt);
+		float getTextureMipmapBias() const { return mData.mipmapBias; }
 
 
-		/** Gets the type of unit these texture settings should be bound to.  
-		*/
-		BindingType getBindingType(void) const;
+		/**
+		 * @brief	Returns the minimum mip level limit.
+		 */
+		float getMinimumMip() const { return mData.mipMin; }
 
 
-		/// @copydoc Texture::setHardwareGammaEnabled
-		void setHardwareGammaEnabled(bool enabled);
-		/// @copydoc Texture::isHardwareGammaEnabled
-		bool isHardwareGammaEnabled() const;
+		/**
+		 * @brief	Returns the maximum mip level limit.
+		 */
+		float getMaximumMip() const { return mData.mipMax; }
 
 
-        /** Gets the texture addressing mode for a given coordinate, 
-		 	i.e. what happens at uv values above 1.0.
-        @note
-        	The default is TAM_WRAP i.e. the texture repeats over values of 1.0.
-        */
-        const UVWAddressingMode& getTextureAddressingMode(void) const;
+		/**
+		 * @brief	Gets a border color for the specified side. Index must be >= 0 and < 4.
+		 */
+		const Color& getBorderColor(UINT32 idx);
 
 
-        /** Sets the texture addressing mode, i.e. what happens at uv values above 1.0.
-        @note
-        The default is TAM_WRAP i.e. the texture repeats over values of 1.0.
-		@note This is a shortcut method which sets the addressing mode for all
-			coordinates at once; you can also call the more specific method
-			to set the addressing mode per coordinate.
-        @note
-        This applies for both the fixed-function and programmable pipelines.
-        */
-        void setTextureAddressingMode( TextureAddressingMode tam);
-
-        /** Sets the texture addressing mode, i.e. what happens at uv values above 1.0.
-        @note
-        The default is TAM_WRAP i.e. the texture repeats over values of 1.0.
-        @note
-        This applies for both the fixed-function and programmable pipelines.
-		*/
-        void setTextureAddressingMode( TextureAddressingMode u, 
-			TextureAddressingMode v, TextureAddressingMode w);
+		static SamplerStatePtr create(const SAMPLER_STATE_DESC& desc);
 
 
-        /** Sets the texture addressing mode, i.e. what happens at uv values above 1.0.
-        @note
-        The default is TAM_WRAP i.e. the texture repeats over values of 1.0.
-        @note
-        This applies for both the fixed-function and programmable pipelines.
-		*/
-        void setTextureAddressingMode( const UVWAddressingMode& uvw);
+	private:
+		friend class RenderStateManager;
 
 
-        /** Set the texture filtering for this unit, using the simplified interface.
-        @remarks
-            You also have the option of specifying the minification, magnification
-            and mip filter individually if you want more control over filtering
-            options. See the alternative setTextureFiltering methods for details.
-        @note
-        This option applies in both the fixed function and the programmable pipeline.
-        @param filterType The high-level filter type to use.
-        */
-        void setTextureFiltering(TextureFilterOptions filterType);
-        /** Set a single filtering option on this texture unit. 
-        @params ftype The filtering type to set
-        @params opts The filtering option to set
-        */
-        void setTextureFiltering(FilterType ftype, FilterOptions opts);
-        /** Set a the detailed filtering options on this texture unit. 
-        @params minFilter The filtering to use when reducing the size of the texture. 
-            Can be FO_POINT, FO_LINEAR or FO_ANISOTROPIC
-        @params magFilter The filtering to use when increasing the size of the texture
-            Can be FO_POINT, FO_LINEAR or FO_ANISOTROPIC
-        @params mipFilter The filtering to use between mip levels
-            Can be FO_NONE (turns off mipmapping), FO_POINT or FO_LINEAR (trilinear filtering)
-        */
-        void setTextureFiltering(FilterOptions minFilter, FilterOptions magFilter, FilterOptions mipFilter);
-        // get the texture filtering for the given type
-        FilterOptions getTextureFiltering(FilterType ftpye) const;
+		virtual void initialize(const SAMPLER_STATE_DESC& desc);
 
 
-        /** Sets the anisotropy level to be used for this texture level.
-        @par maxAniso The maximal anisotropy level, should be between 2 and the maximum supported by hardware (1 is the default, ie. no anisotrophy).
-        @note
-        This option applies in both the fixed function and the programmable pipeline.
-        */
-        void setTextureAnisotropy(unsigned int maxAniso);
-        // get this layer texture anisotropy level
-        unsigned int getTextureAnisotropy() const;
-
-		/** Sets the bias value applied to the mipmap calculation.
-		@remarks
-			You can alter the mipmap calculation by biasing the result with a 
-			single floating point value. After the mip level has been calculated,
-			this bias value is added to the result to give the final mip level.
-			Lower mip levels are larger (higher detail), so a negative bias will
-			force the larger mip levels to be used, and a positive bias
-			will cause smaller mip levels to be used. The bias values are in 
-			mip levels, so a -1 bias will force mip levels one larger than by the
-			default calculation.
-		@param bias The bias value as described above, can be positive or negative.
-		*/
-		void setTextureMipmapBias(float bias) { mMipmapBias = bias; }
-		/** Gets the bias value applied to the mipmap calculation.
-		@see TextureUnitState::setTextureMipmapBias
-		*/
-		float getTextureMipmapBias(void) const { return mMipmapBias; }
-protected:
-        UVWAddressingMode mAddressMode;
-
-		bool mHwGamma;
-
-        /// Texture filtering - minification
-        FilterOptions mMinFilter;
-        /// Texture filtering - magnification
-        FilterOptions mMagFilter;
-        /// Texture filtering - mipmapping
-        FilterOptions mMipFilter;
-        ///Texture anisotropy
-        unsigned int mMaxAniso;
-		/// Mipmap bias (always float, not float)
-		float mMipmapBias;
-
-		/// Binding type (fragment or vertex pipeline)
-		BindingType mBindingType;
-    };
+        SAMPLER_STATE_DESC mData;
 
 
-	/** @} */
-	/** @} */
+		/************************************************************************/
+		/* 								RTTI		                     		*/
+		/************************************************************************/
 
 
+	public:
+		friend class SamplerStateRTTI;
+		static RTTITypeBase* getRTTIStatic();
+		virtual RTTITypeBase* getRTTI() const;	
+    };
 }
 }

+ 53 - 0
CamelotRenderer/Include/CmSamplerStateRTTI.h

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

+ 9 - 6
CamelotRenderer/Source/CmCgProgram.cpp

@@ -316,19 +316,23 @@ namespace CamelotEngine {
 					// Record logical / physical mapping
 					// Record logical / physical mapping
 					if(def.isSampler())
 					if(def.isSampler())
 					{
 					{
-						CM_LOCK_MUTEX(mSamplerLogicalToPhysical->mutex)
-							mSamplerLogicalToPhysical->map.insert(
+						mSamplerLogicalToPhysical->map.insert(
 							GpuLogicalIndexUseMap::value_type(logicalIndex, 
 							GpuLogicalIndexUseMap::value_type(logicalIndex, 
 							GpuLogicalIndexUse(def.physicalIndex, def.arraySize, GPV_GLOBAL)));
 							GpuLogicalIndexUse(def.physicalIndex, def.arraySize, GPV_GLOBAL)));
 						mSamplerLogicalToPhysical->bufferSize += def.arraySize;
 						mSamplerLogicalToPhysical->bufferSize += def.arraySize;
 						mConstantDefs->samplerCount = mSamplerLogicalToPhysical->bufferSize;
 						mConstantDefs->samplerCount = mSamplerLogicalToPhysical->bufferSize;
+
+						mTextureLogicalToPhysical->map.insert(
+							GpuLogicalIndexUseMap::value_type(logicalIndex, 
+							GpuLogicalIndexUse(def.physicalIndex, def.arraySize, GPV_GLOBAL)));
+						mTextureLogicalToPhysical->bufferSize += def.arraySize;
+						mConstantDefs->textureCount = mTextureLogicalToPhysical->bufferSize;
 					}
 					}
 					else
 					else
 					{
 					{
 						if (def.isFloat())
 						if (def.isFloat())
 						{
 						{
-							CM_LOCK_MUTEX(mFloatLogicalToPhysical->mutex)
-								mFloatLogicalToPhysical->map.insert(
+							mFloatLogicalToPhysical->map.insert(
 								GpuLogicalIndexUseMap::value_type(logicalIndex, 
 								GpuLogicalIndexUseMap::value_type(logicalIndex, 
 								GpuLogicalIndexUse(def.physicalIndex, def.arraySize * def.elementSize, GPV_GLOBAL)));
 								GpuLogicalIndexUse(def.physicalIndex, def.arraySize * def.elementSize, GPV_GLOBAL)));
 							mFloatLogicalToPhysical->bufferSize += def.arraySize * def.elementSize;
 							mFloatLogicalToPhysical->bufferSize += def.arraySize * def.elementSize;
@@ -336,8 +340,7 @@ namespace CamelotEngine {
 						}
 						}
 						else
 						else
 						{
 						{
-							CM_LOCK_MUTEX(mIntLogicalToPhysical->mutex)
-								mIntLogicalToPhysical->map.insert(
+							mIntLogicalToPhysical->map.insert(
 								GpuLogicalIndexUseMap::value_type(logicalIndex, 
 								GpuLogicalIndexUseMap::value_type(logicalIndex, 
 								GpuLogicalIndexUse(def.physicalIndex, def.arraySize * def.elementSize, GPV_GLOBAL)));
 								GpuLogicalIndexUse(def.physicalIndex, def.arraySize * def.elementSize, GPV_GLOBAL)));
 							mIntLogicalToPhysical->bufferSize += def.arraySize * def.elementSize;
 							mIntLogicalToPhysical->bufferSize += def.arraySize * def.elementSize;

+ 3 - 8
CamelotRenderer/Source/CmDeferredRenderContext.cpp

@@ -30,9 +30,9 @@ namespace CamelotEngine
 		mCommandQueue->queue(boost::bind(&RenderSystem::setViewport, mRenderSystem, vp));
 		mCommandQueue->queue(boost::bind(&RenderSystem::setViewport, mRenderSystem, vp));
 	}
 	}
 
 
-	void DeferredRenderContext::setTextureUnitSettings(UINT16 texUnit, const TexturePtr& tex, const SamplerState& samplerState)
+	void DeferredRenderContext::setSamplerState(UINT16 texUnit, const SamplerState& samplerState)
 	{
 	{
-		mCommandQueue->queue(boost::bind(&RenderSystem::setTextureUnitSettings, mRenderSystem, texUnit, tex, samplerState));
+		mCommandQueue->queue(boost::bind(&RenderSystem::setSamplerState, mRenderSystem, texUnit, samplerState));
 	}
 	}
 
 
 	void DeferredRenderContext::setTexture(UINT16 unit, bool enabled, const TexturePtr &texPtr)
 	void DeferredRenderContext::setTexture(UINT16 unit, bool enabled, const TexturePtr &texPtr)
@@ -40,11 +40,6 @@ namespace CamelotEngine
 		mCommandQueue->queue(boost::bind(&RenderSystem::setTexture, mRenderSystem, unit, enabled, texPtr));
 		mCommandQueue->queue(boost::bind(&RenderSystem::setTexture, mRenderSystem, unit, enabled, texPtr));
 	}
 	}
 
 
-	void DeferredRenderContext::setVertexTexture(UINT16 unit, const TexturePtr& tex)
-	{
-		mCommandQueue->queue(boost::bind(&RenderSystem::setVertexTexture, mRenderSystem, unit, tex));
-	}
-
 	void DeferredRenderContext::disableTextureUnit(UINT16 texUnit)
 	void DeferredRenderContext::disableTextureUnit(UINT16 texUnit)
 	{
 	{
 		mCommandQueue->queue(boost::bind(&RenderSystem::disableTextureUnit, mRenderSystem, texUnit));
 		mCommandQueue->queue(boost::bind(&RenderSystem::disableTextureUnit, mRenderSystem, texUnit));
@@ -66,7 +61,7 @@ namespace CamelotEngine
 		mCommandQueue->queue(boost::bind(&RenderSystem::setTextureAnisotropy, mRenderSystem, unit, maxAnisotropy));
 		mCommandQueue->queue(boost::bind(&RenderSystem::setTextureAnisotropy, mRenderSystem, unit, maxAnisotropy));
 	}
 	}
 
 
-	void DeferredRenderContext::setTextureAddressingMode(UINT16 unit, const SamplerState::UVWAddressingMode& uvw)
+	void DeferredRenderContext::setTextureAddressingMode(UINT16 unit, const UVWAddressingMode& uvw)
 	{
 	{
 		mCommandQueue->queue(boost::bind(&RenderSystem::setTextureAddressingMode, mRenderSystem, unit, uvw));
 		mCommandQueue->queue(boost::bind(&RenderSystem::setTextureAddressingMode, mRenderSystem, unit, uvw));
 	}
 	}

+ 23 - 0
CamelotRenderer/Source/CmDepthStencilState.cpp

@@ -0,0 +1,23 @@
+#include "CmDepthStencilState.h"
+#include "CmRenderStateManager.h"
+#include "CmException.h"
+
+namespace CamelotEngine
+{
+	void DepthStencilState::initialize(const DEPTH_STENCIL_DESC& desc)
+	{
+		mData = desc;
+		mStencilRefValue = 0;
+	}
+
+	DepthStencilState::DepthStencilState()
+		:mStencilRefValue(0)
+	{
+
+	}
+
+	DepthStencilStatePtr DepthStencilState::create(const DEPTH_STENCIL_DESC& desc)
+	{
+		return RenderStateManager::instance().createDepthStencilState(desc);
+	}
+}

+ 3 - 1
CamelotRenderer/Source/CmGpuProgram.cpp

@@ -116,6 +116,8 @@ namespace CamelotEngine
 			mIntLogicalToPhysical = GpuLogicalBufferStructPtr(new GpuLogicalBufferStruct());
 			mIntLogicalToPhysical = GpuLogicalBufferStructPtr(new GpuLogicalBufferStruct());
 		if (recreateIfExists || (mSamplerLogicalToPhysical == nullptr))
 		if (recreateIfExists || (mSamplerLogicalToPhysical == nullptr))
 			mSamplerLogicalToPhysical = GpuLogicalBufferStructPtr(new GpuLogicalBufferStruct());
 			mSamplerLogicalToPhysical = GpuLogicalBufferStructPtr(new GpuLogicalBufferStruct());
+		if(recreateIfExists || (mTextureLogicalToPhysical == nullptr))
+			mTextureLogicalToPhysical = GpuLogicalBufferStructPtr(new GpuLogicalBufferStruct());
 	}
 	}
 	//---------------------------------------------------------------------
 	//---------------------------------------------------------------------
 	void GpuProgram::createNamedParameterMappingStructures(bool recreateIfExists) const
 	void GpuProgram::createNamedParameterMappingStructures(bool recreateIfExists) const
@@ -144,7 +146,7 @@ namespace CamelotEngine
 			ret->_setNamedConstants(mConstantDefs);
 			ret->_setNamedConstants(mConstantDefs);
 		}
 		}
 		// link shared logical / physical map for low-level use
 		// link shared logical / physical map for low-level use
-		ret->_setLogicalIndexes(mFloatLogicalToPhysical, mIntLogicalToPhysical, mSamplerLogicalToPhysical);
+		ret->_setLogicalIndexes(mFloatLogicalToPhysical, mIntLogicalToPhysical, mSamplerLogicalToPhysical, mTextureLogicalToPhysical);
 
 
 		op.completeOperation(ret);
 		op.completeOperation(ret);
     }
     }

+ 32 - 32
CamelotRenderer/Source/CmGpuProgramParams.cpp

@@ -105,10 +105,12 @@ namespace CamelotEngine
 		// RealConstantEntry, IntConstantEntry
 		// RealConstantEntry, IntConstantEntry
 		mFloatConstants = oth.mFloatConstants;
 		mFloatConstants = oth.mFloatConstants;
 		mIntConstants  = oth.mIntConstants;
 		mIntConstants  = oth.mIntConstants;
+		mSamplerStates = oth.mSamplerStates;
 		mTextures = oth.mTextures;
 		mTextures = oth.mTextures;
 		mFloatLogicalToPhysical = oth.mFloatLogicalToPhysical;
 		mFloatLogicalToPhysical = oth.mFloatLogicalToPhysical;
 		mIntLogicalToPhysical = oth.mIntLogicalToPhysical;
 		mIntLogicalToPhysical = oth.mIntLogicalToPhysical;
 		mSamplerLogicalToPhysical = oth.mSamplerLogicalToPhysical;
 		mSamplerLogicalToPhysical = oth.mSamplerLogicalToPhysical;
+		mTextureLogicalToPhysical = oth.mTextureLogicalToPhysical;
 		mNamedConstants = oth.mNamedConstants;
 		mNamedConstants = oth.mNamedConstants;
 
 
 		mCombinedVariability = oth.mCombinedVariability;
 		mCombinedVariability = oth.mCombinedVariability;
@@ -136,21 +138,28 @@ namespace CamelotEngine
 			mIntConstants.insert(mIntConstants.end(), 
 			mIntConstants.insert(mIntConstants.end(), 
 				namedConstants->intBufferSize - mIntConstants.size(), 0);
 				namedConstants->intBufferSize - mIntConstants.size(), 0);
 		}
 		}
-		if (namedConstants->samplerCount > mTextures.size())
+		if (namedConstants->textureCount > mTextures.size())
 		{
 		{
 			mTextures.insert(mTextures.end(), 
 			mTextures.insert(mTextures.end(), 
-				namedConstants->samplerCount - mTextures.size(), nullptr);
+				namedConstants->textureCount - mTextures.size(), TextureHandle());
+		}
+		if (namedConstants->samplerCount > mSamplerStates.size())
+		{
+			mSamplerStates.insert(mSamplerStates.end(), 
+				namedConstants->samplerCount - mSamplerStates.size(), nullptr);
 		}
 		}
 	}
 	}
 	//---------------------------------------------------------------------
 	//---------------------------------------------------------------------
 	void GpuProgramParameters::_setLogicalIndexes(
 	void GpuProgramParameters::_setLogicalIndexes(
 		const GpuLogicalBufferStructPtr& floatIndexMap, 
 		const GpuLogicalBufferStructPtr& floatIndexMap, 
 		const GpuLogicalBufferStructPtr& intIndexMap,
 		const GpuLogicalBufferStructPtr& intIndexMap,
-		const GpuLogicalBufferStructPtr& samplerIndexMap)
+		const GpuLogicalBufferStructPtr& samplerIndexMap,
+		const GpuLogicalBufferStructPtr& textureIndexMap)
 	{
 	{
 		mFloatLogicalToPhysical = floatIndexMap;
 		mFloatLogicalToPhysical = floatIndexMap;
 		mIntLogicalToPhysical = intIndexMap;
 		mIntLogicalToPhysical = intIndexMap;
 		mSamplerLogicalToPhysical = samplerIndexMap;
 		mSamplerLogicalToPhysical = samplerIndexMap;
+		mTextureLogicalToPhysical = textureIndexMap;
 
 
 		// resize the internal buffers
 		// resize the internal buffers
 		// Note that these will only contain something after the first parameter
 		// Note that these will only contain something after the first parameter
@@ -162,16 +171,23 @@ namespace CamelotEngine
 			mFloatConstants.insert(mFloatConstants.end(), 
 			mFloatConstants.insert(mFloatConstants.end(), 
 				floatIndexMap->bufferSize - mFloatConstants.size(), 0.0f);
 				floatIndexMap->bufferSize - mFloatConstants.size(), 0.0f);
 		}
 		}
+
 		if ((intIndexMap != nullptr) &&  intIndexMap->bufferSize > mIntConstants.size())
 		if ((intIndexMap != nullptr) &&  intIndexMap->bufferSize > mIntConstants.size())
 		{
 		{
 			mIntConstants.insert(mIntConstants.end(), 
 			mIntConstants.insert(mIntConstants.end(), 
 				intIndexMap->bufferSize - mIntConstants.size(), 0);
 				intIndexMap->bufferSize - mIntConstants.size(), 0);
 		}
 		}
 
 
-		if ((samplerIndexMap != nullptr) &&  samplerIndexMap->bufferSize > mTextures.size())
+		if ((samplerIndexMap != nullptr) &&  samplerIndexMap->bufferSize > mSamplerStates.size())
+		{
+			mSamplerStates.insert(mSamplerStates.end(), 
+				samplerIndexMap->bufferSize - mSamplerStates.size(), nullptr);
+		}
+
+		if ((textureIndexMap != nullptr) &&  textureIndexMap->bufferSize > mTextures.size())
 		{
 		{
 			mTextures.insert(mTextures.end(), 
 			mTextures.insert(mTextures.end(), 
-				samplerIndexMap->bufferSize - mTextures.size(), nullptr);
+				textureIndexMap->bufferSize - mTextures.size(), TextureHandle());
 		}
 		}
 	}
 	}
 	//---------------------------------------------------------------------()
 	//---------------------------------------------------------------------()
@@ -395,7 +411,7 @@ namespace CamelotEngine
 	void GpuProgramParameters::_readTexture(UINT32 physicalIndex, TextureHandle& dest)
 	void GpuProgramParameters::_readTexture(UINT32 physicalIndex, TextureHandle& dest)
 	{
 	{
 		assert(physicalIndex < mTextures.size());
 		assert(physicalIndex < mTextures.size());
-		dest = mTextures[physicalIndex]->texture;
+		dest = mTextures[physicalIndex];
 	}
 	}
 	//---------------------------------------------------------------------
 	//---------------------------------------------------------------------
 	GpuLogicalIndexUse* GpuProgramParameters::_getFloatConstantLogicalIndexUse(
 	GpuLogicalIndexUse* GpuProgramParameters::_getFloatConstantLogicalIndexUse(
@@ -405,9 +421,8 @@ namespace CamelotEngine
 			return 0;
 			return 0;
 
 
 		GpuLogicalIndexUse* indexUse = 0;
 		GpuLogicalIndexUse* indexUse = 0;
-		CM_LOCK_MUTEX(mFloatLogicalToPhysical->mutex)
 
 
-			GpuLogicalIndexUseMap::iterator logi = mFloatLogicalToPhysical->map.find(logicalIndex);
+		GpuLogicalIndexUseMap::iterator logi = mFloatLogicalToPhysical->map.find(logicalIndex);
 		if (logi == mFloatLogicalToPhysical->map.end())
 		if (logi == mFloatLogicalToPhysical->map.end())
 		{
 		{
 			if (requestedSize)
 			if (requestedSize)
@@ -504,9 +519,8 @@ namespace CamelotEngine
 		}
 		}
 
 
 		GpuLogicalIndexUse* indexUse = 0;
 		GpuLogicalIndexUse* indexUse = 0;
-		CM_LOCK_MUTEX(mIntLogicalToPhysical->mutex)
 
 
-			GpuLogicalIndexUseMap::iterator logi = mIntLogicalToPhysical->map.find(logicalIndex);
+		GpuLogicalIndexUseMap::iterator logi = mIntLogicalToPhysical->map.find(logicalIndex);
 		if (logi == mIntLogicalToPhysical->map.end())
 		if (logi == mIntLogicalToPhysical->map.end())
 		{
 		{
 			if (requestedSize)
 			if (requestedSize)
@@ -673,22 +687,17 @@ namespace CamelotEngine
 	//----------------------------------------------------------------------------
 	//----------------------------------------------------------------------------
 	TextureHandle GpuProgramParameters::getTexture(UINT32 pos) const 
 	TextureHandle GpuProgramParameters::getTexture(UINT32 pos) const 
 	{ 
 	{ 
-		if(mTextures[pos] == nullptr)
+		if(!mTextures[pos].isLoaded())
 		{
 		{
 			return TextureHandle();
 			return TextureHandle();
 		}
 		}
 
 
-		return mTextures[pos]->texture; 
+		return mTextures[pos]; 
 	}
 	}
 	//----------------------------------------------------------------------------
 	//----------------------------------------------------------------------------
-	const SamplerState& GpuProgramParameters::getSamplerState(UINT32 pos) const 
+	SamplerStatePtr GpuProgramParameters::getSamplerState(UINT32 pos) const 
 	{ 
 	{ 
-		if(mTextures[pos] == nullptr)
-		{
-			return SamplerState::EMPTY;
-		}
-
-		return mTextures[pos]->samplerState; 
+		return mSamplerStates[pos]; 
 	}
 	}
 	//-----------------------------------------------------------------------------
 	//-----------------------------------------------------------------------------
 	bool GpuProgramParameters::hasNamedConstant(const String& name) const
 	bool GpuProgramParameters::hasNamedConstant(const String& name) const
@@ -735,27 +744,17 @@ namespace CamelotEngine
 			_findNamedConstantDefinition(name, !mIgnoreMissingParams);
 			_findNamedConstantDefinition(name, !mIgnoreMissingParams);
 
 
 		if (def)
 		if (def)
-		{
-			if(mTextures[def->physicalIndex] == nullptr)
-				mTextures[def->physicalIndex] = GpuTextureEntryPtr(new GpuTextureEntry());
-
-			mTextures[def->physicalIndex]->texture = val;
-		}
+			mTextures[def->physicalIndex] = val;
 	}
 	}
 	//-----------------------------------------------------------------------------
 	//-----------------------------------------------------------------------------
-	void GpuProgramParameters::setNamedConstant(const String& name, const SamplerState& val)
+	void GpuProgramParameters::setNamedConstant(const String& name, SamplerStatePtr val)
 	{
 	{
 		// look up, and throw an exception if we're not ignoring missing
 		// look up, and throw an exception if we're not ignoring missing
 		const GpuConstantDefinition* def = 
 		const GpuConstantDefinition* def = 
 			_findNamedConstantDefinition(name, !mIgnoreMissingParams);
 			_findNamedConstantDefinition(name, !mIgnoreMissingParams);
 
 
 		if (def)
 		if (def)
-		{
-			if(mTextures[def->physicalIndex] == nullptr)
-				mTextures[def->physicalIndex] = GpuTextureEntryPtr(new GpuTextureEntry());
-
-			mTextures[def->physicalIndex]->samplerState = val;
-		}
+			mSamplerStates[def->physicalIndex] = val;
 	}
 	}
 	//-----------------------------------------------------------------------------
 	//-----------------------------------------------------------------------------
 	void GpuProgramParameters::setNamedConstant(const String& name, float val)
 	void GpuProgramParameters::setNamedConstant(const String& name, float val)
@@ -879,6 +878,7 @@ namespace CamelotEngine
 		mFloatConstants = source.getFloatConstantList();
 		mFloatConstants = source.getFloatConstantList();
 		mIntConstants = source.getIntConstantList();
 		mIntConstants = source.getIntConstantList();
 		mTextures = source.getTextureList();
 		mTextures = source.getTextureList();
+		mSamplerStates = source.getSamplerStateList();
 		mCombinedVariability = source.mCombinedVariability;
 		mCombinedVariability = source.mCombinedVariability;
 	}
 	}
 }
 }

+ 1 - 1
CamelotRenderer/Source/CmHighLevelGpuProgram.cpp

@@ -124,7 +124,7 @@ namespace CamelotEngine
 		getConstantDefinitions_internal();
 		getConstantDefinitions_internal();
 		params->_setNamedConstants(mConstantDefs);
 		params->_setNamedConstants(mConstantDefs);
 		// also set logical / physical maps for programs which use this
 		// also set logical / physical maps for programs which use this
-		params->_setLogicalIndexes(mFloatLogicalToPhysical, mIntLogicalToPhysical, mSamplerLogicalToPhysical);
+		params->_setLogicalIndexes(mFloatLogicalToPhysical, mIntLogicalToPhysical, mSamplerLogicalToPhysical, mTextureLogicalToPhysical);
 	}
 	}
 	//---------------------------------------------------------------------
 	//---------------------------------------------------------------------
 	HighLevelGpuProgramPtr HighLevelGpuProgram::create(const String& source, const String& entryPoint, 
 	HighLevelGpuProgramPtr HighLevelGpuProgram::create(const String& source, const String& entryPoint, 

+ 1 - 1
CamelotRenderer/Source/CmMaterialRTTI.cpp

@@ -45,7 +45,7 @@ namespace CamelotEngine
 					allParams[i]->_readTexture(iter->second.physicalIndex, texture);
 					allParams[i]->_readTexture(iter->second.physicalIndex, texture);
 					params->mTextureParams[iter->first] = texture;
 					params->mTextureParams[iter->first] = texture;
 
 
-					SamplerState samplerState = allParams[i]->getSamplerState(iter->second.physicalIndex);
+					SamplerStatePtr samplerState = allParams[i]->getSamplerState(iter->second.physicalIndex);
 					params->mSamplerStateParams[iter->first] = samplerState;
 					params->mSamplerStateParams[iter->first] = samplerState;
 				}
 				}
 				else
 				else

+ 32 - 0
CamelotRenderer/Source/CmRenderStateManager.cpp

@@ -0,0 +1,32 @@
+#include "CmRenderStateManager.h"
+#include "CmSamplerState.h"
+#include "CmDepthStencilState.h"
+
+namespace CamelotEngine
+{
+	SamplerStatePtr RenderStateManager::createSamplerState(const SAMPLER_STATE_DESC& desc) const
+	{
+		SamplerStatePtr samplerState = SamplerStatePtr(new SamplerState());
+		samplerState->initialize(desc);
+
+		return samplerState;
+	}
+
+	DepthStencilStatePtr RenderStateManager::createDepthStencilState(const DEPTH_STENCIL_DESC& desc) const
+	{
+		DepthStencilStatePtr depthStencilState = DepthStencilStatePtr(new DepthStencilState());
+		depthStencilState->initialize(desc);
+
+		return depthStencilState;
+	}
+
+	SamplerStatePtr RenderStateManager::createEmptySamplerState() const
+	{
+		return SamplerStatePtr(new SamplerState());
+	}
+
+	DepthStencilStatePtr RenderStateManager::createEmptyDepthStencilState() const
+	{
+		return DepthStencilStatePtr(new DepthStencilState());
+	}
+}

+ 2 - 38
CamelotRenderer/Source/CmRenderSystem.cpp

@@ -245,39 +245,13 @@ namespace CamelotEngine {
         return mActiveViewport;
         return mActiveViewport;
     }
     }
 	//-----------------------------------------------------------------------
 	//-----------------------------------------------------------------------
-    void RenderSystem::setTextureUnitSettings(UINT16 texUnit, const TexturePtr& tex, const SamplerState& tl)
+    void RenderSystem::setSamplerState(UINT16 texUnit, const SamplerState& tl)
     {
     {
 		THROW_IF_NOT_RENDER_THREAD;
 		THROW_IF_NOT_RENDER_THREAD;
 
 
         // This method is only ever called to set a texture unit to valid details
         // This method is only ever called to set a texture unit to valid details
         // The method _disableTextureUnit is called to turn a unit off
         // The method _disableTextureUnit is called to turn a unit off
 
 
-		// Vertex texture binding?
-		if (mCurrentCapabilities->hasCapability(RSC_VERTEX_TEXTURE_FETCH) &&
-			!mCurrentCapabilities->getVertexTextureUnitsShared())
-		{
-			if (tl.getBindingType() == SamplerState::BT_VERTEX)
-			{
-				// Bind vertex texture
-				setVertexTexture(texUnit, tex);
-				// bind nothing to fragment unit (hardware isn't shared but fragment
-				// unit can't be using the same index
-				setTexture(texUnit, true, sNullTexPtr);
-			}
-			else
-			{
-				// vice versa
-				setVertexTexture(texUnit, sNullTexPtr);
-				setTexture(texUnit, true, tex);
-			}
-		}
-		else
-		{
-			// Shared vertex / fragment textures or no vertex texture support
-			// Bind texture (may be blank)
-			setTexture(texUnit, true, tex);
-		}
-
         // Set texture layer filtering
         // Set texture layer filtering
         setTextureFiltering(texUnit, 
         setTextureFiltering(texUnit, 
             tl.getTextureFiltering(FT_MIN), 
             tl.getTextureFiltering(FT_MIN), 
@@ -291,19 +265,9 @@ namespace CamelotEngine {
 		setTextureMipmapBias(texUnit, tl.getTextureMipmapBias());
 		setTextureMipmapBias(texUnit, tl.getTextureMipmapBias());
 
 
         // Texture addressing mode
         // Texture addressing mode
-        const SamplerState::UVWAddressingMode& uvw = tl.getTextureAddressingMode();
+        const UVWAddressingMode& uvw = tl.getTextureAddressingMode();
         setTextureAddressingMode(texUnit, uvw);
         setTextureAddressingMode(texUnit, uvw);
     }
     }
-	//-----------------------------------------------------------------------
-	void RenderSystem::setVertexTexture(UINT16 unit, const TexturePtr& tex)
-	{
-		THROW_IF_NOT_RENDER_THREAD;
-
-		CM_EXCEPT(NotImplementedException, 
-			"This rendersystem does not support separate vertex texture samplers, "
-			"you should use the regular texture samplers which are shared between "
-			"the vertex and fragment units.");
-	}
     //-----------------------------------------------------------------------
     //-----------------------------------------------------------------------
     void RenderSystem::disableTextureUnit(UINT16 texUnit)
     void RenderSystem::disableTextureUnit(UINT16 texUnit)
     {
     {

+ 3 - 0
CamelotRenderer/Source/CmResources.cpp

@@ -224,6 +224,9 @@ namespace CamelotEngine
 
 
 	void Resources::create(BaseResourceHandle resource, const String& filePath, bool overwrite)
 	void Resources::create(BaseResourceHandle resource, const String& filePath, bool overwrite)
 	{
 	{
+		if(resource == nullptr)
+			CM_EXCEPT(InvalidParametersException, "Trying to save an uninitialized resource.");
+
 		if(!resource.isLoaded())
 		if(!resource.isLoaded())
 			resource.waitUntilLoaded();
 			resource.waitUntilLoaded();
 
 

+ 34 - 162
CamelotRenderer/Source/CmSamplerState.cpp

@@ -1,183 +1,55 @@
-/*
------------------------------------------------------------------------------
-This source file is part of OGRE
-    (Object-oriented Graphics Rendering Engine)
-For the latest info, see http://www.ogre3d.org
-
-Copyright (c) 2000-2011 Torus Knot Software Ltd
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
------------------------------------------------------------------------------
-*/
 #include "CmSamplerState.h"
 #include "CmSamplerState.h"
+#include "CmSamplerStateRTTI.h"
+#include "CmRenderStateManager.h"
 #include "CmException.h"
 #include "CmException.h"
 
 
-namespace CamelotEngine {
-
-	SamplerState SamplerState::EMPTY;
-    //-----------------------------------------------------------------------
-    SamplerState::SamplerState()
-		: mHwGamma(false)
-		, mMinFilter(FO_LINEAR)
-		, mMagFilter(FO_LINEAR)
-		, mMipFilter(FO_POINT)
-		, mMaxAniso(0)
-		, mMipmapBias(0)
-		, mBindingType(BT_FRAGMENT)
-    {
-		setTextureAddressingMode(TAM_WRAP);
-    }
+namespace CamelotEngine 
+{
+	SamplerState SamplerState::DEFAULT;
 
 
-    //-----------------------------------------------------------------------
-    SamplerState::SamplerState(const SamplerState& oth )
-    {
-        *this = oth;
-    }
-
-    //-----------------------------------------------------------------------
-    SamplerState::~SamplerState()
-    {
-    }
-    //-----------------------------------------------------------------------
-    SamplerState & SamplerState::operator = ( 
-        const SamplerState &oth )
-    {
-        return *this;
-    }
-	//-----------------------------------------------------------------------
-	void SamplerState::setBindingType(SamplerState::BindingType bt)
-	{
-		mBindingType = bt;
-
-	}
-	//-----------------------------------------------------------------------
-	SamplerState::BindingType SamplerState::getBindingType(void) const
+	void SamplerState::initialize(const SAMPLER_STATE_DESC& desc)
 	{
 	{
-		return mBindingType;
-	}
-	//-----------------------------------------------------------------------
-	void SamplerState::setHardwareGammaEnabled(bool g)
-	{
-		mHwGamma = g;
-	}
-	//-----------------------------------------------------------------------
-	bool SamplerState::isHardwareGammaEnabled() const
-	{
-		return mHwGamma;
-	}
-    //-----------------------------------------------------------------------
-    const SamplerState::UVWAddressingMode& 
-	SamplerState::getTextureAddressingMode(void) const
-    {
-        return mAddressMode;
-    }
-    //-----------------------------------------------------------------------
-    void SamplerState::setTextureAddressingMode(
-		SamplerState::TextureAddressingMode tam)
-    {
-        mAddressMode.u = tam;
-        mAddressMode.v = tam;
-        mAddressMode.w = tam;
-    }
-    //-----------------------------------------------------------------------
-    void SamplerState::setTextureAddressingMode(
-		SamplerState::TextureAddressingMode u, 
-		SamplerState::TextureAddressingMode v,
-		SamplerState::TextureAddressingMode w)
-    {
-        mAddressMode.u = u;
-        mAddressMode.v = v;
-        mAddressMode.w = w;
-    }
-    //-----------------------------------------------------------------------
-    void SamplerState::setTextureAddressingMode(
-		const SamplerState::UVWAddressingMode& uvw)
-    {
-        mAddressMode = uvw;
-    }
-	//-----------------------------------------------------------------------
-	void SamplerState::setTextureFiltering(TextureFilterOptions filterType)
-	{
-        switch (filterType)
-        {
-        case TFO_NONE:
-            setTextureFiltering(FO_POINT, FO_POINT, FO_NONE);
-            break;
-        case TFO_BILINEAR:
-            setTextureFiltering(FO_LINEAR, FO_LINEAR, FO_POINT);
-            break;
-        case TFO_TRILINEAR:
-            setTextureFiltering(FO_LINEAR, FO_LINEAR, FO_LINEAR);
-            break;
-        case TFO_ANISOTROPIC:
-            setTextureFiltering(FO_ANISOTROPIC, FO_ANISOTROPIC, FO_LINEAR);
-            break;
-        }
+		mData = desc;
 	}
 	}
-	//-----------------------------------------------------------------------
-    void SamplerState::setTextureFiltering(FilterType ft, FilterOptions fo)
-    {
-        switch (ft)
-        {
-        case FT_MIN:
-            mMinFilter = fo;
-            break;
-        case FT_MAG:
-            mMagFilter = fo;
-            break;
-        case FT_MIP:
-            mMipFilter = fo;
-            break;
-        }
-    }
-	//-----------------------------------------------------------------------
-    void SamplerState::setTextureFiltering(FilterOptions minFilter, 
-        FilterOptions magFilter, FilterOptions mipFilter)
-    {
-        mMinFilter = minFilter;
-        mMagFilter = magFilter;
-        mMipFilter = mipFilter;
-    }
-	//-----------------------------------------------------------------------
+
 	FilterOptions SamplerState::getTextureFiltering(FilterType ft) const
 	FilterOptions SamplerState::getTextureFiltering(FilterType ft) const
 	{
 	{
         switch (ft)
         switch (ft)
         {
         {
         case FT_MIN:
         case FT_MIN:
-            return mMinFilter;
+            return mData.minFilter;
         case FT_MAG:
         case FT_MAG:
-            return mMagFilter;
+            return mData.magFilter;
         case FT_MIP:
         case FT_MIP:
-            return mMipFilter;
+            return mData.mipFilter;
         }
         }
-		// to keep compiler happy
-		return mMinFilter;
+
+		return mData.minFilter;
 	}
 	}
 
 
-	//-----------------------------------------------------------------------
-	void SamplerState::setTextureAnisotropy(unsigned int maxAniso)
+	const Color& SamplerState::getBorderColor(UINT32 idx)
 	{
 	{
-		mMaxAniso = maxAniso;
+		assert(idx >= 0 && idx < 4);
+
+		return mData.borderColor[idx];
 	}
 	}
-	//-----------------------------------------------------------------------
-	unsigned int SamplerState::getTextureAnisotropy() const
+
+	SamplerStatePtr SamplerState::create(const SAMPLER_STATE_DESC& desc)
+	{
+		return RenderStateManager::instance().createSamplerState(desc);
+	}
+
+	/************************************************************************/
+	/* 								RTTI		                     		*/
+	/************************************************************************/
+
+	RTTITypeBase* SamplerState::getRTTIStatic()
+	{
+		return SamplerStateRTTI::instance();
+	}
+
+	RTTITypeBase* SamplerState::getRTTI() const
 	{
 	{
-        return mMaxAniso;
+		return SamplerState::getRTTIStatic();
 	}
 	}
 }
 }