Explorar o código

Added shader params
Fixed an issue with OpenGL failing when testing valid FBO textures

Marko Pintera %!s(int64=13) %!d(string=hai) anos
pai
achega
4ec92954ca
Modificáronse 35 ficheiros con 1043 adicións e 428 borrados
  1. 54 51
      CamelotClient/CamelotClient.cpp
  2. 3 3
      CamelotD3D11RenderSystem/Include/CmD3D11GpuParamBlock.h
  3. 2 2
      CamelotD3D11RenderSystem/Include/CmD3D11HardwareBufferManager.h
  4. 4 4
      CamelotD3D11RenderSystem/Source/CmD3D11GpuParamBlock.cpp
  5. 43 38
      CamelotD3D11RenderSystem/Source/CmD3D11HLSLParamParser.cpp
  6. 2 2
      CamelotD3D11RenderSystem/Source/CmD3D11HardwareBufferManager.cpp
  7. 1 1
      CamelotD3D11RenderSystem/Source/CmD3D11RenderSystem.cpp
  8. 32 31
      CamelotD3D9Renderer/Include/CmD3D9HLSLParamParser.h
  9. 2 2
      CamelotD3D9Renderer/Include/CmD3D9HardwareBufferManager.h
  10. 2 2
      CamelotD3D9Renderer/Source/CmD3D9HardwareBufferManager.cpp
  11. 40 40
      CamelotD3D9Renderer/Source/CmD3D9RenderSystem.cpp
  12. 4 3
      CamelotGLRenderer/Include/CmGLGpuParamBlock.h
  13. 2 2
      CamelotGLRenderer/Include/CmGLHardwareBufferManager.h
  14. 5 0
      CamelotGLRenderer/Include/CmGLRenderSystem.h
  15. 4 4
      CamelotGLRenderer/Source/CmGLGpuParamBlock.cpp
  16. 2 2
      CamelotGLRenderer/Source/CmGLHardwareBufferManager.cpp
  17. 41 4
      CamelotGLRenderer/Source/CmGLRenderSystem.cpp
  18. 12 31
      CamelotGLRenderer/Source/CmGLRenderTexture.cpp
  19. 33 31
      CamelotGLRenderer/Source/GLSL/include/CmGLSLParamParser.h
  20. 6 6
      CamelotRenderer/CamelotRenderer.vcxproj.filters
  21. 55 0
      CamelotRenderer/Include/CmCommonEnums.h
  22. 6 5
      CamelotRenderer/Include/CmGpuParamBlock.h
  23. 10 56
      CamelotRenderer/Include/CmGpuParamDesc.h
  24. 7 6
      CamelotRenderer/Include/CmGpuParams.h
  25. 2 0
      CamelotRenderer/Include/CmGpuProgram.h
  26. 1 1
      CamelotRenderer/Include/CmHardwareBufferManager.h
  27. 16 3
      CamelotRenderer/Include/CmMaterial.h
  28. 4 3
      CamelotRenderer/Include/CmPrerequisites.h
  29. 37 0
      CamelotRenderer/Include/CmShader.h
  30. 10 10
      CamelotRenderer/Source/CmGpuParamBlock.cpp
  31. 20 13
      CamelotRenderer/Source/CmGpuParams.cpp
  32. 519 34
      CamelotRenderer/Source/CmMaterial.cpp
  33. 18 18
      CamelotRenderer/Source/CmMaterialRTTI.cpp
  34. 40 0
      CamelotRenderer/Source/CmShader.cpp
  35. 4 20
      CamelotRenderer/TODO.txt

+ 54 - 51
CamelotClient/CamelotClient.cpp

@@ -26,9 +26,9 @@ using namespace CamelotEngine;
 
 
 int _tmain(int argc, _TCHAR* argv[])
 int _tmain(int argc, _TCHAR* argv[])
 {
 {
-	//gApplication().startUp("CamelotGLRenderSystem", "CamelotForwardRenderer");
+	gApplication().startUp("CamelotGLRenderSystem", "CamelotForwardRenderer");
 	//gApplication().startUp("CamelotD3D9RenderSystem", "CamelotForwardRenderer");
 	//gApplication().startUp("CamelotD3D9RenderSystem", "CamelotForwardRenderer");
-	gApplication().startUp("CamelotD3D11RenderSystem", "CamelotForwardRenderer");
+	//gApplication().startUp("CamelotD3D11RenderSystem", "CamelotForwardRenderer");
 
 
 	RenderSystem* renderSystem = RenderSystem::instancePtr();
 	RenderSystem* renderSystem = RenderSystem::instancePtr();
 	RenderWindowPtr renderWindow = gApplication().getPrimaryRenderWindow();
 	RenderWindowPtr renderWindow = gApplication().getPrimaryRenderWindow();
@@ -74,28 +74,28 @@ int _tmain(int argc, _TCHAR* argv[])
 	//vertProg =  HighLevelGpuProgram::create(vertShaderCode, "vs_main", "hlsl", GPT_VERTEX_PROGRAM, GPP_VS_2_0);
 	//vertProg =  HighLevelGpuProgram::create(vertShaderCode, "vs_main", "hlsl", GPT_VERTEX_PROGRAM, GPP_VS_2_0);
 
 
 	/////////////////// HLSL 11 SHADERS //////////////////////////
 	/////////////////// HLSL 11 SHADERS //////////////////////////
-	String fragShaderCode = "SamplerState samp : register(s0);			\
-							Texture2D tex : register(t0); \
-							float4 ps_main(in float4 inPos : SV_Position, float2 uv : TEXCOORD0) : SV_Target		\
-							{														\
-							float4 color = tex.Sample(samp, uv);				\
-							return color;										\
-							}";
-
-	fragProg =  HighLevelGpuProgram::create(fragShaderCode, "ps_main", "hlsl", GPT_FRAGMENT_PROGRAM, GPP_PS_4_0);
-
-	String vertShaderCode = "float4x4 matViewProjection;	\
-							void vs_main(										\
-							in float4 inPos : POSITION,							\
-							in float2 uv : TEXCOORD0,								\
-							out float4 oPosition : SV_Position,					\
-							out float2 oUv : TEXCOORD0)							\
-							{														\
-							oPosition = mul(matViewProjection, inPos);			\
-							oUv = uv;											\
-							}";
-
-	vertProg =  HighLevelGpuProgram::create(vertShaderCode, "vs_main", "hlsl", GPT_VERTEX_PROGRAM, GPP_VS_4_0);
+	//String fragShaderCode = "SamplerState samp : register(s0);			\
+	//						Texture2D tex : register(t0); \
+	//						float4 ps_main(in float4 inPos : SV_Position, float2 uv : TEXCOORD0) : SV_Target		\
+	//						{														\
+	//						float4 color = tex.Sample(samp, uv);				\
+	//						return color;										\
+	//						}";
+
+	//fragProg =  HighLevelGpuProgram::create(fragShaderCode, "ps_main", "hlsl", GPT_FRAGMENT_PROGRAM, GPP_PS_4_0);
+
+	//String vertShaderCode = "float4x4 matViewProjection;	\
+	//						void vs_main(										\
+	//						in float4 inPos : POSITION,							\
+	//						in float2 uv : TEXCOORD0,								\
+	//						out float4 oPosition : SV_Position,					\
+	//						out float2 oUv : TEXCOORD0)							\
+	//						{														\
+	//						oPosition = mul(matViewProjection, inPos);			\
+	//						oUv = uv;											\
+	//						}";
+
+	//vertProg =  HighLevelGpuProgram::create(vertShaderCode, "vs_main", "hlsl", GPT_VERTEX_PROGRAM, GPP_VS_4_0);
 
 
 	/////////////////// CG SHADERS //////////////////////////
 	/////////////////// CG SHADERS //////////////////////////
 	//String fragShaderCode = "sampler2D tex;					\
 	//String fragShaderCode = "sampler2D tex;					\
@@ -121,31 +121,31 @@ int _tmain(int argc, _TCHAR* argv[])
 	//vertProg =  HighLevelGpuProgram::create(vertShaderCode, "vs_main", "cg", GPT_VERTEX_PROGRAM, GPP_VS_2_0);
 	//vertProg =  HighLevelGpuProgram::create(vertShaderCode, "vs_main", "cg", GPT_VERTEX_PROGRAM, GPP_VS_2_0);
 
 
 	///////////////// GLSL SHADERS ////////////////////////////
 	///////////////// GLSL SHADERS ////////////////////////////
-	//String fragShaderCode = " #version 400 \n \
-	//						  uniform sampler2D tex; \
-	//						  in vec2 texcoord0; \
-	//						  out vec4 fragColor; \
-	//						  void main() \
-	//						  {\
-	//							  vec4 texColor = texture2D(tex, texcoord0.st);\
-	//							  fragColor = texColor; \
-	//						  }";
-
-	//fragProg = HighLevelGpuProgram::create(fragShaderCode, "main", "glsl", GPT_FRAGMENT_PROGRAM, GPP_PS_2_0);
-
-	//// TODO - Make sure to document the strict input parameter naming. (Exact supported names are in GLSLParamParser)
-	//String vertShaderCode = "#version 400 \n \
-	//						 uniform mainFragBlock { mat4 matViewProjection; }; \
-	//						 in vec4 cm_position; \
-	//						 in vec2 cm_texcoord0; \
-	//						 out vec2 texcoord0; \
-	//						 void main() \
-	//						 { \
-	//							texcoord0 = cm_texcoord0; \
-	//							gl_Position = cm_position * matViewProjection; \
-	//						 }";
-
-	//vertProg = HighLevelGpuProgram::create(vertShaderCode, "main", "glsl", GPT_VERTEX_PROGRAM, GPP_VS_2_0);
+	String fragShaderCode = " #version 400 \n \
+							  uniform sampler2D tex; \
+							  in vec2 texcoord0; \
+							  out vec4 fragColor; \
+							  void main() \
+							  {\
+								  vec4 texColor = texture2D(tex, texcoord0.st);\
+								  fragColor = texColor; \
+							  }";
+
+	fragProg = HighLevelGpuProgram::create(fragShaderCode, "main", "glsl", GPT_FRAGMENT_PROGRAM, GPP_PS_2_0);
+
+	// TODO - Make sure to document the strict input parameter naming. (Exact supported names are in GLSLParamParser)
+	String vertShaderCode = "#version 400 \n \
+							 uniform mainFragBlock { mat4 matViewProjection; }; \
+							 in vec4 cm_position; \
+							 in vec2 cm_texcoord0; \
+							 out vec2 texcoord0; \
+							 void main() \
+							 { \
+								texcoord0 = cm_texcoord0; \
+								gl_Position = cm_position * matViewProjection; \
+							 }";
+
+	vertProg = HighLevelGpuProgram::create(vertShaderCode, "main", "glsl", GPT_VERTEX_PROGRAM, GPP_VS_2_0);
 
 
 	HighLevelGpuProgramHandle vertProgRef(vertProg);
 	HighLevelGpuProgramHandle vertProgRef(vertProg);
 
 
@@ -158,6 +158,9 @@ int _tmain(int argc, _TCHAR* argv[])
 	fragProgRef = static_resource_cast<HighLevelGpuProgram>(gResources().load("C:\\fragProgCg.vprog"));
 	fragProgRef = static_resource_cast<HighLevelGpuProgram>(gResources().load("C:\\fragProgCg.vprog"));
 
 
 	ShaderPtr testShader = ShaderPtr(new Shader("TestShader"));
 	ShaderPtr testShader = ShaderPtr(new Shader("TestShader"));
+	testShader->addParameter("matViewProjection", "matViewProjection", GPDT_MATRIX_4X4);
+	testShader->addParameter("samp", "samp", GPOT_SAMPLER2D);
+	testShader->addParameter("tex", "tex", GPOT_TEXTURE2D);
 	TechniquePtr newTechniqueGL = testShader->addTechnique("GLRenderSystem", "ForwardRenderer");
 	TechniquePtr newTechniqueGL = testShader->addTechnique("GLRenderSystem", "ForwardRenderer");
 	PassPtr newPassGL = newTechniqueGL->addPass();
 	PassPtr newPassGL = newTechniqueGL->addPass();
 	newPassGL->setVertexProgram(vertProgRef);
 	newPassGL->setVertexProgram(vertProgRef);
@@ -193,9 +196,9 @@ int _tmain(int argc, _TCHAR* argv[])
 	dbgMesh = static_resource_cast<Mesh>(gResources().load("C:\\ExportMesh.mesh"));
 	dbgMesh = static_resource_cast<Mesh>(gResources().load("C:\\ExportMesh.mesh"));
 
 
 	testMaterial->setTexture("tex", testTex);
 	testMaterial->setTexture("tex", testTex);
-	gResources().create(testMaterial, "C:\\ExportMaterial.mat", true);
+	//gResources().create(testMaterial, "C:\\ExportMaterial.mat", true);
 
 
-	testMaterial = gResources().load("C:\\ExportMaterial.mat");
+	//testMaterial = gResources().load("C:\\ExportMaterial.mat");
 
 
 	//_ASSERT(_CrtCheckMemory());
 	//_ASSERT(_CrtCheckMemory());
 
 

+ 3 - 3
CamelotD3D11RenderSystem/Include/CmD3D11GpuParamBlock.h

@@ -5,7 +5,7 @@
 
 
 namespace CamelotEngine
 namespace CamelotEngine
 {
 {
-	class CM_D3D11_EXPORT D3D11GpuParamBlock : public GpuParamBlockBuffer
+	class CM_D3D11_EXPORT D3D11GpuParamBlock : public GpuParamBlock
 	{
 	{
 	private:
 	private:
 		struct D3D11GpuParamBlockSharedData
 		struct D3D11GpuParamBlockSharedData
@@ -14,11 +14,11 @@ namespace CamelotEngine
 		};
 		};
 
 
 	public:
 	public:
-		D3D11GpuParamBlock(const GpuParamBlockDesc& desc);
+		D3D11GpuParamBlock(const GpuParamBlockDesc& desc, GpuParamBlockUsage usage);
 		~D3D11GpuParamBlock();
 		~D3D11GpuParamBlock();
 
 
 		virtual void updateIfDirty();
 		virtual void updateIfDirty();
-		virtual GpuParamBlockBufferPtr clone() const;
+		virtual GpuParamBlockPtr clone() const;
 
 
 		ID3D11Buffer* getD3D11Buffer() const;
 		ID3D11Buffer* getD3D11Buffer() const;
 
 

+ 2 - 2
CamelotD3D11RenderSystem/Include/CmD3D11HardwareBufferManager.h

@@ -21,8 +21,8 @@ namespace CamelotEngine
 		 */
 		 */
 		IndexBufferPtr createIndexBuffer(IndexBuffer::IndexType itype, UINT32 numIndexes, GpuBufferUsage usage);
 		IndexBufferPtr createIndexBuffer(IndexBuffer::IndexType itype, UINT32 numIndexes, GpuBufferUsage usage);
 
 
-		/** @copydoc HardwareBufferManagerInterface::createGpuParamBlockBuffer */
-		GpuParamBlockBufferPtr createGpuParamBlockBuffer(const GpuParamBlockDesc& paramDesc);
+		/** @copydoc HardwareBufferManagerInterface::createGpuParamBlock */
+		GpuParamBlockPtr createGpuParamBlock(const GpuParamBlockDesc& paramDesc, GpuParamBlockUsage usage = GPBU_STATIC);
 
 
 		/**
 		/**
 		 * @copydoc HardwareBufferManagerInterface::createGpuBuffer
 		 * @copydoc HardwareBufferManagerInterface::createGpuBuffer

+ 4 - 4
CamelotD3D11RenderSystem/Source/CmD3D11GpuParamBlock.cpp

@@ -5,8 +5,8 @@
 
 
 namespace CamelotEngine
 namespace CamelotEngine
 {
 {
-	D3D11GpuParamBlock::D3D11GpuParamBlock(const GpuParamBlockDesc& desc)
-		:GpuParamBlockBuffer(desc), mD3D11SharedData(nullptr)
+	D3D11GpuParamBlock::D3D11GpuParamBlock(const GpuParamBlockDesc& desc, GpuParamBlockUsage usage)
+		:GpuParamBlock(desc, usage), mD3D11SharedData(nullptr)
 	{
 	{
 		mD3D11SharedData = new D3D11GpuParamBlockSharedData();
 		mD3D11SharedData = new D3D11GpuParamBlockSharedData();
 	}
 	}
@@ -37,10 +37,10 @@ namespace CamelotEngine
 			mD3D11SharedData->mBuffer->writeData(0, mSize, mData, true);
 			mD3D11SharedData->mBuffer->writeData(0, mSize, mData, true);
 		}
 		}
 
 
-		GpuParamBlockBuffer::updateIfDirty();
+		GpuParamBlock::updateIfDirty();
 	}
 	}
 
 
-	GpuParamBlockBufferPtr D3D11GpuParamBlock::clone() const
+	GpuParamBlockPtr D3D11GpuParamBlock::clone() const
 	{
 	{
 		std::shared_ptr<D3D11GpuParamBlock> clonedParamBlock(new D3D11GpuParamBlock(*this));
 		std::shared_ptr<D3D11GpuParamBlock> clonedParamBlock(new D3D11GpuParamBlock(*this));
 		clonedParamBlock->mData = new UINT8[mSize];
 		clonedParamBlock->mData = new UINT8[mSize];

+ 43 - 38
CamelotD3D11RenderSystem/Source/CmD3D11HLSLParamParser.cpp

@@ -85,74 +85,79 @@ namespace CamelotEngine
 				blockDesc.slot = resourceDesc.BindPoint + i;
 				blockDesc.slot = resourceDesc.BindPoint + i;
 				blockDesc.blockSize = 0; // Calculated manually as we add parameters
 				blockDesc.blockSize = 0; // Calculated manually as we add parameters
 
 
+				if(resourceDesc.Name == "$Global" || resourceDesc.Name == "$Param") // Special buffers, as defined by DX11 docs
+					blockDesc.isShareable = false;
+				else
+					blockDesc.isShareable = true;
+
 				desc.paramBlocks.insert(std::make_pair(blockDesc.name, blockDesc));
 				desc.paramBlocks.insert(std::make_pair(blockDesc.name, blockDesc));
 			}
 			}
 			else
 			else
 			{
 			{
-				GpuParamSpecialDesc memberDesc;
+				GpuParamObjectDesc memberDesc;
 				memberDesc.name = resourceDesc.Name;
 				memberDesc.name = resourceDesc.Name;
 				memberDesc.slot = resourceDesc.BindPoint + i;
 				memberDesc.slot = resourceDesc.BindPoint + i;
-				memberDesc.type = GST_UNKNOWN;
+				memberDesc.type = GPOT_UNKNOWN;
 
 
 				switch(resourceDesc.Type)
 				switch(resourceDesc.Type)
 				{
 				{
 				case D3D_SIT_SAMPLER:
 				case D3D_SIT_SAMPLER:
-					memberDesc.type = GST_SAMPLER2D; // Actual dimension of the sampler doesn't matter
+					memberDesc.type = GPOT_SAMPLER2D; // Actual dimension of the sampler doesn't matter
 					desc.samplers.insert(std::make_pair(memberDesc.name, memberDesc));
 					desc.samplers.insert(std::make_pair(memberDesc.name, memberDesc));
 					break;
 					break;
 				case D3D_SIT_TEXTURE:
 				case D3D_SIT_TEXTURE:
 					switch(resourceDesc.Dimension)
 					switch(resourceDesc.Dimension)
 					{
 					{
 					case D3D_SRV_DIMENSION_TEXTURE1D:
 					case D3D_SRV_DIMENSION_TEXTURE1D:
-						memberDesc.type = GST_TEXTURE1D;
+						memberDesc.type = GPOT_TEXTURE1D;
 						break;
 						break;
 					case D3D_SRV_DIMENSION_TEXTURE2D:
 					case D3D_SRV_DIMENSION_TEXTURE2D:
-						memberDesc.type = GST_TEXTURE2D;
+						memberDesc.type = GPOT_TEXTURE2D;
 						break;
 						break;
 					case D3D_SRV_DIMENSION_TEXTURE3D:
 					case D3D_SRV_DIMENSION_TEXTURE3D:
-						memberDesc.type = GST_TEXTURE3D;
+						memberDesc.type = GPOT_TEXTURE3D;
 						break;
 						break;
 					case D3D_SRV_DIMENSION_TEXTURECUBE:
 					case D3D_SRV_DIMENSION_TEXTURECUBE:
-						memberDesc.type = GST_TEXTURECUBE;
+						memberDesc.type = GPOT_TEXTURECUBE;
 						break;
 						break;
 					default:
 					default:
 						LOGWRN("Skipping texture because it has unsupported dimension: " + toString(resourceDesc.Dimension));
 						LOGWRN("Skipping texture because it has unsupported dimension: " + toString(resourceDesc.Dimension));
 					}
 					}
 
 
-					if(memberDesc.type != GST_UNKNOWN)
+					if(memberDesc.type != GPOT_UNKNOWN)
 						desc.textures.insert(std::make_pair(memberDesc.name, memberDesc));
 						desc.textures.insert(std::make_pair(memberDesc.name, memberDesc));
 
 
 					break;
 					break;
 				case D3D_SIT_STRUCTURED:
 				case D3D_SIT_STRUCTURED:
-					memberDesc.type = GST_STRUCTURED_BUFFER;
+					memberDesc.type = GPOT_STRUCTURED_BUFFER;
 					desc.buffers.insert(std::make_pair(memberDesc.name, memberDesc));
 					desc.buffers.insert(std::make_pair(memberDesc.name, memberDesc));
 					break;
 					break;
 				case D3D_SIT_BYTEADDRESS:
 				case D3D_SIT_BYTEADDRESS:
-					memberDesc.type = GST_BYTE_BUFFER;
+					memberDesc.type = GPOT_BYTE_BUFFER;
 					desc.buffers.insert(std::make_pair(memberDesc.name, memberDesc));
 					desc.buffers.insert(std::make_pair(memberDesc.name, memberDesc));
 					break;
 					break;
 				case D3D11_SIT_UAV_RWTYPED:
 				case D3D11_SIT_UAV_RWTYPED:
-					memberDesc.type = GST_RWTYPED_BUFFER;
+					memberDesc.type = GPOT_RWTYPED_BUFFER;
 					desc.buffers.insert(std::make_pair(memberDesc.name, memberDesc));
 					desc.buffers.insert(std::make_pair(memberDesc.name, memberDesc));
 					break;
 					break;
 				case D3D11_SIT_UAV_RWSTRUCTURED:
 				case D3D11_SIT_UAV_RWSTRUCTURED:
-					memberDesc.type = GST_RWSTRUCTURED_BUFFER;
+					memberDesc.type = GPOT_RWSTRUCTURED_BUFFER;
 					desc.buffers.insert(std::make_pair(memberDesc.name, memberDesc));
 					desc.buffers.insert(std::make_pair(memberDesc.name, memberDesc));
 					break;
 					break;
 				case D3D11_SIT_UAV_RWBYTEADDRESS:
 				case D3D11_SIT_UAV_RWBYTEADDRESS:
-					memberDesc.type = GST_RWBYTE_BUFFER;
+					memberDesc.type = GPOT_RWBYTE_BUFFER;
 					desc.buffers.insert(std::make_pair(memberDesc.name, memberDesc));
 					desc.buffers.insert(std::make_pair(memberDesc.name, memberDesc));
 					break;
 					break;
 				case D3D_SIT_UAV_APPEND_STRUCTURED:
 				case D3D_SIT_UAV_APPEND_STRUCTURED:
-					memberDesc.type = GST_RWAPPEND_BUFFER;
+					memberDesc.type = GPOT_RWAPPEND_BUFFER;
 					desc.buffers.insert(std::make_pair(memberDesc.name, memberDesc));
 					desc.buffers.insert(std::make_pair(memberDesc.name, memberDesc));
 					break;
 					break;
 				case D3D_SIT_UAV_CONSUME_STRUCTURED:
 				case D3D_SIT_UAV_CONSUME_STRUCTURED:
-					memberDesc.type = GST_RWCONSUME_BUFFER;
+					memberDesc.type = GPOT_RWCONSUME_BUFFER;
 					desc.buffers.insert(std::make_pair(memberDesc.name, memberDesc));
 					desc.buffers.insert(std::make_pair(memberDesc.name, memberDesc));
 					break;
 					break;
 				case D3D_SIT_UAV_RWSTRUCTURED_WITH_COUNTER:
 				case D3D_SIT_UAV_RWSTRUCTURED_WITH_COUNTER:
-					memberDesc.type = GST_RWSTRUCTURED_BUFFER_WITH_COUNTER;
+					memberDesc.type = GPOT_RWSTRUCTURED_BUFFER_WITH_COUNTER;
 					desc.buffers.insert(std::make_pair(memberDesc.name, memberDesc));
 					desc.buffers.insert(std::make_pair(memberDesc.name, memberDesc));
 					break;
 					break;
 				default:
 				default:
@@ -206,7 +211,7 @@ namespace CamelotEngine
 
 
 	void D3D11HLSLParamParser::parseVariable(D3D11_SHADER_TYPE_DESC& varTypeDesc, D3D11_SHADER_VARIABLE_DESC& varDesc, GpuParamDesc& desc, GpuParamBlockDesc& paramBlock)
 	void D3D11HLSLParamParser::parseVariable(D3D11_SHADER_TYPE_DESC& varTypeDesc, D3D11_SHADER_VARIABLE_DESC& varDesc, GpuParamDesc& desc, GpuParamBlockDesc& paramBlock)
 	{
 	{
-		GpuParamMemberDesc memberDesc;
+		GpuParamDataDesc memberDesc;
 		memberDesc.name = varDesc.Name;
 		memberDesc.name = varDesc.Name;
 		memberDesc.paramBlockSlot = paramBlock.slot;
 		memberDesc.paramBlockSlot = paramBlock.slot;
 		memberDesc.arraySize = varTypeDesc.Elements == 0 ? 1 : varTypeDesc.Elements;
 		memberDesc.arraySize = varTypeDesc.Elements == 0 ? 1 : varTypeDesc.Elements;
@@ -223,13 +228,13 @@ namespace CamelotEngine
 				switch(varTypeDesc.Type)
 				switch(varTypeDesc.Type)
 				{
 				{
 				case D3D_SVT_BOOL:
 				case D3D_SVT_BOOL:
-					memberDesc.type = GMT_BOOL;
+					memberDesc.type = GPDT_BOOL;
 					break;
 					break;
 				case D3D_SVT_INT:
 				case D3D_SVT_INT:
-					memberDesc.type = GMT_INT1;
+					memberDesc.type = GPDT_INT1;
 					break;
 					break;
 				case D3D_SVT_FLOAT:
 				case D3D_SVT_FLOAT:
-					memberDesc.type = GMT_FLOAT1;
+					memberDesc.type = GPDT_FLOAT1;
 					break;
 					break;
 				default:
 				default:
 					LOGWRN("Skipping variable because it has unsupported type: " + toString(varTypeDesc.Type));
 					LOGWRN("Skipping variable because it has unsupported type: " + toString(varTypeDesc.Type));
@@ -245,16 +250,16 @@ namespace CamelotEngine
 						switch(varTypeDesc.Columns)
 						switch(varTypeDesc.Columns)
 						{
 						{
 						case 1:
 						case 1:
-							memberDesc.type = GMT_INT1;
+							memberDesc.type = GPDT_INT1;
 							break;
 							break;
 						case 2:
 						case 2:
-							memberDesc.type = GMT_INT2;
+							memberDesc.type = GPDT_INT2;
 							break;
 							break;
 						case 3:
 						case 3:
-							memberDesc.type = GMT_INT3;
+							memberDesc.type = GPDT_INT3;
 							break;
 							break;
 						case 4:
 						case 4:
-							memberDesc.type = GMT_INT4;
+							memberDesc.type = GPDT_INT4;
 							break;
 							break;
 						}
 						}
 					}
 					}
@@ -265,16 +270,16 @@ namespace CamelotEngine
 						switch(varTypeDesc.Columns)
 						switch(varTypeDesc.Columns)
 						{
 						{
 						case 1:
 						case 1:
-							memberDesc.type = GMT_FLOAT1;
+							memberDesc.type = GPDT_FLOAT1;
 							break;
 							break;
 						case 2:
 						case 2:
-							memberDesc.type = GMT_FLOAT2;
+							memberDesc.type = GPDT_FLOAT2;
 							break;
 							break;
 						case 3:
 						case 3:
-							memberDesc.type = GMT_FLOAT3;
+							memberDesc.type = GPDT_FLOAT3;
 							break;
 							break;
 						case 4:
 						case 4:
-							memberDesc.type = GMT_FLOAT4;
+							memberDesc.type = GPDT_FLOAT4;
 							break;
 							break;
 						}
 						}
 					}
 					}
@@ -291,13 +296,13 @@ namespace CamelotEngine
 				switch(varTypeDesc.Columns)
 				switch(varTypeDesc.Columns)
 				{
 				{
 				case 2:
 				case 2:
-					memberDesc.type = GMT_MATRIX_2X2;
+					memberDesc.type = GPDT_MATRIX_2X2;
 					break;
 					break;
 				case 3:
 				case 3:
-					memberDesc.type = GMT_MATRIX_2X3;
+					memberDesc.type = GPDT_MATRIX_2X3;
 					break;
 					break;
 				case 4:
 				case 4:
-					memberDesc.type = GMT_MATRIX_2X4;
+					memberDesc.type = GPDT_MATRIX_2X4;
 					break;
 					break;
 				}
 				}
 				break;
 				break;
@@ -305,13 +310,13 @@ namespace CamelotEngine
 				switch(varTypeDesc.Columns)
 				switch(varTypeDesc.Columns)
 				{
 				{
 				case 2:
 				case 2:
-					memberDesc.type = GMT_MATRIX_3X2;
+					memberDesc.type = GPDT_MATRIX_3X2;
 					break;
 					break;
 				case 3:
 				case 3:
-					memberDesc.type = GMT_MATRIX_3X3;
+					memberDesc.type = GPDT_MATRIX_3X3;
 					break;
 					break;
 				case 4:
 				case 4:
-					memberDesc.type = GMT_MATRIX_3X4;
+					memberDesc.type = GPDT_MATRIX_3X4;
 					break;
 					break;
 				}
 				}
 				break;
 				break;
@@ -319,20 +324,20 @@ namespace CamelotEngine
 				switch(varTypeDesc.Columns)
 				switch(varTypeDesc.Columns)
 				{
 				{
 				case 2:
 				case 2:
-					memberDesc.type = GMT_MATRIX_4X2;
+					memberDesc.type = GPDT_MATRIX_4X2;
 					break;
 					break;
 				case 3:
 				case 3:
-					memberDesc.type = GMT_MATRIX_4X3;
+					memberDesc.type = GPDT_MATRIX_4X3;
 					break;
 					break;
 				case 4:
 				case 4:
-					memberDesc.type = GMT_MATRIX_4X4;
+					memberDesc.type = GPDT_MATRIX_4X4;
 					break;
 					break;
 				}
 				}
 				break;
 				break;
 			}
 			}
 			break;
 			break;
 		case D3D_SVC_STRUCT:
 		case D3D_SVC_STRUCT:
-			memberDesc.type = GMT_STRUCT;
+			memberDesc.type = GPDT_STRUCT;
 			break;
 			break;
 		default:
 		default:
 			LOGWRN("Skipping variable because it has unsupported class: " + toString(varTypeDesc.Class));
 			LOGWRN("Skipping variable because it has unsupported class: " + toString(varTypeDesc.Class));

+ 2 - 2
CamelotD3D11RenderSystem/Source/CmD3D11HardwareBufferManager.cpp

@@ -44,9 +44,9 @@ namespace CamelotEngine
 		return IndexBufferPtr(idx);
 		return IndexBufferPtr(idx);
 	}
 	}
 
 
-	GpuParamBlockBufferPtr D3D11HardwareBufferManager::createGpuParamBlockBuffer(const GpuParamBlockDesc& blockDesc)
+	GpuParamBlockPtr D3D11HardwareBufferManager::createGpuParamBlock(const GpuParamBlockDesc& blockDesc, GpuParamBlockUsage usage)
 	{
 	{
-		return GpuParamBlockBufferPtr(new D3D11GpuParamBlock(blockDesc));
+		return GpuParamBlockPtr(new D3D11GpuParamBlock(blockDesc, usage));
 	}
 	}
 
 
 	GpuBufferPtr D3D11HardwareBufferManager::createGpuBuffer(UINT32 elementCount, UINT32 elementSize, 
 	GpuBufferPtr D3D11HardwareBufferManager::createGpuBuffer(UINT32 elementCount, UINT32 elementSize, 

+ 1 - 1
CamelotD3D11RenderSystem/Source/CmD3D11RenderSystem.cpp

@@ -464,7 +464,7 @@ namespace CamelotEngine
 
 
 		for(auto iter = paramDesc.paramBlocks.begin(); iter != paramDesc.paramBlocks.end(); ++iter)
 		for(auto iter = paramDesc.paramBlocks.begin(); iter != paramDesc.paramBlocks.end(); ++iter)
 		{
 		{
-			GpuParamBlockBufferPtr currentBlock = params->getParamBlock(iter->second.slot);
+			GpuParamBlockPtr currentBlock = params->getParamBlock(iter->second.slot);
 
 
 			if(currentBlock != nullptr)
 			if(currentBlock != nullptr)
 			{
 			{

+ 32 - 31
CamelotD3D9Renderer/Include/CmD3D9HLSLParamParser.h

@@ -15,7 +15,7 @@ namespace CamelotEngine
 
 
 	private:
 	private:
 		void processParameter(GpuParamBlockDesc& blockDesc, D3DXHANDLE parent, String prefix, UINT32 index);
 		void processParameter(GpuParamBlockDesc& blockDesc, D3DXHANDLE parent, String prefix, UINT32 index);
-		void populateParamMemberDesc(GpuParamMemberDesc& memberDesc, D3DXCONSTANT_DESC& d3dDesc);
+		void populateParamMemberDesc(GpuParamDataDesc& memberDesc, D3DXCONSTANT_DESC& d3dDesc);
 
 
 	private:
 	private:
 		LPD3DXCONSTANTTABLE mpConstTable;
 		LPD3DXCONSTANTTABLE mpConstTable;
@@ -41,6 +41,7 @@ namespace CamelotEngine
 		blockDesc.name = name;
 		blockDesc.name = name;
 		blockDesc.slot = 0;
 		blockDesc.slot = 0;
 		blockDesc.blockSize = 0;
 		blockDesc.blockSize = 0;
+		blockDesc.isShareable = false;
 
 
 		// Iterate over the constants
 		// Iterate over the constants
 		for (UINT32 i = 0; i < desc.Constants; ++i)
 		for (UINT32 i = 0; i < desc.Constants; ++i)
@@ -91,7 +92,7 @@ namespace CamelotEngine
 			// Process params
 			// Process params
 			if (desc.Type == D3DXPT_FLOAT || desc.Type == D3DXPT_INT || desc.Type == D3DXPT_BOOL)
 			if (desc.Type == D3DXPT_FLOAT || desc.Type == D3DXPT_INT || desc.Type == D3DXPT_BOOL)
 			{
 			{
-				GpuParamMemberDesc memberDesc;
+				GpuParamDataDesc memberDesc;
 				memberDesc.gpuMemOffset = desc.RegisterIndex;
 				memberDesc.gpuMemOffset = desc.RegisterIndex;
 				memberDesc.cpuMemOffset = blockDesc.blockSize;
 				memberDesc.cpuMemOffset = blockDesc.blockSize;
 				memberDesc.paramBlockSlot = blockDesc.slot;
 				memberDesc.paramBlockSlot = blockDesc.slot;
@@ -107,31 +108,31 @@ namespace CamelotEngine
 			}
 			}
 			else if(desc.Type == D3DXPT_SAMPLER1D || desc.Type == D3DXPT_SAMPLER2D || desc.Type == D3DXPT_SAMPLER3D || desc.Type == D3DXPT_SAMPLERCUBE)
 			else if(desc.Type == D3DXPT_SAMPLER1D || desc.Type == D3DXPT_SAMPLER2D || desc.Type == D3DXPT_SAMPLER3D || desc.Type == D3DXPT_SAMPLERCUBE)
 			{
 			{
-				GpuParamSpecialDesc samplerDesc;
+				GpuParamObjectDesc samplerDesc;
 				samplerDesc.name = paramName;
 				samplerDesc.name = paramName;
 				samplerDesc.slot = desc.RegisterIndex;
 				samplerDesc.slot = desc.RegisterIndex;
 
 
-				GpuParamSpecialDesc textureDesc;
+				GpuParamObjectDesc textureDesc;
 				textureDesc.name = paramName;
 				textureDesc.name = paramName;
 				textureDesc.slot = desc.RegisterIndex;
 				textureDesc.slot = desc.RegisterIndex;
 
 
 				switch(desc.Type)
 				switch(desc.Type)
 				{
 				{
 				case D3DXPT_SAMPLER1D:
 				case D3DXPT_SAMPLER1D:
-					samplerDesc.type = GST_SAMPLER1D;
-					textureDesc.type = GST_TEXTURE1D;
+					samplerDesc.type = GPOT_SAMPLER1D;
+					textureDesc.type = GPOT_TEXTURE1D;
 					break;
 					break;
 				case D3DXPT_SAMPLER2D:
 				case D3DXPT_SAMPLER2D:
-					samplerDesc.type = GST_SAMPLER2D;
-					textureDesc.type = GST_TEXTURE2D;
+					samplerDesc.type = GPOT_SAMPLER2D;
+					textureDesc.type = GPOT_TEXTURE2D;
 					break;
 					break;
 				case D3DXPT_SAMPLER3D:
 				case D3DXPT_SAMPLER3D:
-					samplerDesc.type = GST_SAMPLER3D;
-					textureDesc.type = GST_TEXTURE3D;
+					samplerDesc.type = GPOT_SAMPLER3D;
+					textureDesc.type = GPOT_TEXTURE3D;
 					break;
 					break;
 				case D3DXPT_SAMPLERCUBE:
 				case D3DXPT_SAMPLERCUBE:
-					samplerDesc.type = GST_SAMPLERCUBE;
-					textureDesc.type = GST_TEXTURECUBE;
+					samplerDesc.type = GPOT_SAMPLERCUBE;
+					textureDesc.type = GPOT_TEXTURECUBE;
 					break;
 					break;
 				default:
 				default:
 					CM_EXCEPT(InternalErrorException, "Invalid sampler type: " + toString(desc.Type) + " for parameter " + paramName);
 					CM_EXCEPT(InternalErrorException, "Invalid sampler type: " + toString(desc.Type) + " for parameter " + paramName);
@@ -147,7 +148,7 @@ namespace CamelotEngine
 		}
 		}
 	}
 	}
 
 
-	void D3D9HLSLParamParser::populateParamMemberDesc(GpuParamMemberDesc& memberDesc, D3DXCONSTANT_DESC& d3dDesc)
+	void D3D9HLSLParamParser::populateParamMemberDesc(GpuParamDataDesc& memberDesc, D3DXCONSTANT_DESC& d3dDesc)
 	{
 	{
 		memberDesc.arraySize = d3dDesc.Elements;
 		memberDesc.arraySize = d3dDesc.Elements;
 		switch(d3dDesc.Type)
 		switch(d3dDesc.Type)
@@ -156,19 +157,19 @@ namespace CamelotEngine
 			switch(d3dDesc.Columns)
 			switch(d3dDesc.Columns)
 			{
 			{
 			case 1:
 			case 1:
-				memberDesc.type = GMT_INT1;
+				memberDesc.type = GPDT_INT1;
 				memberDesc.elementSize = 4;
 				memberDesc.elementSize = 4;
 				break;
 				break;
 			case 2:
 			case 2:
-				memberDesc.type = GMT_INT2;
+				memberDesc.type = GPDT_INT2;
 				memberDesc.elementSize = 4;
 				memberDesc.elementSize = 4;
 				break;
 				break;
 			case 3:
 			case 3:
-				memberDesc.type = GMT_INT3;
+				memberDesc.type = GPDT_INT3;
 				memberDesc.elementSize = 4;
 				memberDesc.elementSize = 4;
 				break;
 				break;
 			case 4:
 			case 4:
-				memberDesc.type = GMT_INT4;
+				memberDesc.type = GPDT_INT4;
 				memberDesc.elementSize = 4;
 				memberDesc.elementSize = 4;
 				break;
 				break;
 			} // columns
 			} // columns
@@ -193,15 +194,15 @@ namespace CamelotEngine
 						switch(secondDim)
 						switch(secondDim)
 						{
 						{
 						case 2:
 						case 2:
-							memberDesc.type = GMT_MATRIX_2X2;
+							memberDesc.type = GPDT_MATRIX_2X2;
 							memberDesc.elementSize = 8; // HLSL always packs
 							memberDesc.elementSize = 8; // HLSL always packs
 							break;
 							break;
 						case 3:
 						case 3:
-							memberDesc.type = GMT_MATRIX_2X3;
+							memberDesc.type = GPDT_MATRIX_2X3;
 							memberDesc.elementSize = 8; // HLSL always packs
 							memberDesc.elementSize = 8; // HLSL always packs
 							break;
 							break;
 						case 4:
 						case 4:
-							memberDesc.type = GMT_MATRIX_2X4;
+							memberDesc.type = GPDT_MATRIX_2X4;
 							memberDesc.elementSize = 8; 
 							memberDesc.elementSize = 8; 
 							break;
 							break;
 						} // columns
 						} // columns
@@ -210,15 +211,15 @@ namespace CamelotEngine
 						switch(secondDim)
 						switch(secondDim)
 						{
 						{
 						case 2:
 						case 2:
-							memberDesc.type = GMT_MATRIX_3X2;
+							memberDesc.type = GPDT_MATRIX_3X2;
 							memberDesc.elementSize = 12; // HLSL always packs
 							memberDesc.elementSize = 12; // HLSL always packs
 							break;
 							break;
 						case 3:
 						case 3:
-							memberDesc.type = GMT_MATRIX_3X3;
+							memberDesc.type = GPDT_MATRIX_3X3;
 							memberDesc.elementSize = 12; // HLSL always packs
 							memberDesc.elementSize = 12; // HLSL always packs
 							break;
 							break;
 						case 4:
 						case 4:
-							memberDesc.type = GMT_MATRIX_3X4;
+							memberDesc.type = GPDT_MATRIX_3X4;
 							memberDesc.elementSize = 12; 
 							memberDesc.elementSize = 12; 
 							break;
 							break;
 						} // columns
 						} // columns
@@ -227,15 +228,15 @@ namespace CamelotEngine
 						switch(secondDim)
 						switch(secondDim)
 						{
 						{
 						case 2:
 						case 2:
-							memberDesc.type = GMT_MATRIX_4X2;
+							memberDesc.type = GPDT_MATRIX_4X2;
 							memberDesc.elementSize = 16; // HLSL always packs
 							memberDesc.elementSize = 16; // HLSL always packs
 							break;
 							break;
 						case 3:
 						case 3:
-							memberDesc.type = GMT_MATRIX_4X3;
+							memberDesc.type = GPDT_MATRIX_4X3;
 							memberDesc.elementSize = 16; // HLSL always packs
 							memberDesc.elementSize = 16; // HLSL always packs
 							break;
 							break;
 						case 4:
 						case 4:
-							memberDesc.type = GMT_MATRIX_4X4;
+							memberDesc.type = GPDT_MATRIX_4X4;
 							memberDesc.elementSize = 16; 
 							memberDesc.elementSize = 16; 
 							break;
 							break;
 						} // secondDim
 						} // secondDim
@@ -249,19 +250,19 @@ namespace CamelotEngine
 				switch(d3dDesc.Columns)
 				switch(d3dDesc.Columns)
 				{
 				{
 				case 1:
 				case 1:
-					memberDesc.type = GMT_FLOAT1;
+					memberDesc.type = GPDT_FLOAT1;
 					memberDesc.elementSize = 4;
 					memberDesc.elementSize = 4;
 					break;
 					break;
 				case 2:
 				case 2:
-					memberDesc.type = GMT_FLOAT2;
+					memberDesc.type = GPDT_FLOAT2;
 					memberDesc.elementSize = 4;
 					memberDesc.elementSize = 4;
 					break;
 					break;
 				case 3:
 				case 3:
-					memberDesc.type = GMT_FLOAT3;
+					memberDesc.type = GPDT_FLOAT3;
 					memberDesc.elementSize = 4;
 					memberDesc.elementSize = 4;
 					break;
 					break;
 				case 4:
 				case 4:
-					memberDesc.type = GMT_FLOAT4;
+					memberDesc.type = GPDT_FLOAT4;
 					memberDesc.elementSize = 4;
 					memberDesc.elementSize = 4;
 					break;
 					break;
 				} // columns
 				} // columns
@@ -269,7 +270,7 @@ namespace CamelotEngine
 			}
 			}
 			break;
 			break;
 		case D3DXPT_BOOL:
 		case D3DXPT_BOOL:
-			memberDesc.type = GMT_BOOL;
+			memberDesc.type = GPDT_BOOL;
 			memberDesc.elementSize = 1;
 			memberDesc.elementSize = 1;
 			break;
 			break;
 		default:
 		default:

+ 2 - 2
CamelotD3D9Renderer/Include/CmD3D9HardwareBufferManager.h

@@ -56,8 +56,8 @@ namespace CamelotEngine {
 		 */
 		 */
 		IndexBufferPtr createIndexBuffer(IndexBuffer::IndexType itype, UINT32 numIndexes, GpuBufferUsage usage);
 		IndexBufferPtr createIndexBuffer(IndexBuffer::IndexType itype, UINT32 numIndexes, GpuBufferUsage usage);
 
 
-		/** @copydoc HardwareBufferManager::createGpuParamBlockBuffer */
-		GpuParamBlockBufferPtr createGpuParamBlockBuffer(const GpuParamBlockDesc& paramDesc);
+		/** @copydoc HardwareBufferManager::createGpuParamBlock */
+		GpuParamBlockPtr createGpuParamBlock(const GpuParamBlockDesc& paramDesc, GpuParamBlockUsage usage = GPBU_STATIC);
 
 
 		/**
 		/**
 		 * @copydoc HardwareBufferManager::createGenericBuffer
 		 * @copydoc HardwareBufferManager::createGenericBuffer

+ 2 - 2
CamelotD3D9Renderer/Source/CmD3D9HardwareBufferManager.cpp

@@ -67,9 +67,9 @@ namespace CamelotEngine {
             
             
     }
     }
 	//-----------------------------------------------------------------------
 	//-----------------------------------------------------------------------
-	GpuParamBlockBufferPtr D3D9HardwareBufferManager::createGpuParamBlockBuffer(const GpuParamBlockDesc& paramDesc)
+	GpuParamBlockPtr D3D9HardwareBufferManager::createGpuParamBlock(const GpuParamBlockDesc& paramDesc, GpuParamBlockUsage usage)
 	{
 	{
-		return GpuParamBlockBufferPtr(new GpuParamBlockBuffer(paramDesc));
+		return GpuParamBlockPtr(new GpuParamBlock(paramDesc, usage));
 	}
 	}
 	//-----------------------------------------------------------------------
 	//-----------------------------------------------------------------------
 	GpuBufferPtr D3D9HardwareBufferManager::createGpuBuffer(UINT32 elementCount, UINT32 elementSize, 
 	GpuBufferPtr D3D9HardwareBufferManager::createGpuBuffer(UINT32 elementCount, UINT32 elementSize, 

+ 40 - 40
CamelotD3D9Renderer/Source/CmD3D9RenderSystem.cpp

@@ -359,26 +359,26 @@ namespace CamelotEngine
 			{
 			{
 				for(auto iter = paramDesc.params.begin(); iter != paramDesc.params.end(); ++iter)
 				for(auto iter = paramDesc.params.begin(); iter != paramDesc.params.end(); ++iter)
 				{
 				{
-					const GpuParamMemberDesc& paramDesc = iter->second;
+					const GpuParamDataDesc& paramDesc = iter->second;
 
 
-					GpuParamBlockBufferPtr paramBlock = params->getParamBlock(paramDesc.paramBlockSlot);
+					GpuParamBlockPtr paramBlock = params->getParamBlock(paramDesc.paramBlockSlot);
 					const UINT8* ptrData = paramBlock->getDataPtr(paramDesc.cpuMemOffset * sizeof(UINT32));
 					const UINT8* ptrData = paramBlock->getDataPtr(paramDesc.cpuMemOffset * sizeof(UINT32));
 
 
 					switch(paramDesc.type)
 					switch(paramDesc.type)
 					{
 					{
-					case GMT_FLOAT1:
-					case GMT_FLOAT2:
-					case GMT_FLOAT3:
-					case GMT_FLOAT4:
-					case GMT_MATRIX_2X2:
-					case GMT_MATRIX_2X3:
-					case GMT_MATRIX_2X4:
-					case GMT_MATRIX_3X2:
-					case GMT_MATRIX_3X3:
-					case GMT_MATRIX_3X4:
-					case GMT_MATRIX_4X2:
-					case GMT_MATRIX_4X3:
-					case GMT_MATRIX_4X4:
+					case GPDT_FLOAT1:
+					case GPDT_FLOAT2:
+					case GPDT_FLOAT3:
+					case GPDT_FLOAT4:
+					case GPDT_MATRIX_2X2:
+					case GPDT_MATRIX_2X3:
+					case GPDT_MATRIX_2X4:
+					case GPDT_MATRIX_3X2:
+					case GPDT_MATRIX_3X3:
+					case GPDT_MATRIX_3X4:
+					case GPDT_MATRIX_4X2:
+					case GPDT_MATRIX_4X3:
+					case GPDT_MATRIX_4X4:
 						{
 						{
 							UINT32 slotCount = (paramDesc.elementSize / 4) * paramDesc.arraySize;
 							UINT32 slotCount = (paramDesc.elementSize / 4) * paramDesc.arraySize;
 							assert (paramDesc.elementSize % 4 == 0 && "Should not have any elements less than 4 wide for D3D9");
 							assert (paramDesc.elementSize % 4 == 0 && "Should not have any elements less than 4 wide for D3D9");
@@ -387,10 +387,10 @@ namespace CamelotEngine
 								CM_EXCEPT(RenderingAPIException, "Unable to upload vertex shader float parameters.");
 								CM_EXCEPT(RenderingAPIException, "Unable to upload vertex shader float parameters.");
 							break;
 							break;
 						}
 						}
-					case GMT_INT1:
-					case GMT_INT2:
-					case GMT_INT3:
-					case GMT_INT4:
+					case GPDT_INT1:
+					case GPDT_INT2:
+					case GPDT_INT3:
+					case GPDT_INT4:
 						{
 						{
 							UINT32 slotCount = (paramDesc.elementSize / 4) * paramDesc.arraySize;
 							UINT32 slotCount = (paramDesc.elementSize / 4) * paramDesc.arraySize;
 							assert (paramDesc.elementSize % 4 == 0 && "Should not have any elements less than 4 wide for D3D9");
 							assert (paramDesc.elementSize % 4 == 0 && "Should not have any elements less than 4 wide for D3D9");
@@ -399,7 +399,7 @@ namespace CamelotEngine
 								CM_EXCEPT(RenderingAPIException, "Unable to upload vertex shader int parameters.");
 								CM_EXCEPT(RenderingAPIException, "Unable to upload vertex shader int parameters.");
 							break;
 							break;
 						}
 						}
-					case GMT_BOOL:
+					case GPDT_BOOL:
 						if (FAILED(hr = getActiveD3D9Device()->SetVertexShaderConstantB(paramDesc.gpuMemOffset, (const BOOL*)ptrData, paramDesc.arraySize))) 
 						if (FAILED(hr = getActiveD3D9Device()->SetVertexShaderConstantB(paramDesc.gpuMemOffset, (const BOOL*)ptrData, paramDesc.arraySize))) 
 							CM_EXCEPT(RenderingAPIException, "Unable to upload vertex shader bool parameters.");
 							CM_EXCEPT(RenderingAPIException, "Unable to upload vertex shader bool parameters.");
 						break;
 						break;
@@ -411,26 +411,26 @@ namespace CamelotEngine
 			{
 			{
 				for(auto iter = paramDesc.params.begin(); iter != paramDesc.params.end(); ++iter)
 				for(auto iter = paramDesc.params.begin(); iter != paramDesc.params.end(); ++iter)
 				{
 				{
-					const GpuParamMemberDesc& paramDesc = iter->second;
+					const GpuParamDataDesc& paramDesc = iter->second;
 
 
-					GpuParamBlockBufferPtr paramBlock = params->getParamBlock(paramDesc.paramBlockSlot);
+					GpuParamBlockPtr paramBlock = params->getParamBlock(paramDesc.paramBlockSlot);
 					const UINT8* ptrData = paramBlock->getDataPtr(paramDesc.cpuMemOffset * sizeof(UINT32));
 					const UINT8* ptrData = paramBlock->getDataPtr(paramDesc.cpuMemOffset * sizeof(UINT32));
 
 
 					switch(paramDesc.type)
 					switch(paramDesc.type)
 					{
 					{
-					case GMT_FLOAT1:
-					case GMT_FLOAT2:
-					case GMT_FLOAT3:
-					case GMT_FLOAT4:
-					case GMT_MATRIX_2X2:
-					case GMT_MATRIX_2X3:
-					case GMT_MATRIX_2X4:
-					case GMT_MATRIX_3X2:
-					case GMT_MATRIX_3X3:
-					case GMT_MATRIX_3X4:
-					case GMT_MATRIX_4X2:
-					case GMT_MATRIX_4X3:
-					case GMT_MATRIX_4X4:
+					case GPDT_FLOAT1:
+					case GPDT_FLOAT2:
+					case GPDT_FLOAT3:
+					case GPDT_FLOAT4:
+					case GPDT_MATRIX_2X2:
+					case GPDT_MATRIX_2X3:
+					case GPDT_MATRIX_2X4:
+					case GPDT_MATRIX_3X2:
+					case GPDT_MATRIX_3X3:
+					case GPDT_MATRIX_3X4:
+					case GPDT_MATRIX_4X2:
+					case GPDT_MATRIX_4X3:
+					case GPDT_MATRIX_4X4:
 						{
 						{
 							UINT32 slotCount = (paramDesc.elementSize / 4) * paramDesc.arraySize;
 							UINT32 slotCount = (paramDesc.elementSize / 4) * paramDesc.arraySize;
 							assert (paramDesc.elementSize % 4 == 0 && "Should not have any elements less than 4 wide for D3D9");
 							assert (paramDesc.elementSize % 4 == 0 && "Should not have any elements less than 4 wide for D3D9");
@@ -439,10 +439,10 @@ namespace CamelotEngine
 								CM_EXCEPT(RenderingAPIException, "Unable to upload pixel shader float parameters.");
 								CM_EXCEPT(RenderingAPIException, "Unable to upload pixel shader float parameters.");
 							break;
 							break;
 						}
 						}
-					case GMT_INT1:
-					case GMT_INT2:
-					case GMT_INT3:
-					case GMT_INT4:
+					case GPDT_INT1:
+					case GPDT_INT2:
+					case GPDT_INT3:
+					case GPDT_INT4:
 						{
 						{
 							UINT32 slotCount = (paramDesc.elementSize / 4) * paramDesc.arraySize;
 							UINT32 slotCount = (paramDesc.elementSize / 4) * paramDesc.arraySize;
 							assert (paramDesc.elementSize % 4 == 0 && "Should not have any elements less than 4 wide for D3D9");
 							assert (paramDesc.elementSize % 4 == 0 && "Should not have any elements less than 4 wide for D3D9");
@@ -451,7 +451,7 @@ namespace CamelotEngine
 								CM_EXCEPT(RenderingAPIException, "Unable to upload pixel shader int parameters.");
 								CM_EXCEPT(RenderingAPIException, "Unable to upload pixel shader int parameters.");
 							break;
 							break;
 						}
 						}
-					case GMT_BOOL:
+					case GPDT_BOOL:
 						if (FAILED(hr = getActiveD3D9Device()->SetPixelShaderConstantB(paramDesc.gpuMemOffset, (const BOOL*)ptrData, paramDesc.arraySize))) 
 						if (FAILED(hr = getActiveD3D9Device()->SetPixelShaderConstantB(paramDesc.gpuMemOffset, (const BOOL*)ptrData, paramDesc.arraySize))) 
 							CM_EXCEPT(RenderingAPIException, "Unable to upload pixel shader bool parameters.");
 							CM_EXCEPT(RenderingAPIException, "Unable to upload pixel shader bool parameters.");
 						break;
 						break;

+ 4 - 3
CamelotGLRenderer/Include/CmGLGpuParamBlock.h

@@ -2,10 +2,11 @@
 
 
 #include "CmGLPrerequisites.h"
 #include "CmGLPrerequisites.h"
 #include "CmGpuParamBlock.h"
 #include "CmGpuParamBlock.h"
+#include "CmCommonEnums.h"
 
 
 namespace CamelotEngine
 namespace CamelotEngine
 {
 {
-	class CM_RSGL_EXPORT GLGpuParamBlock : public GpuParamBlockBuffer
+	class CM_RSGL_EXPORT GLGpuParamBlock : public GpuParamBlock
 	{
 	{
 	private:
 	private:
 		struct GLGpuParamBlockSharedData
 		struct GLGpuParamBlockSharedData
@@ -14,11 +15,11 @@ namespace CamelotEngine
 		};
 		};
 
 
 	public:
 	public:
-		GLGpuParamBlock(const GpuParamBlockDesc& desc);
+		GLGpuParamBlock(const GpuParamBlockDesc& desc, GpuParamBlockUsage usage);
 		~GLGpuParamBlock();
 		~GLGpuParamBlock();
 
 
 		virtual void updateIfDirty();
 		virtual void updateIfDirty();
-		virtual GpuParamBlockBufferPtr clone() const;
+		virtual GpuParamBlockPtr clone() const;
 
 
 		GLuint getGLHandle() const { return mGLSharedData->mGLHandle; }
 		GLuint getGLHandle() const { return mGLSharedData->mGLHandle; }
 
 

+ 2 - 2
CamelotGLRenderer/Include/CmGLHardwareBufferManager.h

@@ -62,8 +62,8 @@ namespace CamelotEngine {
             IndexBuffer::IndexType itype, UINT32 numIndexes, 
             IndexBuffer::IndexType itype, UINT32 numIndexes, 
             GpuBufferUsage usage);
             GpuBufferUsage usage);
 
 
-		/** @copydoc HardwareBufferManager::createGpuParamBlockBuffer */
-		GpuParamBlockBufferPtr createGpuParamBlockBuffer(const GpuParamBlockDesc& paramDesc);
+		/** @copydoc HardwareBufferManager::createGpuParamBlock */
+		GpuParamBlockPtr createGpuParamBlock(const GpuParamBlockDesc& paramDesc, GpuParamBlockUsage usage = GPBU_STATIC);
 
 
 		/**
 		/**
 		 * @copydoc HardwareBufferManager::createGenericBuffer
 		 * @copydoc HardwareBufferManager::createGenericBuffer

+ 5 - 0
CamelotGLRenderer/Include/CmGLRenderSystem.h

@@ -550,6 +550,11 @@ namespace CamelotEngine {
         */
         */
         void switchContext(GLContext *context);
         void switchContext(GLContext *context);
 
 
+		/**
+		 * @brief	Checks if there are any OpenGL errors and prints them to the log.
+		 */
+		bool checkForErrors() const;
+
 		/**
 		/**
 		 * @brief	OpenGL shares all texture slots, but the engine prefers to keep textures
 		 * @brief	OpenGL shares all texture slots, but the engine prefers to keep textures
 		 * 			separate per-stage. This will convert texture unit that is set per stage
 		 * 			separate per-stage. This will convert texture unit that is set per stage

+ 4 - 4
CamelotGLRenderer/Source/CmGLGpuParamBlock.cpp

@@ -2,8 +2,8 @@
 
 
 namespace CamelotEngine
 namespace CamelotEngine
 {
 {
-	GLGpuParamBlock::GLGpuParamBlock(const GpuParamBlockDesc& desc)
-		:GpuParamBlockBuffer(desc), mGLSharedData(nullptr)
+	GLGpuParamBlock::GLGpuParamBlock(const GpuParamBlockDesc& desc, GpuParamBlockUsage usage)
+		:GpuParamBlock(desc, usage), mGLSharedData(nullptr)
 	{
 	{
 		mGLSharedData = new GLGpuParamBlockSharedData();
 		mGLSharedData = new GLGpuParamBlockSharedData();
 	}
 	}
@@ -36,10 +36,10 @@ namespace CamelotEngine
 			glBindBuffer(GL_UNIFORM_BUFFER, 0);
 			glBindBuffer(GL_UNIFORM_BUFFER, 0);
 		}
 		}
 
 
-		GpuParamBlockBuffer::updateIfDirty();
+		GpuParamBlock::updateIfDirty();
 	}
 	}
 
 
-	GpuParamBlockBufferPtr GLGpuParamBlock::clone() const
+	GpuParamBlockPtr GLGpuParamBlock::clone() const
 	{
 	{
 		std::shared_ptr<GLGpuParamBlock> clonedParamBlock(new GLGpuParamBlock(*this));
 		std::shared_ptr<GLGpuParamBlock> clonedParamBlock(new GLGpuParamBlock(*this));
 		clonedParamBlock->mData = new UINT8[mSize];
 		clonedParamBlock->mData = new UINT8[mSize];

+ 2 - 2
CamelotGLRenderer/Source/CmGLHardwareBufferManager.cpp

@@ -104,9 +104,9 @@ namespace CamelotEngine {
 		return IndexBufferPtr(buf);
 		return IndexBufferPtr(buf);
     }
     }
 	//---------------------------------------------------------------------
 	//---------------------------------------------------------------------
-	GpuParamBlockBufferPtr GLHardwareBufferManager::createGpuParamBlockBuffer(const GpuParamBlockDesc& paramDesc)
+	GpuParamBlockPtr GLHardwareBufferManager::createGpuParamBlock(const GpuParamBlockDesc& paramDesc, GpuParamBlockUsage usage)
 	{
 	{
-		return GpuParamBlockBufferPtr(new GLGpuParamBlock(paramDesc));
+		return GpuParamBlockPtr(new GLGpuParamBlock(paramDesc, usage));
 	}
 	}
 	//---------------------------------------------------------------------
 	//---------------------------------------------------------------------
 	GpuBufferPtr GLHardwareBufferManager::createGpuBuffer(UINT32 elementCount, UINT32 elementSize, 
 	GpuBufferPtr GLHardwareBufferManager::createGpuBuffer(UINT32 elementCount, UINT32 elementSize, 

+ 41 - 4
CamelotGLRenderer/Source/CmGLRenderSystem.cpp

@@ -341,7 +341,7 @@ namespace CamelotEngine
 			if(iter->second.slot == 0)
 			if(iter->second.slot == 0)
 				continue;
 				continue;
 
 
-			GpuParamBlockBufferPtr paramBlock = params->getParamBlock(iter->second.slot);
+			GpuParamBlockPtr paramBlock = params->getParamBlock(iter->second.slot);
 			if(paramBlock == nullptr)
 			if(paramBlock == nullptr)
 				continue;
 				continue;
 
 
@@ -356,9 +356,9 @@ namespace CamelotEngine
 
 
 		for(auto iter = paramDesc.params.begin(); iter != paramDesc.params.end(); ++iter)
 		for(auto iter = paramDesc.params.begin(); iter != paramDesc.params.end(); ++iter)
 		{
 		{
-			const GpuParamMemberDesc& paramDesc = iter->second;
+			const GpuParamDataDesc& paramDesc = iter->second;
 
 
-			GpuParamBlockBufferPtr paramBlock = params->getParamBlock(paramDesc.paramBlockSlot);
+			GpuParamBlockPtr paramBlock = params->getParamBlock(paramDesc.paramBlockSlot);
 			
 			
 			if(paramDesc.paramBlockSlot != 0) // 0 means uniforms are not in a block
 			if(paramDesc.paramBlockSlot != 0) // 0 means uniforms are not in a block
 				continue;
 				continue;
@@ -427,7 +427,7 @@ namespace CamelotEngine
 			case GCT_INT4:
 			case GCT_INT4:
 				glProgramUniform4iv(glProgram, paramDesc.gpuMemOffset, paramDesc.arraySize, (GLint*)ptrData);
 				glProgramUniform4iv(glProgram, paramDesc.gpuMemOffset, paramDesc.arraySize, (GLint*)ptrData);
 				break;
 				break;
-			case GMT_BOOL:
+			case GPDT_BOOL:
 				glProgramUniform1uiv(glProgram, paramDesc.gpuMemOffset, paramDesc.arraySize, (GLuint*)ptrData);
 				glProgramUniform1uiv(glProgram, paramDesc.gpuMemOffset, paramDesc.arraySize, (GLuint*)ptrData);
 				break;
 				break;
 			case GCT_UNKNOWN:
 			case GCT_UNKNOWN:
@@ -1385,6 +1385,8 @@ namespace CamelotEngine
 			// set up glew and GLSupport
 			// set up glew and GLSupport
 			initialiseContext(context);
 			initialiseContext(context);
 
 
+			checkForErrors();
+
 			std::vector<CamelotEngine::String> tokens = StringUtil::split(mGLSupport->getGLVersion(), ".");
 			std::vector<CamelotEngine::String> tokens = StringUtil::split(mGLSupport->getGLVersion(), ".");
 
 
 			if (!tokens.empty())
 			if (!tokens.empty())
@@ -1399,13 +1401,20 @@ namespace CamelotEngine
 			// Initialise GL after the first window has been created
 			// Initialise GL after the first window has been created
 			// TODO: fire this from emulation options, and don't duplicate float and Current capabilities
 			// TODO: fire this from emulation options, and don't duplicate float and Current capabilities
 			mCurrentCapabilities = createRenderSystemCapabilities();
 			mCurrentCapabilities = createRenderSystemCapabilities();
+			checkForErrors();
 
 
 			initialiseFromRenderSystemCapabilities(mCurrentCapabilities);
 			initialiseFromRenderSystemCapabilities(mCurrentCapabilities);
+			checkForErrors();
 
 
 			// Initialise the main context
 			// Initialise the main context
 			oneTimeContextInitialization();
 			oneTimeContextInitialization();
+			checkForErrors();
+
 			if(mCurrentContext)
 			if(mCurrentContext)
+			{
 				mCurrentContext->setInitialized();
 				mCurrentContext->setInitialized();
+				checkForErrors();
+			}
 		}
 		}
 	}
 	}
 	//---------------------------------------------------------------------
 	//---------------------------------------------------------------------
@@ -1732,6 +1741,28 @@ namespace CamelotEngine
 		glColor4f(1,1,1,1);
 		glColor4f(1,1,1,1);
 	}
 	}
 	//-----------------------------------------------------------------------
 	//-----------------------------------------------------------------------
+	bool GLRenderSystem::checkForErrors() const
+	{
+		GLenum glErr = glGetError();
+		bool errorsFound = false;
+		String msg;
+		while (glErr != GL_NO_ERROR)
+		{
+			const char* glerrStr = (const char*)gluErrorString(glErr);
+			if (glerrStr)
+			{
+				msg += String(glerrStr);
+			}
+			glErr = glGetError();
+			errorsFound = true;
+		}
+
+		if(errorsFound)
+			LOGWRN("OpenGL error: " + msg);
+
+		return errorsFound;
+	}
+	//-----------------------------------------------------------------------
 	GLint GLRenderSystem::getGLDrawMode() const
 	GLint GLRenderSystem::getGLDrawMode() const
 	{
 	{
 		GLint primType;
 		GLint primType;
@@ -1807,15 +1838,18 @@ namespace CamelotEngine
 		}
 		}
 
 
 		HardwareBufferManager::startUp(new GLHardwareBufferManager);
 		HardwareBufferManager::startUp(new GLHardwareBufferManager);
+		checkForErrors();
 
 
 		// GPU Program Manager setup
 		// GPU Program Manager setup
 		GpuProgramManager::startUp(new GLGpuProgramManager());
 		GpuProgramManager::startUp(new GLGpuProgramManager());
+		checkForErrors();
 
 
 		if(caps->isShaderProfileSupported("glsl"))
 		if(caps->isShaderProfileSupported("glsl"))
 		{
 		{
 			// NFZ - check for GLSL vertex and fragment shader support successful
 			// NFZ - check for GLSL vertex and fragment shader support successful
 			mGLSLProgramFactory = new GLSLProgramFactory();
 			mGLSLProgramFactory = new GLSLProgramFactory();
 			HighLevelGpuProgramManager::instance().addFactory(mGLSLProgramFactory);
 			HighLevelGpuProgramManager::instance().addFactory(mGLSLProgramFactory);
+			checkForErrors();
 		}
 		}
 
 
 		if(caps->isShaderProfileSupported("cg"))
 		if(caps->isShaderProfileSupported("cg"))
@@ -1823,6 +1857,7 @@ namespace CamelotEngine
 			// NFZ - check for GLSL vertex and fragment shader support successful
 			// NFZ - check for GLSL vertex and fragment shader support successful
 			mCgProgramFactory = new CgProgramFactory();
 			mCgProgramFactory = new CgProgramFactory();
 			HighLevelGpuProgramManager::instance().addFactory(mCgProgramFactory);
 			HighLevelGpuProgramManager::instance().addFactory(mCgProgramFactory);
+			checkForErrors();
 		}
 		}
 
 
 		if(caps->hasCapability(RSC_HWOCCLUSION))
 		if(caps->hasCapability(RSC_HWOCCLUSION))
@@ -1855,6 +1890,7 @@ namespace CamelotEngine
 			{
 			{
 				// Create FBO manager
 				// Create FBO manager
 				GLRTTManager::startUp(new GLRTTManager());
 				GLRTTManager::startUp(new GLRTTManager());
+				checkForErrors();
 			}
 			}
 		}
 		}
 		else
 		else
@@ -1902,6 +1938,7 @@ namespace CamelotEngine
 
 
 		/// Create the texture manager        
 		/// Create the texture manager        
 		TextureManager::startUp(new GLTextureManager(*mGLSupport)); 
 		TextureManager::startUp(new GLTextureManager(*mGLSupport)); 
+		checkForErrors();
 
 
 		mGLInitialised = true;
 		mGLInitialised = true;
 	}
 	}

+ 12 - 31
CamelotGLRenderer/Source/CmGLRenderTexture.cpp

@@ -82,39 +82,24 @@ namespace CamelotEngine
 /// Size of probe texture
 /// Size of probe texture
 #define PROBE_SIZE 16
 #define PROBE_SIZE 16
 
 
-/// Stencil and depth formats to be tried
-static const GLenum stencilFormats[] =
-{
-    GL_NONE,                    // No stencil
-    GL_STENCIL_INDEX1_EXT,
-    GL_STENCIL_INDEX4_EXT,
-    GL_STENCIL_INDEX8_EXT,
-    GL_STENCIL_INDEX16_EXT
-};
-static const UINT32 stencilBits[] =
-{
-    0, 1, 4, 8, 16
-};
-#define STENCILFORMAT_COUNT (sizeof(stencilFormats)/sizeof(GLenum))
-
 static const GLenum depthFormats[] =
 static const GLenum depthFormats[] =
 {
 {
     GL_NONE,
     GL_NONE,
     GL_DEPTH_COMPONENT16,
     GL_DEPTH_COMPONENT16,
-    GL_DEPTH_COMPONENT24,    // Prefer 24 bit depth
     GL_DEPTH_COMPONENT32,
     GL_DEPTH_COMPONENT32,
-    GL_DEPTH24_STENCIL8_EXT // packed depth / stencil
+    GL_DEPTH24_STENCIL8, // packed depth / stencil
+	GL_DEPTH32F_STENCIL8
 };
 };
 static const UINT32 depthBits[] =
 static const UINT32 depthBits[] =
 {
 {
-    0,16,24,32,24
+    0,16,32,24,32
 };
 };
 #define DEPTHFORMAT_COUNT (sizeof(depthFormats)/sizeof(GLenum))
 #define DEPTHFORMAT_COUNT (sizeof(depthFormats)/sizeof(GLenum))
 
 
 	GLRTTManager::GLRTTManager()
 	GLRTTManager::GLRTTManager()
     {
     {
 		detectFBOFormats();
 		detectFBOFormats();
-
+		
         glGenFramebuffersEXT(1, &mTempFBO);
         glGenFramebuffersEXT(1, &mTempFBO);
     }
     }
 
 
@@ -251,7 +236,7 @@ static const UINT32 depthBits[] =
             // Create and attach framebuffer
             // Create and attach framebuffer
             glGenFramebuffersEXT(1, &fb);
             glGenFramebuffersEXT(1, &fb);
             glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb);
             glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb);
-            if (fmt!=GL_NONE)
+            if (fmt!=GL_NONE && !PixelUtil::isDepth((PixelFormat)x))
             {
             {
 				// Create and attach texture
 				// Create and attach texture
 				glGenTextures(1, &tid);
 				glGenTextures(1, &tid);
@@ -288,19 +273,15 @@ static const UINT32 depthBits[] =
                 // For each depth/stencil formats
                 // For each depth/stencil formats
                 for (UINT32 depth = 0; depth < DEPTHFORMAT_COUNT; ++depth)
                 for (UINT32 depth = 0; depth < DEPTHFORMAT_COUNT; ++depth)
                 {
                 {
-                    if (depthFormats[depth] != GL_DEPTH24_STENCIL8_EXT)
+                    if (depthFormats[depth] != GL_DEPTH24_STENCIL8_EXT && depthFormats[depth] != GL_DEPTH32F_STENCIL8)
                     {
                     {
-                        // General depth/stencil combination
-                        for (UINT32 stencil = 0; stencil < STENCILFORMAT_COUNT; ++stencil)
+                        if (_tryFormat(depthFormats[depth], GL_NONE))
                         {
                         {
-                            if (_tryFormat(depthFormats[depth], stencilFormats[stencil]))
-                            {
-                                /// Add mode to allowed modes
-                                FormatProperties::Mode mode;
-                                mode.depth = depth;
-                                mode.stencil = stencil;
-                                mProps[x].modes.push_back(mode);
-                            }
+                            /// Add mode to allowed modes
+                            FormatProperties::Mode mode;
+                            mode.depth = depth;
+                            mode.stencil = 0;
+                            mProps[x].modes.push_back(mode);
                         }
                         }
                     }
                     }
                     else
                     else

+ 33 - 31
CamelotGLRenderer/Source/GLSL/include/CmGLSLParamParser.h

@@ -43,7 +43,7 @@ namespace CamelotEngine
 		void buildVertexDeclaration(GLuint glProgram, VertexDeclaration& declaration);
 		void buildVertexDeclaration(GLuint glProgram, VertexDeclaration& declaration);
 
 
 	private:
 	private:
-		void determineParamInfo(GpuParamMemberDesc& desc, const String& paramName, GLuint programHandle, GLuint uniformIndex);
+		void determineParamInfo(GpuParamDataDesc& desc, const String& paramName, GLuint programHandle, GLuint uniformIndex);
 
 
 		/**
 		/**
 		* @brief	GLSL has no concept of semantics, so we require all shaders to use specific names for attributes
 		* @brief	GLSL has no concept of semantics, so we require all shaders to use specific names for attributes
@@ -153,6 +153,7 @@ namespace CamelotEngine
 		newGlobalBlockDesc.slot = 0;
 		newGlobalBlockDesc.slot = 0;
 		newGlobalBlockDesc.name = "CM_INTERNAL_Globals";
 		newGlobalBlockDesc.name = "CM_INTERNAL_Globals";
 		newGlobalBlockDesc.blockSize = 0;
 		newGlobalBlockDesc.blockSize = 0;
+		newGlobalBlockDesc.isShareable = false;
 
 
 		UINT32 textureSlot = 0;
 		UINT32 textureSlot = 0;
 
 
@@ -172,6 +173,7 @@ namespace CamelotEngine
 			newBlockDesc.slot = index + 1;
 			newBlockDesc.slot = index + 1;
 			newBlockDesc.name = uniformName;
 			newBlockDesc.name = uniformName;
 			newBlockDesc.blockSize = 0;
 			newBlockDesc.blockSize = 0;
+			newBlockDesc.isShareable = true;
 
 
 			returnParamDesc.paramBlocks[newBlockDesc.name] = newBlockDesc;
 			returnParamDesc.paramBlocks[newBlockDesc.name] = newBlockDesc;
 			blockSlotToName.insert(std::make_pair(newBlockDesc.slot, newBlockDesc.name));
 			blockSlotToName.insert(std::make_pair(newBlockDesc.slot, newBlockDesc.name));
@@ -216,31 +218,31 @@ namespace CamelotEngine
 
 
 			if(isSampler)
 			if(isSampler)
 			{
 			{
-				GpuParamSpecialDesc samplerParam;
+				GpuParamObjectDesc samplerParam;
 				samplerParam.name = paramName;
 				samplerParam.name = paramName;
 				samplerParam.slot = glGetUniformLocation(glProgram, uniformName);
 				samplerParam.slot = glGetUniformLocation(glProgram, uniformName);
 
 
-				GpuParamSpecialDesc textureParam;
+				GpuParamObjectDesc textureParam;
 				textureParam.name = paramName;
 				textureParam.name = paramName;
 				textureParam.slot = samplerParam.slot;
 				textureParam.slot = samplerParam.slot;
 
 
 				switch(uniformType)
 				switch(uniformType)
 				{
 				{
 				case GL_SAMPLER_1D:
 				case GL_SAMPLER_1D:
-					samplerParam.type = GST_SAMPLER1D;
-					textureParam.type = GST_TEXTURE1D;
+					samplerParam.type = GPOT_SAMPLER1D;
+					textureParam.type = GPOT_TEXTURE1D;
 					break;
 					break;
 				case GL_SAMPLER_2D:
 				case GL_SAMPLER_2D:
-					samplerParam.type = GST_SAMPLER2D;
-					textureParam.type = GST_TEXTURE2D;
+					samplerParam.type = GPOT_SAMPLER2D;
+					textureParam.type = GPOT_TEXTURE2D;
 					break;
 					break;
 				case GL_SAMPLER_3D:
 				case GL_SAMPLER_3D:
-					samplerParam.type = GST_SAMPLER3D;
-					textureParam.type = GST_TEXTURE3D;
+					samplerParam.type = GPOT_SAMPLER3D;
+					textureParam.type = GPOT_TEXTURE3D;
 					break;
 					break;
 				case GL_SAMPLER_CUBE:
 				case GL_SAMPLER_CUBE:
-					samplerParam.type = GST_SAMPLERCUBE;
-					textureParam.type = GST_TEXTURECUBE;
+					samplerParam.type = GPOT_SAMPLERCUBE;
+					textureParam.type = GPOT_TEXTURECUBE;
 					break;
 					break;
 				}
 				}
 
 
@@ -249,7 +251,7 @@ namespace CamelotEngine
 			}
 			}
 			else
 			else
 			{
 			{
-				GpuParamMemberDesc gpuParam;
+				GpuParamDataDesc gpuParam;
 				gpuParam.name = paramName;
 				gpuParam.name = paramName;
 
 
 				GLint blockIndex;
 				GLint blockIndex;
@@ -315,7 +317,7 @@ namespace CamelotEngine
 		delete[] uniformName;
 		delete[] uniformName;
 	}
 	}
 
 
-	void GLSLParamParser::determineParamInfo(GpuParamMemberDesc& desc, const String& paramName, GLuint programHandle, GLuint uniformIndex)
+	void GLSLParamParser::determineParamInfo(GpuParamDataDesc& desc, const String& paramName, GLuint programHandle, GLuint uniformIndex)
 	{
 	{
 		GLint arraySize;
 		GLint arraySize;
 		glGetActiveUniformsiv(programHandle, 1, &uniformIndex, GL_UNIFORM_SIZE, &arraySize);
 		glGetActiveUniformsiv(programHandle, 1, &uniformIndex, GL_UNIFORM_SIZE, &arraySize);
@@ -327,75 +329,75 @@ namespace CamelotEngine
 		switch (uniformType)
 		switch (uniformType)
 		{
 		{
 		case GL_BOOL:
 		case GL_BOOL:
-			desc.type = GMT_BOOL;
+			desc.type = GPDT_BOOL;
 			desc.elementSize = 1;
 			desc.elementSize = 1;
 			break;
 			break;
 		case GL_FLOAT:
 		case GL_FLOAT:
-			desc.type = GMT_FLOAT1;
+			desc.type = GPDT_FLOAT1;
 			desc.elementSize = 1;
 			desc.elementSize = 1;
 			break;
 			break;
 		case GL_FLOAT_VEC2:
 		case GL_FLOAT_VEC2:
-			desc.type = GMT_FLOAT2;
+			desc.type = GPDT_FLOAT2;
 			desc.elementSize = 2;
 			desc.elementSize = 2;
 			break;
 			break;
 		case GL_FLOAT_VEC3:
 		case GL_FLOAT_VEC3:
-			desc.type = GMT_FLOAT3;
+			desc.type = GPDT_FLOAT3;
 			desc.elementSize = 3;
 			desc.elementSize = 3;
 			break;
 			break;
 		case GL_FLOAT_VEC4:
 		case GL_FLOAT_VEC4:
-			desc.type = GMT_FLOAT4;
+			desc.type = GPDT_FLOAT4;
 			desc.elementSize = 4;
 			desc.elementSize = 4;
 			break;
 			break;
 		case GL_INT:
 		case GL_INT:
-			desc.type = GMT_INT1;
+			desc.type = GPDT_INT1;
 			desc.elementSize = 1;
 			desc.elementSize = 1;
 			break;
 			break;
 		case GL_INT_VEC2:
 		case GL_INT_VEC2:
-			desc.type = GMT_INT2;
+			desc.type = GPDT_INT2;
 			desc.elementSize = 2;
 			desc.elementSize = 2;
 			break;
 			break;
 		case GL_INT_VEC3:
 		case GL_INT_VEC3:
-			desc.type = GMT_INT3;
+			desc.type = GPDT_INT3;
 			desc.elementSize = 3;
 			desc.elementSize = 3;
 			break;
 			break;
 		case GL_INT_VEC4:
 		case GL_INT_VEC4:
-			desc.type = GMT_INT4;
+			desc.type = GPDT_INT4;
 			desc.elementSize = 4;
 			desc.elementSize = 4;
 			break;
 			break;
 		case GL_FLOAT_MAT2:
 		case GL_FLOAT_MAT2:
-			desc.type = GMT_MATRIX_2X2;
+			desc.type = GPDT_MATRIX_2X2;
 			desc.elementSize = 4;
 			desc.elementSize = 4;
 			break;
 			break;
 		case GL_FLOAT_MAT3:
 		case GL_FLOAT_MAT3:
-			desc.type = GMT_MATRIX_3X3;
+			desc.type = GPDT_MATRIX_3X3;
 			desc.elementSize = 9;
 			desc.elementSize = 9;
 			break;
 			break;
 		case GL_FLOAT_MAT4:
 		case GL_FLOAT_MAT4:
-			desc.type = GMT_MATRIX_4X4;
+			desc.type = GPDT_MATRIX_4X4;
 			desc.elementSize = 16;
 			desc.elementSize = 16;
 			break;
 			break;
 		case GL_FLOAT_MAT2x3:
 		case GL_FLOAT_MAT2x3:
-			desc.type = GMT_MATRIX_2X3;
+			desc.type = GPDT_MATRIX_2X3;
 			desc.elementSize = 6;
 			desc.elementSize = 6;
 			break;
 			break;
 		case GL_FLOAT_MAT3x2:
 		case GL_FLOAT_MAT3x2:
-			desc.type = GMT_MATRIX_3X2;
+			desc.type = GPDT_MATRIX_3X2;
 			desc.elementSize = 6;
 			desc.elementSize = 6;
 			break;
 			break;
 		case GL_FLOAT_MAT2x4:
 		case GL_FLOAT_MAT2x4:
-			desc.type = GMT_MATRIX_2X4;
+			desc.type = GPDT_MATRIX_2X4;
 			desc.elementSize = 8;
 			desc.elementSize = 8;
 			break;
 			break;
 		case GL_FLOAT_MAT4x2:
 		case GL_FLOAT_MAT4x2:
-			desc.type = GMT_MATRIX_4X2;
+			desc.type = GPDT_MATRIX_4X2;
 			desc.elementSize = 8;
 			desc.elementSize = 8;
 			break;
 			break;
 		case GL_FLOAT_MAT3x4:
 		case GL_FLOAT_MAT3x4:
-			desc.type = GMT_MATRIX_3X4;
+			desc.type = GPDT_MATRIX_3X4;
 			desc.elementSize = 12;
 			desc.elementSize = 12;
 			break;
 			break;
 		case GL_FLOAT_MAT4x3:
 		case GL_FLOAT_MAT4x3:
-			desc.type = GMT_MATRIX_4X3;
+			desc.type = GPDT_MATRIX_4X3;
 			desc.elementSize = 12;
 			desc.elementSize = 12;
 			break;
 			break;
 		default:
 		default:

+ 6 - 6
CamelotRenderer/CamelotRenderer.vcxproj.filters

@@ -329,9 +329,6 @@
     <ClInclude Include="Include\CmGpuParams.h">
     <ClInclude Include="Include\CmGpuParams.h">
       <Filter>Header Files\RenderSystem</Filter>
       <Filter>Header Files\RenderSystem</Filter>
     </ClInclude>
     </ClInclude>
-    <ClInclude Include="Include\CmGpuParamBlock.h">
-      <Filter>Header Files\RenderSystem</Filter>
-    </ClInclude>
     <ClInclude Include="Include\CmVertexDeclaration.h">
     <ClInclude Include="Include\CmVertexDeclaration.h">
       <Filter>Header Files\RenderSystem</Filter>
       <Filter>Header Files\RenderSystem</Filter>
     </ClInclude>
     </ClInclude>
@@ -365,6 +362,9 @@
     <ClInclude Include="Include\CmVertexData.h">
     <ClInclude Include="Include\CmVertexData.h">
       <Filter>Header Files\RenderSystem</Filter>
       <Filter>Header Files\RenderSystem</Filter>
     </ClInclude>
     </ClInclude>
+    <ClInclude Include="Include\CmGpuParamBlock.h">
+      <Filter>Header Files\RenderSystem</Filter>
+    </ClInclude>
   </ItemGroup>
   </ItemGroup>
   <ItemGroup>
   <ItemGroup>
     <ClCompile Include="Source\CamelotRenderer.cpp">
     <ClCompile Include="Source\CamelotRenderer.cpp">
@@ -520,9 +520,6 @@
     <ClCompile Include="Source\CmGpuParams.cpp">
     <ClCompile Include="Source\CmGpuParams.cpp">
       <Filter>Source Files\RenderSystem</Filter>
       <Filter>Source Files\RenderSystem</Filter>
     </ClCompile>
     </ClCompile>
-    <ClCompile Include="Source\CmGpuParamBlock.cpp">
-      <Filter>Source Files\RenderSystem</Filter>
-    </ClCompile>
     <ClCompile Include="Source\CmVertexDeclaration.cpp">
     <ClCompile Include="Source\CmVertexDeclaration.cpp">
       <Filter>Source Files\RenderSystem</Filter>
       <Filter>Source Files\RenderSystem</Filter>
     </ClCompile>
     </ClCompile>
@@ -553,5 +550,8 @@
     <ClCompile Include="Source\CmVertexData.cpp">
     <ClCompile Include="Source\CmVertexData.cpp">
       <Filter>Source Files\RenderSystem</Filter>
       <Filter>Source Files\RenderSystem</Filter>
     </ClCompile>
     </ClCompile>
+    <ClCompile Include="Source\CmGpuParamBlock.cpp">
+      <Filter>Source Files\RenderSystem</Filter>
+    </ClCompile>
   </ItemGroup>
   </ItemGroup>
 </Project>
 </Project>

+ 55 - 0
CamelotRenderer/Include/CmCommonEnums.h

@@ -256,6 +256,61 @@ namespace CamelotEngine {
 		GVU_RANDOMWRITE = 0x08
 		GVU_RANDOMWRITE = 0x08
 	};
 	};
 
 
+	enum GpuParamBlockUsage
+	{
+		GPBU_STATIC,
+		GPBU_DYNAMIC
+	};
+
+	enum GpuParamDataType
+	{
+		GPDT_FLOAT1 = 1,
+		GPDT_FLOAT2 = 2,
+		GPDT_FLOAT3 = 3,
+		GPDT_FLOAT4 = 4,
+		GPDT_MATRIX_2X2 = 11,
+		GPDT_MATRIX_2X3 = 12,
+		GPDT_MATRIX_2X4 = 13,
+		GPDT_MATRIX_3X2 = 14,
+		GPDT_MATRIX_3X3 = 15,
+		GPDT_MATRIX_3X4 = 16,
+		GPDT_MATRIX_4X2 = 17,
+		GPDT_MATRIX_4X3 = 18,
+		GPDT_MATRIX_4X4 = 19,
+		GPDT_INT1 = 20,
+		GPDT_INT2 = 21,
+		GPDT_INT3 = 22,
+		GPDT_INT4 = 23,
+		GPDT_BOOL = 24,
+		GPDT_STRUCT = 25,
+		GPDT_UNKNOWN = 0xffff
+	};
+
+	enum GpuParamObjectType
+	{
+		GPOT_SAMPLER1D = 1,
+		GPOT_SAMPLER2D = 2,
+		GPOT_SAMPLER3D = 3,
+		GPOT_SAMPLERCUBE = 4,
+		GPOT_TEXTURE1D = 11,
+		GPOT_TEXTURE2D = 12,
+		GPOT_TEXTURE3D = 13,
+		GPOT_TEXTURECUBE = 14,
+		GPOT_RWTEXTURE1D = 21,
+		GPOT_RWTEXTURE2D = 22,
+		GPOT_RWTEXTURE3D = 23,
+		GPOT_BYTE_BUFFER = 32,
+		GPOT_STRUCTURED_BUFFER = 33,
+		GPOT_RWTYPED_BUFFER = 41,
+		GPOT_RWBYTE_BUFFER = 42,
+		GPOT_RWSTRUCTURED_BUFFER = 43,
+		GPOT_RWSTRUCTURED_BUFFER_WITH_COUNTER = 44,
+		GPOT_RWAPPEND_BUFFER = 45,
+		GPOT_RWCONSUME_BUFFER = 46,
+		GPOT_UNKNOWN = 0xffff
+	};
+
+
 	/** Texture addressing mode for each texture coordinate. */
 	/** Texture addressing mode for each texture coordinate. */
 	struct UVWAddressingMode
 	struct UVWAddressingMode
 	{
 	{

+ 6 - 5
CamelotRenderer/Include/CmGpuParamBlock.h

@@ -1,10 +1,11 @@
 #pragma once
 #pragma once
 
 
 #include "CmPrerequisites.h"
 #include "CmPrerequisites.h"
+#include "CmCommonEnums.h"
 
 
 namespace CamelotEngine
 namespace CamelotEngine
 {
 {
-	class CM_EXPORT GpuParamBlockBuffer
+	class CM_EXPORT GpuParamBlock
 	{
 	{
 	private:
 	private:
 		struct GpuParamBlockSharedData
 		struct GpuParamBlockSharedData
@@ -14,8 +15,8 @@ namespace CamelotEngine
 		};
 		};
 
 
 	public:
 	public:
-		GpuParamBlockBuffer(const GpuParamBlockDesc& desc);
-		virtual ~GpuParamBlockBuffer();
+		GpuParamBlock(const GpuParamBlockDesc& desc, GpuParamBlockUsage usage);
+		virtual ~GpuParamBlock();
 
 
 		void write(UINT32 offset, const void* data, UINT32 size);
 		void write(UINT32 offset, const void* data, UINT32 size);
 		void zeroOut(UINT32 offset, UINT32 size);
 		void zeroOut(UINT32 offset, UINT32 size);
@@ -25,9 +26,9 @@ namespace CamelotEngine
 
 
 		virtual void updateIfDirty();
 		virtual void updateIfDirty();
 
 
-		virtual GpuParamBlockBufferPtr clone() const;
+		virtual GpuParamBlockPtr clone() const;
 		
 		
-		static GpuParamBlockBufferPtr create(const GpuParamBlockDesc& desc);
+		static GpuParamBlockPtr create(const GpuParamBlockDesc& desc);
 	protected:
 	protected:
 		GpuParamBlockSharedData* sharedData;
 		GpuParamBlockSharedData* sharedData;
 		bool mOwnsSharedData;
 		bool mOwnsSharedData;

+ 10 - 56
CamelotRenderer/Include/CmGpuParamDesc.h

@@ -1,74 +1,27 @@
 #pragma once
 #pragma once
 
 
 #include "CmPrerequisites.h"
 #include "CmPrerequisites.h"
+#include "CmCommonEnums.h"
 #include "CmGpuProgramParams.h" // TODO - Only here because I need some type definitions (GpuConstantType) - Remove later
 #include "CmGpuProgramParams.h" // TODO - Only here because I need some type definitions (GpuConstantType) - Remove later
 
 
 namespace CamelotEngine
 namespace CamelotEngine
 {
 {
-	enum GpuMemberType
-	{
-		GMT_FLOAT1 = 1,
-		GMT_FLOAT2 = 2,
-		GMT_FLOAT3 = 3,
-		GMT_FLOAT4 = 4,
-		GMT_MATRIX_2X2 = 11,
-		GMT_MATRIX_2X3 = 12,
-		GMT_MATRIX_2X4 = 13,
-		GMT_MATRIX_3X2 = 14,
-		GMT_MATRIX_3X3 = 15,
-		GMT_MATRIX_3X4 = 16,
-		GMT_MATRIX_4X2 = 17,
-		GMT_MATRIX_4X3 = 18,
-		GMT_MATRIX_4X4 = 19,
-		GMT_INT1 = 20,
-		GMT_INT2 = 21,
-		GMT_INT3 = 22,
-		GMT_INT4 = 23,
-		GMT_BOOL = 24,
-		GMT_STRUCT = 25,
-		GMT_UNKNOWN = 0xffff
-	};
-
-	enum GpuSpecialType
-	{
-		GST_SAMPLER1D = 1,
-		GST_SAMPLER2D = 2,
-		GST_SAMPLER3D = 3,
-		GST_SAMPLERCUBE = 4,
-		GST_TEXTURE1D = 11,
-		GST_TEXTURE2D = 12,
-		GST_TEXTURE3D = 13,
-		GST_TEXTURECUBE = 14,
-		GST_RWTEXTURE1D = 21,
-		GST_RWTEXTURE2D = 22,
-		GST_RWTEXTURE3D = 23,
-		GST_BYTE_BUFFER = 32,
-		GST_STRUCTURED_BUFFER = 33,
-		GST_RWTYPED_BUFFER = 41,
-		GST_RWBYTE_BUFFER = 42,
-		GST_RWSTRUCTURED_BUFFER = 43,
-		GST_RWSTRUCTURED_BUFFER_WITH_COUNTER = 44,
-		GST_RWAPPEND_BUFFER = 45,
-		GST_RWCONSUME_BUFFER = 46,
-		GST_UNKNOWN = 0xffff
-	};
-
-	struct GpuParamMemberDesc
+	struct GpuParamDataDesc
 	{
 	{
 		String name;
 		String name;
 		UINT32 elementSize; // Multiple of 4 bytes
 		UINT32 elementSize; // Multiple of 4 bytes
 		UINT32 arraySize;
 		UINT32 arraySize;
-		GpuMemberType type;
+		GpuParamDataType type;
 
 
 		UINT32 paramBlockSlot;
 		UINT32 paramBlockSlot;
 		UINT32 gpuMemOffset;
 		UINT32 gpuMemOffset;
 		UINT32 cpuMemOffset;
 		UINT32 cpuMemOffset;
 	};
 	};
 
 
-	struct GpuParamSpecialDesc
+	struct GpuParamObjectDesc
 	{
 	{
 		String name;
 		String name;
-		GpuSpecialType type;
+		GpuParamObjectType type;
 
 
 		UINT32 slot;
 		UINT32 slot;
 	};
 	};
@@ -78,15 +31,16 @@ namespace CamelotEngine
 		String name;
 		String name;
 		UINT32 slot;
 		UINT32 slot;
 		UINT32 blockSize;
 		UINT32 blockSize;
+		bool isShareable;
 	};
 	};
 
 
 	struct GpuParamDesc
 	struct GpuParamDesc
 	{
 	{
 		map<String, GpuParamBlockDesc>::type paramBlocks;
 		map<String, GpuParamBlockDesc>::type paramBlocks;
-		map<String, GpuParamMemberDesc>::type params;
+		map<String, GpuParamDataDesc>::type params;
 
 
-		map<String, GpuParamSpecialDesc>::type samplers;
-		map<String, GpuParamSpecialDesc>::type textures;
-		map<String, GpuParamSpecialDesc>::type buffers;
+		map<String, GpuParamObjectDesc>::type samplers;
+		map<String, GpuParamObjectDesc>::type textures;
+		map<String, GpuParamObjectDesc>::type buffers;
 	};
 	};
 }
 }

+ 7 - 6
CamelotRenderer/Include/CmGpuParams.h

@@ -9,17 +9,18 @@ namespace CamelotEngine
 	public:
 	public:
 		GpuParams(GpuParamDesc& paramDesc);
 		GpuParams(GpuParamDesc& paramDesc);
 
 
-		GpuParamBlockBufferPtr getParamBlock(UINT32 slot) const;
-		GpuParamBlockBufferPtr getParamBlock(const String& name) const;
+		GpuParamBlockPtr getParamBlock(UINT32 slot) const;
+		GpuParamBlockPtr getParamBlock(const String& name) const;
 
 
-		void setParamBlock(UINT32 slot, GpuParamBlockBufferPtr paramBlock);
-		void setParamBlock(const String& name, GpuParamBlockBufferPtr paramBlock);
+		void setParamBlock(UINT32 slot, GpuParamBlockPtr paramBlock);
+		void setParamBlock(const String& name, GpuParamBlockPtr paramBlock);
 
 
 		const GpuParamDesc& getParamDesc() const { return mParamDesc; }
 		const GpuParamDesc& getParamDesc() const { return mParamDesc; }
 
 
 		bool hasParam(const String& name) const;
 		bool hasParam(const String& name) const;
 		bool hasTexture(const String& name) const;
 		bool hasTexture(const String& name) const;
 		bool hasSamplerState(const String& name) const;
 		bool hasSamplerState(const String& name) const;
+		bool hasParamBlock(const String& name) const;
 
 
 		void setParam(const String& name, float value, UINT32 arrayIndex = 0);
 		void setParam(const String& name, float value, UINT32 arrayIndex = 0);
 		void setParam(const String& name, int value, UINT32 arrayIndex = 0);
 		void setParam(const String& name, int value, UINT32 arrayIndex = 0);
@@ -57,9 +58,9 @@ namespace CamelotEngine
 		GpuParamDesc& mParamDesc;
 		GpuParamDesc& mParamDesc;
 		bool mTransposeMatrices;
 		bool mTransposeMatrices;
 
 
-		GpuParamMemberDesc* getParamDesc(const String& name) const;
+		GpuParamDataDesc* getParamDesc(const String& name) const;
 
 
-		vector<GpuParamBlockBufferPtr>::type mParamBlocks;
+		vector<GpuParamBlockPtr>::type mParamBlocks;
 		vector<TextureHandle>::type mTextures;
 		vector<TextureHandle>::type mTextures;
 		vector<SamplerStatePtr>::type mSamplerStates;
 		vector<SamplerStatePtr>::type mSamplerStates;
 	};
 	};

+ 2 - 0
CamelotRenderer/Include/CmGpuProgram.h

@@ -142,6 +142,8 @@ namespace CamelotEngine {
         */
         */
 		virtual GpuParamsPtr createParameters();
 		virtual GpuParamsPtr createParameters();
 
 
+		const GpuParamDesc& getParamDesc() const { return mParametersDesc; }
+
 		/** Returns a string that specifies the language of the gpu programs as specified
 		/** Returns a string that specifies the language of the gpu programs as specified
         in a material script. ie: asm, cg, hlsl, glsl
         in a material script. ie: asm, cg, hlsl, glsl
         */
         */

+ 1 - 1
CamelotRenderer/Include/CmHardwareBufferManager.h

@@ -109,7 +109,7 @@ namespace CamelotEngine {
 		 *
 		 *
 		 * @return	The new GPU parameter block.
 		 * @return	The new GPU parameter block.
 		 */
 		 */
-		virtual GpuParamBlockBufferPtr createGpuParamBlockBuffer(const GpuParamBlockDesc& paramDesc) = 0;
+		virtual GpuParamBlockPtr createGpuParamBlock(const GpuParamBlockDesc& paramDesc, GpuParamBlockUsage usage = GPBU_STATIC) = 0;
 
 
 		/**
 		/**
 		 * @brief	Creates a generic buffer that can be passed as a parameter to a shader.
 		 * @brief	Creates a generic buffer that can be passed as a parameter to a shader.

+ 16 - 3
CamelotRenderer/Include/CmMaterial.h

@@ -2,7 +2,7 @@
 
 
 #include "CmPrerequisites.h"
 #include "CmPrerequisites.h"
 #include "CmResource.h"
 #include "CmResource.h"
-#include "CmGpuParams.h"
+#include "CmCommonEnums.h"
 
 
 namespace CamelotEngine
 namespace CamelotEngine
 {
 {
@@ -60,6 +60,8 @@ namespace CamelotEngine
 		void setMat3(const String& name, const Matrix3& value);
 		void setMat3(const String& name, const Matrix3& value);
 		void setMat4(const String& name, const Matrix4& value);
 		void setMat4(const String& name, const Matrix4& value);
 
 
+		void setParamBlock(const String& name, GpuParamBlockPtr paramBlock);
+
 		UINT32 getNumPasses() const;
 		UINT32 getNumPasses() const;
 
 
 		PassPtr getPass(UINT32 passIdx) const;
 		PassPtr getPass(UINT32 passIdx) const;
@@ -69,14 +71,18 @@ namespace CamelotEngine
 	private:
 	private:
 		ShaderPtr mShader;
 		ShaderPtr mShader;
 		TechniquePtr mBestTechnique;
 		TechniquePtr mBestTechnique;
-		vector<PassParametersPtr>::type mParameters;
+
+		set<String>::type mValidShareableParamBlocks;
+		set<String>::type mValidParams;
+
+		vector<PassParametersPtr>::type mParametersPerPass;
 
 
 		void throwIfNotInitialized() const;
 		void throwIfNotInitialized() const;
 
 
 		template <typename T>
 		template <typename T>
 		void setParam(const String& name, T& value)
 		void setParam(const String& name, T& value)
 		{
 		{
-			for(auto iter = mParameters.begin(); iter != mParameters.end(); ++iter)
+			for(auto iter = mParametersPerPass.begin(); iter != mParametersPerPass.end(); ++iter)
 			{
 			{
 				PassParametersPtr params = *iter;
 				PassParametersPtr params = *iter;
 
 
@@ -94,6 +100,13 @@ namespace CamelotEngine
 
 
 		void initBestTechnique();
 		void initBestTechnique();
 
 
+		set<String>::type determineValidParameters(const vector<const GpuParamDesc*>::type& paramDescs) const;
+		set<String>::type determineValidShareableParamBlocks(const vector<const GpuParamDesc*>::type& paramDescs) const;
+		map<String, String>::type determineParameterToBlockMapping(const vector<const GpuParamDesc*>::type& paramDescs);
+
+		bool areParamsEqual(const GpuParamDataDesc& paramA, const GpuParamDataDesc& paramB, bool ignoreBufferOffsets = false) const;
+		bool areParamsEqual(const GpuParamObjectDesc& paramA, const GpuParamObjectDesc& paramB) const;
+
 		/************************************************************************/
 		/************************************************************************/
 		/* 								RTTI		                     		*/
 		/* 								RTTI		                     		*/
 		/************************************************************************/
 		/************************************************************************/

+ 4 - 3
CamelotRenderer/Include/CmPrerequisites.h

@@ -135,10 +135,11 @@ namespace CamelotEngine {
 	class RenderStateManager;
 	class RenderStateManager;
 	class RasterizerState;
 	class RasterizerState;
 	class BlendState;
 	class BlendState;
-	class GpuParamBlockBuffer;
+	class GpuParamBlock;
 	class GpuParams;
 	class GpuParams;
 	struct GpuParamDesc;
 	struct GpuParamDesc;
-	struct GpuParamMemberDesc;
+	struct GpuParamDataDesc;
+	struct GpuParamObjectDesc;
 	struct GpuParamBlockDesc;
 	struct GpuParamBlockDesc;
 	class TextureView;
 	class TextureView;
 	// Asset import
 	// Asset import
@@ -197,7 +198,7 @@ namespace CamelotEngine
 	typedef std::shared_ptr<RenderTarget> RenderTargetPtr;
 	typedef std::shared_ptr<RenderTarget> RenderTargetPtr;
 	typedef std::shared_ptr<RenderTexture> RenderTexturePtr;
 	typedef std::shared_ptr<RenderTexture> RenderTexturePtr;
 	typedef std::shared_ptr<MultiRenderTexture> MultiRenderTexturePtr;
 	typedef std::shared_ptr<MultiRenderTexture> MultiRenderTexturePtr;
-	typedef std::shared_ptr<GpuParamBlockBuffer> GpuParamBlockBufferPtr;
+	typedef std::shared_ptr<GpuParamBlock> GpuParamBlockPtr;
 	typedef std::shared_ptr<GpuParams> GpuParamsPtr;
 	typedef std::shared_ptr<GpuParams> GpuParamsPtr;
 	typedef std::shared_ptr<TextureView> TextureViewPtr;
 	typedef std::shared_ptr<TextureView> TextureViewPtr;
 }
 }

+ 37 - 0
CamelotRenderer/Include/CmShader.h

@@ -2,9 +2,33 @@
 
 
 #include "CmPrerequisites.h"
 #include "CmPrerequisites.h"
 #include "CmResource.h"
 #include "CmResource.h"
+#include "CmCommonEnums.h"
 
 
 namespace CamelotEngine
 namespace CamelotEngine
 {
 {
+	struct CM_EXPORT SHADER_DATA_PARAM_DESC
+	{
+		String name;
+		String gpuVariableName;
+		GpuParamDataType type;
+		UINT32 arraySize;
+		bool hidden;
+	};
+
+	struct CM_EXPORT SHADER_OBJECT_PARAM_DESC
+	{
+		String name;
+		String gpuVariableName;
+		GpuParamObjectType type;
+		bool hidden;
+	};
+
+	struct CM_EXPORT SHADER_PARAM_BLOCK_DESC
+	{
+		bool shared;
+		GpuParamBlockUsage usage;
+	};
+
 	/**
 	/**
 	 * @brief	Shader represents a collection of techniques. They are used in Materials,
 	 * @brief	Shader represents a collection of techniques. They are used in Materials,
 	 * 			which can be considered as instances of a Shader. Multiple materials
 	 * 			which can be considered as instances of a Shader. Multiple materials
@@ -37,10 +61,23 @@ namespace CamelotEngine
 		 */
 		 */
 		TechniquePtr getBestTechnique() const;
 		TechniquePtr getBestTechnique() const;
 
 
+		void addParameter(const String& name, const String& gpuVariableName, GpuParamDataType type, UINT32 arraySize = 1, bool hidden = false);
+		void addParameter(const String& name, const String& gpuVariableName, GpuParamObjectType type, bool hidden = false);
+		void removeParameter(const String& name);
+		void setParamBlockAttribs(const String& name, bool shared, GpuParamBlockUsage usage);
+
+		const map<String, SHADER_DATA_PARAM_DESC>::type& getDataParams() const { return mDataParams; }
+		const map<String, SHADER_OBJECT_PARAM_DESC>::type& getObjectParams() const { return mObjectParams; }
+		const map<String, SHADER_PARAM_BLOCK_DESC>::type& getParamBlocks() const { return mParamBlocks; }
+
 	private:
 	private:
 		String mName;
 		String mName;
 		vector<TechniquePtr>::type mTechniques;
 		vector<TechniquePtr>::type mTechniques;
 
 
+		map<String, SHADER_DATA_PARAM_DESC>::type mDataParams;
+		map<String, SHADER_OBJECT_PARAM_DESC>::type mObjectParams;
+		map<String, SHADER_PARAM_BLOCK_DESC>::type mParamBlocks;
+
 		/************************************************************************/
 		/************************************************************************/
 		/* 								RTTI		                     		*/
 		/* 								RTTI		                     		*/
 		/************************************************************************/
 		/************************************************************************/

+ 10 - 10
CamelotRenderer/Source/CmGpuParamBlock.cpp

@@ -5,7 +5,7 @@
 
 
 namespace CamelotEngine
 namespace CamelotEngine
 {
 {
-	GpuParamBlockBuffer::GpuParamBlockBuffer(const GpuParamBlockDesc& desc)
+	GpuParamBlock::GpuParamBlock(const GpuParamBlockDesc& desc, GpuParamBlockUsage usage)
 		:mSize(desc.blockSize * sizeof(UINT32)), mOwnsSharedData(true)
 		:mSize(desc.blockSize * sizeof(UINT32)), mOwnsSharedData(true)
 	{
 	{
 		mData = new UINT8[mSize];
 		mData = new UINT8[mSize];
@@ -16,7 +16,7 @@ namespace CamelotEngine
 		sharedData->mInitialized = false;
 		sharedData->mInitialized = false;
 	}
 	}
 
 
-	GpuParamBlockBuffer::~GpuParamBlockBuffer()
+	GpuParamBlock::~GpuParamBlock()
 	{
 	{
 		delete [] mData;
 		delete [] mData;
 
 
@@ -24,7 +24,7 @@ namespace CamelotEngine
 			delete sharedData;
 			delete sharedData;
 	}
 	}
 
 
-	void GpuParamBlockBuffer::write(UINT32 offset, const void* data, UINT32 size)
+	void GpuParamBlock::write(UINT32 offset, const void* data, UINT32 size)
 	{
 	{
 #if CM_DEBUG_MODE
 #if CM_DEBUG_MODE
 		if(offset < 0 || (offset + size) > mSize)
 		if(offset < 0 || (offset + size) > mSize)
@@ -40,7 +40,7 @@ namespace CamelotEngine
 		sharedData->mDirty = true;
 		sharedData->mDirty = true;
 	}
 	}
 
 
-	void GpuParamBlockBuffer::zeroOut(UINT32 offset, UINT32 size)
+	void GpuParamBlock::zeroOut(UINT32 offset, UINT32 size)
 	{
 	{
 #if CM_DEBUG_MODE
 #if CM_DEBUG_MODE
 		if(offset < 0 || (offset + size) > mSize)
 		if(offset < 0 || (offset + size) > mSize)
@@ -56,7 +56,7 @@ namespace CamelotEngine
 		sharedData->mDirty = true;
 		sharedData->mDirty = true;
 	}
 	}
 
 
-	const UINT8* GpuParamBlockBuffer::getDataPtr(UINT32 offset) const
+	const UINT8* GpuParamBlock::getDataPtr(UINT32 offset) const
 	{
 	{
 #if CM_DEBUG_MODE
 #if CM_DEBUG_MODE
 		if(offset < 0 || offset >= mSize)
 		if(offset < 0 || offset >= mSize)
@@ -70,16 +70,16 @@ namespace CamelotEngine
 		return &mData[offset];
 		return &mData[offset];
 	}
 	}
 
 
-	void GpuParamBlockBuffer::updateIfDirty()
+	void GpuParamBlock::updateIfDirty()
 	{
 	{
 		sharedData->mDirty = false;
 		sharedData->mDirty = false;
 
 
 		// Do nothing
 		// Do nothing
 	}
 	}
 
 
-	GpuParamBlockBufferPtr GpuParamBlockBuffer::clone() const
+	GpuParamBlockPtr GpuParamBlock::clone() const
 	{
 	{
-		GpuParamBlockBufferPtr clonedParamBlock(new GpuParamBlockBuffer(*this));
+		GpuParamBlockPtr clonedParamBlock(new GpuParamBlock(*this));
 		clonedParamBlock->mData = new UINT8[mSize];
 		clonedParamBlock->mData = new UINT8[mSize];
 		clonedParamBlock->mSize = mSize;
 		clonedParamBlock->mSize = mSize;
 		clonedParamBlock->mOwnsSharedData = false;
 		clonedParamBlock->mOwnsSharedData = false;
@@ -88,8 +88,8 @@ namespace CamelotEngine
 		return clonedParamBlock;
 		return clonedParamBlock;
 	}
 	}
 
 
-	GpuParamBlockBufferPtr GpuParamBlockBuffer::create(const GpuParamBlockDesc& desc)
+	GpuParamBlockPtr GpuParamBlock::create(const GpuParamBlockDesc& desc)
 	{
 	{
-		return HardwareBufferManager::instance().createGpuParamBlockBuffer(desc);
+		return HardwareBufferManager::instance().createGpuParamBlock(desc);
 	}
 	}
 }
 }

+ 20 - 13
CamelotRenderer/Source/CmGpuParams.cpp

@@ -19,11 +19,6 @@ namespace CamelotEngine
 
 
 		mParamBlocks.resize(numParamBlockSlots);
 		mParamBlocks.resize(numParamBlockSlots);
 
 
-		for(auto iter = mParamDesc.paramBlocks.begin(); iter != mParamDesc.paramBlocks.end(); ++iter)
-		{
-			mParamBlocks[iter->second.slot] = GpuParamBlockBuffer::create(iter->second);
-		}
-
 		UINT32 numTextureSlots = 0;
 		UINT32 numTextureSlots = 0;
 		for(auto iter = mParamDesc.textures.begin(); iter != mParamDesc.textures.end(); ++iter)
 		for(auto iter = mParamDesc.textures.begin(); iter != mParamDesc.textures.end(); ++iter)
 		{
 		{
@@ -43,7 +38,7 @@ namespace CamelotEngine
 		mSamplerStates.resize(numSamplerSlots);
 		mSamplerStates.resize(numSamplerSlots);
 	}
 	}
 
 
-	GpuParamBlockBufferPtr GpuParams::getParamBlock(UINT32 slot) const
+	GpuParamBlockPtr GpuParams::getParamBlock(UINT32 slot) const
 	{
 	{
 		if(slot < 0 || slot >= (UINT32)mParamBlocks.size())
 		if(slot < 0 || slot >= (UINT32)mParamBlocks.size())
 		{
 		{
@@ -54,7 +49,7 @@ namespace CamelotEngine
 		return mParamBlocks[slot];
 		return mParamBlocks[slot];
 	}
 	}
 
 
-	GpuParamBlockBufferPtr GpuParams::getParamBlock(const String& name) const
+	GpuParamBlockPtr GpuParams::getParamBlock(const String& name) const
 	{
 	{
 		auto iterFind = mParamDesc.paramBlocks.find(name);
 		auto iterFind = mParamDesc.paramBlocks.find(name);
 
 
@@ -67,7 +62,7 @@ namespace CamelotEngine
 		return mParamBlocks[iterFind->second.slot];
 		return mParamBlocks[iterFind->second.slot];
 	}
 	}
 
 
-	void GpuParams::setParamBlock(UINT32 slot, GpuParamBlockBufferPtr paramBlock)
+	void GpuParams::setParamBlock(UINT32 slot, GpuParamBlockPtr paramBlock)
 	{
 	{
 		if(slot < 0 || slot >= (UINT32)mParamBlocks.size())
 		if(slot < 0 || slot >= (UINT32)mParamBlocks.size())
 		{
 		{
@@ -78,7 +73,7 @@ namespace CamelotEngine
 		mParamBlocks[slot] = paramBlock;
 		mParamBlocks[slot] = paramBlock;
 	}
 	}
 
 
-	void GpuParams::setParamBlock(const String& name, GpuParamBlockBufferPtr paramBlock)
+	void GpuParams::setParamBlock(const String& name, GpuParamBlockPtr paramBlock)
 	{
 	{
 		auto iterFind = mParamDesc.paramBlocks.find(name);
 		auto iterFind = mParamDesc.paramBlocks.find(name);
 
 
@@ -114,6 +109,15 @@ namespace CamelotEngine
 		return false;
 		return false;
 	}
 	}
 
 
+	bool GpuParams::hasParamBlock(const String& name) const
+	{
+		auto paramBlockIter = mParamDesc.paramBlocks.find(name);
+		if(paramBlockIter != mParamDesc.paramBlocks.end())
+			return true;
+
+		return false;
+	}
+
 	void GpuParams::setParam(const String& name, float value, UINT32 arrayIndex)
 	void GpuParams::setParam(const String& name, float value, UINT32 arrayIndex)
 	{
 	{
 		setParam(name, (void*)&value, 1 * sizeof(float), arrayIndex);
 		setParam(name, (void*)&value, 1 * sizeof(float), arrayIndex);
@@ -177,7 +181,7 @@ namespace CamelotEngine
 
 
 	void GpuParams::setParam(const String& name, const void* value, UINT32 sizeBytes, UINT32 arrayIndex)
 	void GpuParams::setParam(const String& name, const void* value, UINT32 sizeBytes, UINT32 arrayIndex)
 	{
 	{
-		GpuParamMemberDesc* desc = getParamDesc(name);
+		GpuParamDataDesc* desc = getParamDesc(name);
 
 
 		if(desc == nullptr)
 		if(desc == nullptr)
 		{
 		{
@@ -198,7 +202,7 @@ namespace CamelotEngine
 				toString(elementSizeBytes) + ". Supplied size: " + toString(sizeBytes));
 				toString(elementSizeBytes) + ". Supplied size: " + toString(sizeBytes));
 		}
 		}
 
 
-		GpuParamBlockBufferPtr paramBlock = mParamBlocks[desc->paramBlockSlot];
+		GpuParamBlockPtr paramBlock = mParamBlocks[desc->paramBlockSlot];
 
 
 		if(paramBlock == nullptr)
 		if(paramBlock == nullptr)
 		{
 		{
@@ -278,10 +282,13 @@ namespace CamelotEngine
 	void GpuParams::updateIfDirty()
 	void GpuParams::updateIfDirty()
 	{
 	{
 		for(size_t i = 0; i < mParamBlocks.size(); i++)
 		for(size_t i = 0; i < mParamBlocks.size(); i++)
-			mParamBlocks[i]->updateIfDirty();
+		{
+			if(mParamBlocks[i] != nullptr)
+				mParamBlocks[i]->updateIfDirty();
+		}
 	}
 	}
 
 
-	GpuParamMemberDesc* GpuParams::getParamDesc(const String& name) const
+	GpuParamDataDesc* GpuParams::getParamDesc(const String& name) const
 	{
 	{
 		auto paramIter = mParamDesc.params.find(name);
 		auto paramIter = mParamDesc.params.find(name);
 		if(paramIter != mParamDesc.params.end())
 		if(paramIter != mParamDesc.params.end())

+ 519 - 34
CamelotRenderer/Source/CmMaterial.cpp

@@ -5,8 +5,11 @@
 #include "CmPass.h"
 #include "CmPass.h"
 #include "CmRenderSystem.h"
 #include "CmRenderSystem.h"
 #include "CmGpuProgramParams.h"
 #include "CmGpuProgramParams.h"
+#include "CmHardwareBufferManager.h"
 #include "CmGpuProgram.h"
 #include "CmGpuProgram.h"
+#include "CmGpuParamDesc.h"
 #include "CmMaterialRTTI.h"
 #include "CmMaterialRTTI.h"
+#include "CmDebug.h"
 
 
 namespace CamelotEngine
 namespace CamelotEngine
 {
 {
@@ -31,65 +34,451 @@ namespace CamelotEngine
 	void Material::initBestTechnique()
 	void Material::initBestTechnique()
 	{
 	{
 		mBestTechnique = nullptr;
 		mBestTechnique = nullptr;
-		mParameters.clear();
+		mParametersPerPass.clear();
 
 
 		if(mShader)
 		if(mShader)
 		{
 		{
 			mBestTechnique = mShader->getBestTechnique();
 			mBestTechnique = mShader->getBestTechnique();
 
 
-			if(mBestTechnique)
+			if(mBestTechnique == nullptr)
+				return;
+
+			mValidShareableParamBlocks.clear();
+			mValidParams.clear();
+
+			vector<const GpuParamDesc*>::type allParamDescs;
+
+			// Make sure all gpu programs are fully loaded
+			for(UINT32 i = 0; i < mBestTechnique->getNumPasses(); i++)
+			{
+				PassPtr curPass = mBestTechnique->getPass(i);
+
+				GpuProgramHandle vertProgram = curPass->getVertexProgram();
+				if(vertProgram)
+				{
+					vertProgram.waitUntilLoaded();
+					allParamDescs.push_back(&vertProgram->getParamDesc());
+				}
+
+				GpuProgramHandle fragProgram = curPass->getFragmentProgram();
+				if(fragProgram)
+				{
+					fragProgram.waitUntilLoaded();
+					allParamDescs.push_back(&fragProgram->getParamDesc());
+				}
+
+				GpuProgramHandle geomProgram = curPass->getGeometryProgram();
+				if(geomProgram)
+				{
+					geomProgram.waitUntilLoaded();
+					allParamDescs.push_back(&geomProgram->getParamDesc());
+				}
+
+				GpuProgramHandle hullProgram = curPass->getHullProgram();
+				if(hullProgram)
+				{
+					hullProgram.waitUntilLoaded();
+					allParamDescs.push_back(&hullProgram->getParamDesc());
+				}
+
+				GpuProgramHandle domainProgram = curPass->getDomainProgram();
+				if(domainProgram)
+				{
+					domainProgram.waitUntilLoaded();
+					allParamDescs.push_back(&domainProgram->getParamDesc());
+				}
+
+				GpuProgramHandle computeProgram = curPass->getComputeProgram();
+				if(computeProgram)
+				{
+					computeProgram.waitUntilLoaded();
+					allParamDescs.push_back(&computeProgram->getParamDesc());
+				}
+			}
+
+			set<String>::type validParameters = determineValidParameters(allParamDescs);
+			set<String>::type validShareableParamBlocks = determineValidShareableParamBlocks(allParamDescs);
+			map<String, String>::type paramToParamBlockMap = determineParameterToBlockMapping(allParamDescs);
+			map<String, GpuParamBlockPtr>::type paramBlocks;
+
+			// Create param blocks
+			const map<String, SHADER_PARAM_BLOCK_DESC>::type& shaderDesc = mShader->getParamBlocks();
+			for(auto iter = validShareableParamBlocks.begin(); iter != validShareableParamBlocks.end(); ++iter)
+			{
+				bool isShared = false;
+				GpuParamBlockUsage usage = GPBU_STATIC;
+
+				auto iterFind = shaderDesc.find(*iter);
+				if(iterFind != shaderDesc.end())
+				{
+					isShared = iterFind->second.shared;
+					usage = iterFind->second.usage;
+				}
+
+				GpuParamBlockDesc blockDesc;
+				for(auto iter2 = allParamDescs.begin(); iter2 != allParamDescs.end(); ++iter2)
+				{
+					auto findParamBlockDesc = (*iter2)->paramBlocks.find(*iter);
+
+					if(findParamBlockDesc != (*iter2)->paramBlocks.end())
+					{
+						blockDesc = findParamBlockDesc->second;
+						break;
+					}
+				}
+
+				GpuParamBlockPtr newParamBlockBuffer;
+				if(!isShared)
+					newParamBlockBuffer = HardwareBufferManager::instance().createGpuParamBlock(blockDesc, usage);
+
+				paramBlocks[*iter] = newParamBlockBuffer;
+				mValidShareableParamBlocks.insert(*iter);
+			}
+
+			// Create data param mappings
+			const map<String, SHADER_DATA_PARAM_DESC>::type& dataParamDesc = mShader->getDataParams();
+			for(auto iter = dataParamDesc.begin(); iter != dataParamDesc.end(); ++iter)
+			{
+				auto findIter = validParameters.find(iter->first);
+
+				// Not valid so we skip it
+				if(findIter == validParameters.end())
+					continue;
+
+				auto findBlockIter = paramToParamBlockMap.find(iter->first);
+
+				if(findBlockIter == paramToParamBlockMap.end())
+					CM_EXCEPT(InternalErrorException, "Parameter doesn't exist in param to param block map but exists in valid param map.");
+
+				String& paramBlockName = findBlockIter->second;
+				mValidParams.insert(iter->first);
+			}
+
+			// Create object param mappings
+			const map<String, SHADER_OBJECT_PARAM_DESC>::type& objectParamDesc = mShader->getObjectParams();
+			for(auto iter = objectParamDesc.begin(); iter != objectParamDesc.end(); ++iter)
+			{
+				auto findIter = validParameters.find(iter->first);
+
+				// Not valid so we skip it
+				if(findIter == validParameters.end())
+					continue;
+
+				mValidParams.insert(iter->first);
+			}
+
+			for(UINT32 i = 0; i < mBestTechnique->getNumPasses(); i++)
 			{
 			{
-				for(UINT32 i = 0; i < mBestTechnique->getNumPasses(); i++)
+				PassPtr curPass = mBestTechnique->getPass(i);
+				PassParametersPtr params = PassParametersPtr(new PassParameters());
+
+				GpuProgramHandle vertProgram = curPass->getVertexProgram();
+				if(vertProgram)
+					params->mVertParams = vertProgram->createParameters();
+
+				GpuProgramHandle fragProgram = curPass->getFragmentProgram();
+				if(fragProgram)
+					params->mFragParams = fragProgram->createParameters();
+
+				GpuProgramHandle geomProgram = curPass->getGeometryProgram();
+				if(geomProgram)
+					params->mGeomParams = geomProgram->createParameters();	
+
+				GpuProgramHandle hullProgram = curPass->getHullProgram();
+				if(hullProgram)
+					params->mHullParams = hullProgram->createParameters();
+
+				GpuProgramHandle domainProgram = curPass->getDomainProgram();
+				if(domainProgram)
+					params->mDomainParams = domainProgram->createParameters();
+
+				GpuProgramHandle computeProgram = curPass->getComputeProgram();
+				if(computeProgram)
+					params->mComputeParams = computeProgram->createParameters();	
+
+				mParametersPerPass.push_back(params);
+			}
+
+			// Assign param block buffers
+			for(auto iter = mParametersPerPass.begin(); iter != mParametersPerPass.end(); ++iter)
+			{
+				PassParametersPtr params = *iter;
+
+				for(UINT32 i = 0; i < params->getNumParams(); i++)
 				{
 				{
-					PassPtr curPass = mBestTechnique->getPass(i);
-					PassParametersPtr params = PassParametersPtr(new PassParameters());
+					GpuParamsPtr& paramPtr = params->getParamByIdx(i);
+					if(paramPtr)
+					{
+						// Assign shareable buffers
+						for(auto iterBlock = mValidShareableParamBlocks.begin(); iterBlock != mValidShareableParamBlocks.end(); ++iterBlock)
+						{
+							const String& paramBlockName = *iterBlock;
+							if(paramPtr->hasParamBlock(paramBlockName))
+							{
+								GpuParamBlockPtr blockBuffer = paramBlocks[paramBlockName];
+
+								paramPtr->setParamBlock(paramBlockName, blockBuffer);
+							}
+						}
+
+						// Create non-shareable ones
+						const GpuParamDesc& desc = paramPtr->getParamDesc();
+						for(auto iterBlockDesc = desc.paramBlocks.begin(); iterBlockDesc != desc.paramBlocks.end(); ++iterBlockDesc)
+						{
+							if(!iterBlockDesc->second.isShareable)
+							{
+								GpuParamBlockPtr newParamBlockBuffer = HardwareBufferManager::instance().createGpuParamBlock(iterBlockDesc->second);
+								paramPtr->setParamBlock(iterBlockDesc->first, newParamBlockBuffer);
+							}
+						}
+					}
+				}
+			}
+		}
+	}
+
+	set<String>::type Material::determineValidParameters(const vector<const GpuParamDesc*>::type& paramDescs) const
+	{
+		map<String, const GpuParamDataDesc*>::type foundDataParams;
+		map<String, const GpuParamObjectDesc*>::type foundObjectParams;
+
+		set<String>::type validParameters;
 
 
-					GpuProgramHandle vertProgram = curPass->getVertexProgram();
-					if(vertProgram)
+		for(auto iter = paramDescs.begin(); iter != paramDescs.end(); ++iter)
+		{
+			const GpuParamDesc& curDesc = **iter;
+
+			// Check regular data params
+			for(auto iter2 = curDesc.params.begin(); iter2 != curDesc.params.end(); ++iter2)
+			{
+				bool isParameterValid = true;
+				const GpuParamDataDesc& curParam = iter2->second;
+
+				auto objectFindIter = foundObjectParams.find(iter2->first);
+				if(objectFindIter != foundObjectParams.end())
+					isParameterValid = false; // Data param but we found another as object param with the same name
+
+				if(isParameterValid)
+				{
+					auto dataFindIter = foundDataParams.find(iter2->first);
+					if(dataFindIter == foundDataParams.end())
+						validParameters.insert(iter2->first);
+					else
 					{
 					{
-						vertProgram.waitUntilLoaded();
-						params->mVertParams = vertProgram->createParameters();
+						const GpuParamDataDesc* otherParam = dataFindIter->second;
+						if(!areParamsEqual(curParam, *otherParam, true))
+							isParameterValid = false;
 					}
 					}
+				}
+
+				if(!isParameterValid)
+					validParameters.erase(iter2->first);
+			}
+
+			// Check sampler params
+			for(auto iter2 = curDesc.samplers.begin(); iter2 != curDesc.samplers.end(); ++iter2)
+			{
+				bool isParameterValid = true;
+				const GpuParamObjectDesc& curParam = iter2->second;
+
+				auto dataFindIter = foundDataParams.find(iter2->first);
+				if(dataFindIter != foundDataParams.end())
+					isParameterValid = false; // Object param but we found another as data param with the same name
+
+				if(isParameterValid)
+				{
+					auto objectFindIter = foundObjectParams.find(iter2->first);
+					if(objectFindIter == foundObjectParams.end())
+						validParameters.insert(iter2->first);
+					else
+					{
+						const GpuParamObjectDesc* otherParam = objectFindIter->second;
+						if(!areParamsEqual(curParam, *otherParam))
+							isParameterValid = false;
+					}
+				}
+
+				if(!isParameterValid)
+					validParameters.erase(iter2->first);
+			}
+
+			// Check texture params
+			for(auto iter2 = curDesc.textures.begin(); iter2 != curDesc.textures.end(); ++iter2)
+			{
+				bool isParameterValid = true;
+				const GpuParamObjectDesc& curParam = iter2->second;
+
+				auto dataFindIter = foundDataParams.find(iter2->first);
+				if(dataFindIter != foundDataParams.end())
+					isParameterValid = false; // Object param but we found another as data param with the same name
+
+				if(isParameterValid)
+				{
+					auto objectFindIter = foundObjectParams.find(iter2->first);
+					if(objectFindIter == foundObjectParams.end())
+						validParameters.insert(iter2->first);
+					else
+					{
+						const GpuParamObjectDesc* otherParam = objectFindIter->second;
+						if(!areParamsEqual(curParam, *otherParam))
+							isParameterValid = false;
+					}
+				}
+
+				if(!isParameterValid)
+					validParameters.erase(iter2->first);
+			}
+
+			// Check buffer params
+			for(auto iter2 = curDesc.buffers.begin(); iter2 != curDesc.buffers.end(); ++iter2)
+			{
+				bool isParameterValid = true;
+				const GpuParamObjectDesc& curParam = iter2->second;
 
 
-					GpuProgramHandle fragProgram = curPass->getFragmentProgram();
-					if(fragProgram)
+				auto dataFindIter = foundDataParams.find(iter2->first);
+				if(dataFindIter != foundDataParams.end())
+					isParameterValid = false; // Object param but we found another as data param with the same name
+
+				if(isParameterValid)
+				{
+					auto objectFindIter = foundObjectParams.find(iter2->first);
+					if(objectFindIter == foundObjectParams.end())
+						validParameters.insert(iter2->first);
+					else
 					{
 					{
-						fragProgram.waitUntilLoaded();
-						params->mFragParams = fragProgram->createParameters();
+						const GpuParamObjectDesc* otherParam = objectFindIter->second;
+						if(!areParamsEqual(curParam, *otherParam))
+							isParameterValid = false;
 					}
 					}
+				}
 
 
-					GpuProgramHandle geomProgram = curPass->getGeometryProgram();
-					if(geomProgram)
+				if(!isParameterValid)
+				{
+					auto validParamIter = validParameters.find(iter2->first);
+
+					if(validParamIter != validParameters.end()) // Do this check so we only report this error once
 					{
 					{
-						geomProgram.waitUntilLoaded();
-						params->mGeomParams = geomProgram->createParameters();	
+						LOGWRN("Found two parameters with the same name but different contents: " + iter2->first);
+						validParameters.erase(validParamIter);
 					}
 					}
+				}
+			}
+		}
+
+		return validParameters;
+	}
+
+	set<String>::type Material::determineValidShareableParamBlocks(const vector<const GpuParamDesc*>::type& paramDescs) const
+	{
+		// Make sure param blocks with the same name actually are the same
+		map<String, std::pair<String, const GpuParamDesc*>>::type uniqueParamBlocks;
+		set<String>::type validParamBlocks;
+
+		for(auto iter = paramDescs.begin(); iter != paramDescs.end(); ++iter)
+		{
+			const GpuParamDesc& curDesc = **iter;
+			for(auto blockIter = curDesc.paramBlocks.begin(); blockIter != curDesc.paramBlocks.end(); ++blockIter)
+			{
+				bool isBlockValid = true;
+				const GpuParamBlockDesc& curBlock = blockIter->second;
+
+				if(!curBlock.isShareable) // Non-shareable buffers are handled differently, they're allowed same names
+					continue;
+
+				auto iterFind = uniqueParamBlocks.find(blockIter->first);
+				if(iterFind == uniqueParamBlocks.end())
+				{
+					uniqueParamBlocks[blockIter->first] = std::make_pair(blockIter->first, *iter);
+					validParamBlocks.insert(blockIter->first);
+					continue;
+				}
+
+				String otherBlockName = iterFind->second.first;
+				const GpuParamDesc* otherDesc = iterFind->second.second;
 
 
-					GpuProgramHandle hullProgram = curPass->getHullProgram();
-					if(hullProgram)
+				for(auto myParamIter = curDesc.params.begin(); myParamIter != curDesc.params.end(); ++myParamIter)
+				{
+					const GpuParamDataDesc& myParam = myParamIter->second;
+
+					if(myParam.paramBlockSlot != curBlock.slot)
+						continue; // Param is in another block, so we will check it when its time for that block
+
+					auto otherParamFind = otherDesc->params.find(myParamIter->first);
+
+					// Cannot find other param, blocks aren't equal
+					if(otherParamFind == otherDesc->params.end())
 					{
 					{
-						hullProgram.waitUntilLoaded();
-						params->mHullParams = hullProgram->createParameters();
+						isBlockValid = false;
+						break;
 					}
 					}
 
 
-					GpuProgramHandle domainProgram = curPass->getDomainProgram();
-					if(domainProgram)
+					const GpuParamDataDesc& otherParam = otherParamFind->second;
+
+					if(!areParamsEqual(myParam, otherParam) || curBlock.name != otherBlockName)
 					{
 					{
-						domainProgram.waitUntilLoaded();
-						params->mDomainParams = domainProgram->createParameters();
+						isBlockValid = false;
+						break;
 					}
 					}
+				}
 
 
-					GpuProgramHandle computeProgram = curPass->getComputeProgram();
-					if(computeProgram)
+				if(!isBlockValid)
+				{
+					auto blockValidIter = validParamBlocks.find(blockIter->first);
+
+					if(blockValidIter != validParamBlocks.end()) // Do this check so we only report this error once
 					{
 					{
-						computeProgram.waitUntilLoaded();
-						params->mComputeParams = computeProgram->createParameters();	
+						LOGWRN("Found two param blocks with the same name but different contents: " + blockIter->first);
+						validParamBlocks.erase(blockValidIter);
 					}
 					}
+				}
+			}
+		}
+
+		return validParamBlocks;
+	}
 
 
-					mParameters.push_back(params);
+	map<String, String>::type Material::determineParameterToBlockMapping(const vector<const GpuParamDesc*>::type& paramDescs)
+	{
+		map<String, String>::type paramToParamBlock;
+
+		for(auto iter = paramDescs.begin(); iter != paramDescs.end(); ++iter)
+		{
+			const GpuParamDesc& curDesc = **iter;
+			for(auto iter2 = curDesc.params.begin(); iter2 != curDesc.params.end(); ++iter2)
+			{
+				const GpuParamDataDesc& curParam = iter2->second;
+				
+				auto iterFind = paramToParamBlock.find(curParam.name);
+				if(iterFind != paramToParamBlock.end())
+					continue;
+
+				for(auto iterBlock = curDesc.paramBlocks.begin(); iterBlock != curDesc.paramBlocks.end(); ++iterBlock)
+				{
+					if(iterBlock->second.slot == curParam.paramBlockSlot)
+					{
+						paramToParamBlock[curParam.name] = iterBlock->second.name;
+						break;
+					}
 				}
 				}
 			}
 			}
 		}
 		}
+
+		return paramToParamBlock;
+	}
+
+	bool Material::areParamsEqual(const GpuParamDataDesc& paramA, const GpuParamDataDesc& paramB, bool ignoreBufferOffsets) const
+	{
+		bool equal = paramA.arraySize == paramB.arraySize && paramA.elementSize == paramB.elementSize && paramA.type == paramB.type;
+
+		if(!ignoreBufferOffsets)
+			equal &= paramA.cpuMemOffset == paramB.cpuMemOffset && paramA.gpuMemOffset == paramB.gpuMemOffset;
+
+		return equal;
+	}
+
+	bool Material::areParamsEqual(const GpuParamObjectDesc& paramA, const GpuParamObjectDesc& paramB) const
+	{
+		return paramA.type == paramB.type;
 	}
 	}
 
 
 	void Material::throwIfNotInitialized() const
 	void Material::throwIfNotInitialized() const
@@ -109,7 +498,14 @@ namespace CamelotEngine
 	{
 	{
 		throwIfNotInitialized();
 		throwIfNotInitialized();
 
 
-		for(auto iter = mParameters.begin(); iter != mParameters.end(); ++iter)
+		auto iterFind = mValidParams.find(name);
+		if(iterFind == mValidParams.end())
+		{
+			LOGWRN("Material doesn't have a parameter named " + name);
+			return;
+		}
+
+		for(auto iter = mParametersPerPass.begin(); iter != mParametersPerPass.end(); ++iter)
 		{
 		{
 			PassParametersPtr params = *iter;
 			PassParametersPtr params = *iter;
 
 
@@ -129,7 +525,14 @@ namespace CamelotEngine
 	{
 	{
 		throwIfNotInitialized();
 		throwIfNotInitialized();
 
 
-		for(auto iter = mParameters.begin(); iter != mParameters.end(); ++iter)
+		auto iterFind = mValidParams.find(name);
+		if(iterFind == mValidParams.end())
+		{
+			LOGWRN("Material doesn't have a parameter named " + name);
+			return;
+		}
+
+		for(auto iter = mParametersPerPass.begin(); iter != mParametersPerPass.end(); ++iter)
 		{
 		{
 			PassParametersPtr params = *iter;
 			PassParametersPtr params = *iter;
 
 
@@ -148,45 +551,127 @@ namespace CamelotEngine
 	void Material::setFloat(const String& name, float value)
 	void Material::setFloat(const String& name, float value)
 	{
 	{
 		throwIfNotInitialized();
 		throwIfNotInitialized();
+
+		auto iterFind = mValidParams.find(name);
+		if(iterFind == mValidParams.end())
+		{
+			LOGWRN("Material doesn't have a parameter named " + name);
+			return;
+		}
+
 		setParam(name, value);
 		setParam(name, value);
 	}
 	}
 
 
 	void Material::setColor(const String& name, const Color& value)
 	void Material::setColor(const String& name, const Color& value)
 	{
 	{
 		throwIfNotInitialized();
 		throwIfNotInitialized();
+
+		auto iterFind = mValidParams.find(name);
+		if(iterFind == mValidParams.end())
+		{
+			LOGWRN("Material doesn't have a parameter named " + name);
+			return;
+		}
+
 		setParam(name, value);
 		setParam(name, value);
 	}
 	}
 
 
 	void Material::setVec2(const String& name, const Vector2& value)
 	void Material::setVec2(const String& name, const Vector2& value)
 	{
 	{
 		throwIfNotInitialized();
 		throwIfNotInitialized();
+
+		auto iterFind = mValidParams.find(name);
+		if(iterFind == mValidParams.end())
+		{
+			LOGWRN("Material doesn't have a parameter named " + name);
+			return;
+		}
+
 		setParam(name, value);
 		setParam(name, value);
 	}
 	}
 
 
 	void Material::setVec3(const String& name, const Vector3& value)
 	void Material::setVec3(const String& name, const Vector3& value)
 	{
 	{
 		throwIfNotInitialized();
 		throwIfNotInitialized();
+
+		auto iterFind = mValidParams.find(name);
+		if(iterFind == mValidParams.end())
+		{
+			LOGWRN("Material doesn't have a parameter named " + name);
+			return;
+		}
+
 		setParam(name, value);
 		setParam(name, value);
 	}
 	}
 
 
 	void Material::setVec4(const String& name, const Vector4& value)
 	void Material::setVec4(const String& name, const Vector4& value)
 	{
 	{
 		throwIfNotInitialized();
 		throwIfNotInitialized();
+
+		auto iterFind = mValidParams.find(name);
+		if(iterFind == mValidParams.end())
+		{
+			LOGWRN("Material doesn't have a parameter named " + name);
+			return;
+		}
+
 		setParam(name, value);
 		setParam(name, value);
 	}
 	}
 
 
 	void Material::setMat3(const String& name, const Matrix3& value)
 	void Material::setMat3(const String& name, const Matrix3& value)
 	{
 	{
 		throwIfNotInitialized();
 		throwIfNotInitialized();
+
+		auto iterFind = mValidParams.find(name);
+		if(iterFind == mValidParams.end())
+		{
+			LOGWRN("Material doesn't have a parameter named " + name);
+			return;
+		}
+
 		setParam(name, value);
 		setParam(name, value);
 	}
 	}
 
 
 	void Material::setMat4(const String& name, const Matrix4& value)
 	void Material::setMat4(const String& name, const Matrix4& value)
 	{
 	{
 		throwIfNotInitialized();
 		throwIfNotInitialized();
+
+		auto iterFind = mValidParams.find(name);
+		if(iterFind == mValidParams.end())
+		{
+			LOGWRN("Material doesn't have a parameter named " + name);
+			return;
+		}
+
 		setParam(name, value);
 		setParam(name, value);
 	}
 	}
 
 
+
+	void Material::setParamBlock(const String& name, GpuParamBlockPtr paramBlock)
+	{
+		auto iterFind = mValidShareableParamBlocks.find(name);
+		if(iterFind == mValidShareableParamBlocks.end())
+		{
+			LOGWRN("Material doesn't have a parameter block named " + name);
+			return;
+		}
+
+		for(auto iter = mParametersPerPass.begin(); iter != mParametersPerPass.end(); ++iter)
+		{
+			PassParametersPtr params = *iter;
+
+			for(UINT32 i = 0; i < params->getNumParams(); i++)
+			{
+				GpuParamsPtr& paramPtr = params->getParamByIdx(i);
+				if(paramPtr)
+				{
+					if(paramPtr->hasParamBlock(name))
+						paramPtr->setParam(name, paramBlock);
+				}
+			}
+		}
+	}
+
 	UINT32 Material::getNumPasses() const
 	UINT32 Material::getNumPasses() const
 	{
 	{
 		throwIfNotInitialized();
 		throwIfNotInitialized();
@@ -204,10 +689,10 @@ namespace CamelotEngine
 
 
 	PassParametersPtr Material::getPassParameters(UINT32 passIdx) const
 	PassParametersPtr Material::getPassParameters(UINT32 passIdx) const
 	{
 	{
-		if(passIdx < 0 || passIdx >= mParameters.size())
+		if(passIdx < 0 || passIdx >= mParametersPerPass.size())
 			CM_EXCEPT(InvalidParametersException, "Invalid pass index.");
 			CM_EXCEPT(InvalidParametersException, "Invalid pass index.");
 
 
-		return mParameters[passIdx];
+		return mParametersPerPass[passIdx];
 	}
 	}
 
 
 	RTTITypeBase* Material::getRTTIStatic()
 	RTTITypeBase* Material::getRTTIStatic()

+ 18 - 18
CamelotRenderer/Source/CmMaterialRTTI.cpp

@@ -19,17 +19,17 @@ namespace CamelotEngine
 		std::shared_ptr<MaterialParams> params = std::shared_ptr<MaterialParams>(new MaterialParams());
 		std::shared_ptr<MaterialParams> params = std::shared_ptr<MaterialParams>(new MaterialParams());
 
 
 		vector<GpuParamsPtr>::type allParams;
 		vector<GpuParamsPtr>::type allParams;
-		for(size_t i = 0; i < material->mParameters.size(); i++)
-		{
-			if(material->mParameters[i]->mFragParams != nullptr)
-				allParams.push_back(material->mParameters[i]->mFragParams);
+		//for(size_t i = 0; i < material->mParameters.size(); i++)
+		//{
+		//	if(material->mParameters[i]->mFragParams != nullptr)
+		//		allParams.push_back(material->mParameters[i]->mFragParams);
 
 
-			if(material->mParameters[i]->mVertParams != nullptr)
-				allParams.push_back(material->mParameters[i]->mVertParams);
+		//	if(material->mParameters[i]->mVertParams != nullptr)
+		//		allParams.push_back(material->mParameters[i]->mVertParams);
 
 
-			if(material->mParameters[i]->mGeomParams != nullptr)
-				allParams.push_back(material->mParameters[i]->mGeomParams);
-		}
+		//	if(material->mParameters[i]->mGeomParams != nullptr)
+		//		allParams.push_back(material->mParameters[i]->mGeomParams);
+		//}
 
 
 		for(size_t i = 0; i < allParams.size(); i++)
 		for(size_t i = 0; i < allParams.size(); i++)
 		{
 		{
@@ -128,17 +128,17 @@ namespace CamelotEngine
 		std::shared_ptr<MaterialParams> params = boost::any_cast<std::shared_ptr<MaterialParams>>(material->mRTTIData);
 		std::shared_ptr<MaterialParams> params = boost::any_cast<std::shared_ptr<MaterialParams>>(material->mRTTIData);
 
 
 		vector<GpuParamsPtr>::type allParams;
 		vector<GpuParamsPtr>::type allParams;
-		for(size_t i = 0; i < material->mParameters.size(); i++)
-		{
-			if(material->mParameters[i]->mFragParams != nullptr)
-				allParams.push_back(material->mParameters[i]->mFragParams);
+		//for(size_t i = 0; i < material->mParameters.size(); i++)
+		//{
+		//	if(material->mParameters[i]->mFragParams != nullptr)
+		//		allParams.push_back(material->mParameters[i]->mFragParams);
 
 
-			if(material->mParameters[i]->mVertParams != nullptr)
-				allParams.push_back(material->mParameters[i]->mVertParams);
+		//	if(material->mParameters[i]->mVertParams != nullptr)
+		//		allParams.push_back(material->mParameters[i]->mVertParams);
 
 
-			if(material->mParameters[i]->mGeomParams != nullptr)
-				allParams.push_back(material->mParameters[i]->mGeomParams);
-		}
+		//	if(material->mParameters[i]->mGeomParams != nullptr)
+		//		allParams.push_back(material->mParameters[i]->mGeomParams);
+		//}
 
 
 		for(size_t i = 0; i < allParams.size(); i++)
 		for(size_t i = 0; i < allParams.size(); i++)
 		{
 		{

+ 40 - 0
CamelotRenderer/Source/CmShader.cpp

@@ -64,6 +64,46 @@ namespace CamelotEngine
 		// TODO - Low priority. Instead of throwing an exception use an extremely simple technique that will be supported almost everywhere as a fallback.
 		// TODO - Low priority. Instead of throwing an exception use an extremely simple technique that will be supported almost everywhere as a fallback.
 	}
 	}
 
 
+	void Shader::addParameter(const String& name, const String& gpuVariableName, GpuParamDataType type, UINT32 arraySize, bool hidden)
+	{
+		SHADER_DATA_PARAM_DESC desc;
+		desc.name = name;
+		desc.gpuVariableName = gpuVariableName;
+		desc.type = type;
+		desc.arraySize = arraySize;
+		desc.hidden = hidden;
+
+		mDataParams[name] = desc;
+		mObjectParams.erase(name);
+	}
+
+	void Shader::addParameter(const String& name, const String& gpuVariableName, GpuParamObjectType type, bool hidden)
+	{
+		SHADER_OBJECT_PARAM_DESC desc;
+		desc.name = name;
+		desc.gpuVariableName = gpuVariableName;
+		desc.type = type;
+		desc.hidden = hidden;
+
+		mObjectParams[name] = desc;
+		mDataParams.erase(name);
+	}
+
+	void Shader::removeParameter(const String& name)
+	{
+		mDataParams.erase(name);
+		mObjectParams.erase(name);
+	}
+
+	void Shader::setParamBlockAttribs(const String& name, bool shared, GpuParamBlockUsage usage)
+	{
+		SHADER_PARAM_BLOCK_DESC desc;
+		desc.shared = shared;
+		desc.usage = usage;
+
+		mParamBlocks[name] = desc;
+	}
+
 	RTTITypeBase* Shader::getRTTIStatic()
 	RTTITypeBase* Shader::getRTTIStatic()
 	{
 	{
 		return ShaderRTTI::instance();
 		return ShaderRTTI::instance();

+ 4 - 20
CamelotRenderer/TODO.txt

@@ -50,6 +50,10 @@ Stuff that needs destroy():
   - Shader
   - Shader
   - Technique
   - Technique
 
 
+GpuParamBlock usage is provided in the constructor but isn't used anywhere
+DX9 will have the same name for sampler and texture. This will cause an error in Material param checking.
+DX9 might have problems with checking if buffers are equal. Probably need to ignore "Global" param block
+
 
 
 Add support for include file resource
 Add support for include file resource
 Make sure we can add an include file to a HighLevelGpuProgram, and make sure it uses it
 Make sure we can add an include file to a HighLevelGpuProgram, and make sure it uses it
@@ -58,26 +62,6 @@ Make sure we can add an include file to a HighLevelGpuProgram, and make sure it
 Make Raster/DepthStencil/Blend/Sampler states resources
 Make Raster/DepthStencil/Blend/Sampler states resources
 Make Shader a resource
 Make Shader a resource
 
 
-Make GpuParamBlock a resource
- - Static/Dynamic usage for GpuParamBlock
- - rename current GpuParamBlock into GpuParamBlockBuffer
- - add new class GpuParamBlock that has addParameter(name, gpuProgramVariable, type, visible)
- - it stores data on per-parameter basis
- - it is a Resource and is serializable
- - in Material when an actual technique is chosen, GpuParamBlockBuffer is bound to GpuParamBlock
-
-Shader::addParamBlock(name, GPU_PARAM_BLOCK_DESC, bool shared)
- - If its shared it won't be instantiated manually when material chooses an actual technique
- - When this method is called we check if any parameter rules are broken:
-   - Ignore missing variables from a param block (weaker techniques might not need them all)
-   - Throw an error if the specified variables come from two different param blocks
-   - Global block should be special to accomodate DX9 shaders
-Shader::addParameter(name, gpuVariableName, type, visible) - Only for objects like textures/buffers/samplers
-
-Material::setParameter - does what it did so far
-Material::setSharedGpuParamBlock(name, GpuParamBlock) - makes he specified block share the data
-
-
  Refactor how we handle RenderTargets (no attach/detach, and no waitForVSync propery in RenderSystem)
  Refactor how we handle RenderTargets (no attach/detach, and no waitForVSync propery in RenderSystem)
  waitForVsync can probably be moved somewhere other than being directly in RenderSystem? (where is it in DX11?)
  waitForVsync can probably be moved somewhere other than being directly in RenderSystem? (where is it in DX11?)