فهرست منبع

Parsing samplers & textures with the same name now works

Marko Pintera 13 سال پیش
والد
کامیت
c62037b142

+ 39 - 34
CamelotClient/CamelotClient.cpp

@@ -27,8 +27,8 @@ using namespace CamelotEngine;
 int _tmain(int argc, _TCHAR* argv[])
 {
 	//gApplication().startUp("CamelotGLRenderSystem", "CamelotForwardRenderer");
-	//gApplication().startUp("CamelotD3D9RenderSystem", "CamelotForwardRenderer");
-	gApplication().startUp("CamelotD3D11RenderSystem", "CamelotForwardRenderer");
+	gApplication().startUp("CamelotD3D9RenderSystem", "CamelotForwardRenderer");
+	//gApplication().startUp("CamelotD3D11RenderSystem", "CamelotForwardRenderer");
 
 	RenderSystem* renderSystem = RenderSystem::instancePtr();
 	RenderWindowPtr renderWindow = gApplication().getPrimaryRenderWindow();
@@ -51,51 +51,51 @@ int _tmain(int argc, _TCHAR* argv[])
 	HighLevelGpuProgramPtr vertProg;
 
 	/////////////////// HLSL 9 SHADERS //////////////////////////
-	//String fragShaderCode = "sampler2D tex;			\
-	//						float4 ps_main(float2 uv : TEXCOORD0) : COLOR0		\
-	//						{														\
-	//						float4 color = tex2D(tex, uv);				\
-	//						return color;										\
-	//						}";
-
-	//fragProg =  HighLevelGpuProgram::create(fragShaderCode, "ps_main", "hlsl", GPT_FRAGMENT_PROGRAM, GPP_PS_2_0);
-
-	//String vertShaderCode = "float4x4 matViewProjection;	\
-	//						void vs_main(										\
-	//						float4 inPos : POSITION,							\
-	//						float2 uv : TEXCOORD0,								\
-	//						out float4 oPosition : POSITION,					\
-	//						out float2 oUv : TEXCOORD0)							\
-	//						{														\
-	//						oPosition = mul(matViewProjection, inPos);			\
-	//						oUv = uv;											\
-	//						}";
-
-	//vertProg =  HighLevelGpuProgram::create(vertShaderCode, "vs_main", "hlsl", GPT_VERTEX_PROGRAM, GPP_VS_2_0);
-
-	/////////////////// 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		\
+	String fragShaderCode = "sampler2D tex;			\
+							float4 ps_main(float2 uv : TEXCOORD0) : COLOR0		\
 							{														\
-							float4 color = tex.Sample(samp, uv);				\
+							float4 color = tex2D(tex, uv);				\
 							return color;										\
 							}";
 
-	fragProg =  HighLevelGpuProgram::create(fragShaderCode, "ps_main", "hlsl", GPT_FRAGMENT_PROGRAM, GPP_PS_4_0);
+	fragProg =  HighLevelGpuProgram::create(fragShaderCode, "ps_main", "hlsl", GPT_FRAGMENT_PROGRAM, GPP_PS_2_0);
 
 	String vertShaderCode = "float4x4 matViewProjection;	\
 							void vs_main(										\
-							in float4 inPos : POSITION,							\
-							in float2 uv : TEXCOORD0,								\
-							out float4 oPosition : SV_Position,					\
+							float4 inPos : POSITION,							\
+							float2 uv : TEXCOORD0,								\
+							out float4 oPosition : 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);
+	vertProg =  HighLevelGpuProgram::create(vertShaderCode, "vs_main", "hlsl", GPT_VERTEX_PROGRAM, GPP_VS_2_0);
+
+	/////////////////// 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);
 
 	/////////////////// CG SHADERS //////////////////////////
 	//String fragShaderCode = "sampler2D tex;					\
@@ -183,6 +183,11 @@ int _tmain(int argc, _TCHAR* argv[])
 	MaterialHandle testMaterial = MaterialPtr(new Material());
 	testMaterial->setShader(testShader);
 
+	testMaterial->setMat4("matViewProjection", Matrix4::IDENTITY);
+
+	//gResources().create(testMaterial, "C:\\testMaterial.mat", true);
+	//testMaterial = static_resource_cast<MaterialHandle>(gResources().load("C:\\testMaterial.mat"));
+
 	/*TextureRef testTex = static_resource_cast<Texture>(Importer::instance().import("C:\\ImportTest.tga"));*/
 	TextureHandle testTex = static_resource_cast<Texture>(Importer::instance().import("C:\\ArenaTowerDFS.psd"));
 	MeshHandle dbgMesh = static_resource_cast<Mesh>(Importer::instance().import("C:\\X_Arena_Tower.FBX"));

+ 6 - 6
CamelotForwardRenderer/Source/CmForwardRenderer.cpp

@@ -131,9 +131,9 @@ namespace CamelotEngine
 		}
 
 		// The rest of the settings are the same no matter whether we use programs or not
-		BlendStatePtr blendState = pass->getBlendState();
+		BlendStateHandle blendState = pass->getBlendState();
 		if(blendState != nullptr)
-			renderContext->setBlendState(blendState);
+			renderContext->setBlendState(blendState.getInternalPtr());
 		else
 			renderContext->setBlendState(BlendState::getDefault());
 		
@@ -145,15 +145,15 @@ namespace CamelotEngine
 
 		// Set up non-texture related material settings
 		// Stencil & depth buffer settings
-		DepthStencilStatePtr depthStancilState = pass->getDepthStencilState();
+		DepthStencilStateHandle depthStancilState = pass->getDepthStencilState();
 		if(depthStancilState != nullptr)
-			renderContext->setDepthStencilState(depthStancilState, pass->getStencilRefValue());
+			renderContext->setDepthStencilState(depthStancilState.getInternalPtr(), pass->getStencilRefValue());
 		else
 			renderContext->setDepthStencilState(DepthStencilState::getDefault(), pass->getStencilRefValue());
 
-		RasterizerStatePtr rasterizerState = pass->getRasterizerState();
+		RasterizerStateHandle rasterizerState = pass->getRasterizerState();
 		if(rasterizerState != nullptr)
-			renderContext->setRasterizerState(rasterizerState);
+			renderContext->setRasterizerState(rasterizerState.getInternalPtr());
 		else
 			renderContext->setRasterizerState(RasterizerState::getDefault());
 	}

+ 2 - 1
CamelotRenderer/Include/CmBlendStateRTTI.h

@@ -9,7 +9,7 @@ namespace CamelotEngine
 {
 	template<> struct SerializableSimpleType<BLEND_STATE_DESC>
 	{	
-		enum { id = 21 }; enum { hasDynamicSize = 1 };
+		enum { id = TID_BLEND_STATE_DESC }; enum { hasDynamicSize = 1 };
 
 		static void toMemory(BLEND_STATE_DESC& data, char* memory)
 		{ 
@@ -17,6 +17,7 @@ namespace CamelotEngine
 
 			memcpy(memory, &size, sizeof(UINT32));
 			memory += sizeof(UINT32);
+			size -= sizeof(UINT32);
 			memcpy(memory, &data, size); 
 		}
 

+ 4 - 4
CamelotRenderer/Include/CmMaterial.h

@@ -73,7 +73,7 @@ namespace CamelotEngine
 		TechniquePtr mBestTechnique;
 
 		set<String>::type mValidShareableParamBlocks;
-		set<String>::type mValidParams;
+		map<String, String>::type mValidParams; // Also maps Shader param name -> gpu variable name
 
 		vector<PassParametersPtr>::type mParametersPerPass;
 
@@ -109,7 +109,7 @@ namespace CamelotEngine
 			}
 		}
 
-		const set<String>::type& getValidParamNames() const { return mValidParams; }
+		const map<String, String>::type& getValidParamNames() const { return mValidParams; }
 
 		TextureHandle getTexture(const String& name) const;
 		SamplerStateHandle getSamplerState(const String& name) const;
@@ -122,12 +122,12 @@ namespace CamelotEngine
 
 		void initBestTechnique();
 
-		set<String>::type determineValidParameters(const vector<const GpuParamDesc*>::type& paramDescs) const;
+		map<String, const GpuParamDataDesc*>::type determineValidDataParameters(const vector<const GpuParamDesc*>::type& paramDescs) const;
+		set<String>::type determineValidObjectParameters(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		                     		*/

+ 9 - 9
CamelotRenderer/Include/CmPass.h

@@ -17,9 +17,9 @@ namespace CamelotEngine
 	class CM_EXPORT Pass : public IReflectable
     {
     protected:
-		BlendStatePtr mBlendState;
-		RasterizerStatePtr mRasterizerState;
-		DepthStencilStatePtr mDepthStencilState;
+		BlendStateHandle mBlendState;
+		RasterizerStateHandle mRasterizerState;
+		DepthStencilStateHandle mDepthStencilState;
 		UINT32 mStencilRefValue;
 
 		GpuProgramHandle mVertexProgram;
@@ -50,14 +50,14 @@ namespace CamelotEngine
 		/**
 		 * @brief	Sets a blend state used for all active render targets.
 		 */
-		void setBlendState(BlendStatePtr blendState);
-		BlendStatePtr getBlendState() const;
+		void setBlendState(BlendStateHandle& blendState);
+		BlendStateHandle getBlendState() const;
 
-		void setRasterizerState(RasterizerStatePtr rasterizerState);
-		RasterizerStatePtr getRasterizerState() const;
+		void setRasterizerState(RasterizerStateHandle& rasterizerState);
+		RasterizerStateHandle getRasterizerState() const;
 
-		void setDepthStencilState(DepthStencilStatePtr depthStencilState);
-		DepthStencilStatePtr getDepthStencilState() const;
+		void setDepthStencilState(DepthStencilStateHandle& depthStencilState);
+		DepthStencilStateHandle getDepthStencilState() const;
 
 		void setStencilRefValue(UINT32 refValue);
 		UINT32 getStencilRefValue() const;

+ 21 - 9
CamelotRenderer/Include/CmPassRTTI.h

@@ -9,14 +9,14 @@ namespace CamelotEngine
 	class CM_EXPORT PassRTTI : public RTTIType<Pass, IReflectable, PassRTTI>
 	{
 	private:
-		BlendStatePtr getBlendState(Pass* obj) { return obj->mBlendState; }
-		void setBlendState(Pass* obj, BlendStatePtr val) { obj->mBlendState = val; } 
+		BlendStateHandle& getBlendState(Pass* obj) { return obj->mBlendState; }
+		void setBlendState(Pass* obj, BlendStateHandle& val) { obj->mBlendState = val; } 
 
-		RasterizerStatePtr getRasterizerState(Pass* obj) { return obj->mRasterizerState; }
-		void setRasterizerState(Pass* obj, RasterizerStatePtr val) { obj->mRasterizerState = val; } 
+		RasterizerStateHandle& getRasterizerState(Pass* obj) { return obj->mRasterizerState; }
+		void setRasterizerState(Pass* obj, RasterizerStateHandle& val) { obj->mRasterizerState = val; } 
 
-		DepthStencilStatePtr getDepthStencilState(Pass* obj) { return obj->mDepthStencilState; }
-		void setDepthStencilState(Pass* obj, DepthStencilStatePtr val) { obj->mDepthStencilState = val; } 
+		DepthStencilStateHandle& getDepthStencilState(Pass* obj) { return obj->mDepthStencilState; }
+		void setDepthStencilState(Pass* obj, DepthStencilStateHandle& val) { obj->mDepthStencilState = val; } 
 
 		GpuProgramHandle& getVertexProgram(Pass* obj) { return obj->mVertexProgram; }
 		void setVertexProgram(Pass* obj, GpuProgramHandle& val) { obj->mVertexProgram = val; } 
@@ -26,16 +26,28 @@ namespace CamelotEngine
 
 		GpuProgramHandle& getGeometryProgram(Pass* obj) { return obj->mGeometryProgram; }
 		void setGeometryProgram(Pass* obj, GpuProgramHandle& val) { obj->mGeometryProgram = val; } 
+
+		GpuProgramHandle& getHullProgram(Pass* obj) { return obj->mHullProgram; }
+		void setHullProgram(Pass* obj, GpuProgramHandle& val) { obj->mHullProgram = val; } 
+
+		GpuProgramHandle& getDomainProgram(Pass* obj) { return obj->mDomainProgram; }
+		void setDomainProgram(Pass* obj, GpuProgramHandle& val) { obj->mDomainProgram = val; } 
+
+		GpuProgramHandle& getComputeProgram(Pass* obj) { return obj->mComputeProgram; }
+		void setComputeProgram(Pass* obj, GpuProgramHandle& val) { obj->mComputeProgram = val; } 
 	public:
 		PassRTTI()
 		{
-			addReflectablePtrField("mBlendState", 0, &PassRTTI::getBlendState, &PassRTTI::setBlendState);
-			addReflectablePtrField("mRasterizerState", 1, &PassRTTI::getRasterizerState, &PassRTTI::setRasterizerState);
-			addReflectablePtrField("mDepthStencilState", 2, &PassRTTI::getDepthStencilState, &PassRTTI::setDepthStencilState);
+			addReflectableField("mBlendState", 0, &PassRTTI::getBlendState, &PassRTTI::setBlendState);
+			addReflectableField("mRasterizerState", 1, &PassRTTI::getRasterizerState, &PassRTTI::setRasterizerState);
+			addReflectableField("mDepthStencilState", 2, &PassRTTI::getDepthStencilState, &PassRTTI::setDepthStencilState);
 
 			addReflectableField("mVertexProgram", 3, &PassRTTI::getVertexProgram, &PassRTTI::setVertexProgram);
 			addReflectableField("mFragmentProgram", 4, &PassRTTI::getFragmentProgram, &PassRTTI::setFragmentProgram);
 			addReflectableField("mGeometryProgram", 5, &PassRTTI::getGeometryProgram, &PassRTTI::setGeometryProgram);
+			addReflectableField("mHullProgram", 6, &PassRTTI::getHullProgram, &PassRTTI::setHullProgram);
+			addReflectableField("mDomainProgram", 7, &PassRTTI::getDomainProgram, &PassRTTI::setDomainProgram);
+			addReflectableField("mComputeProgram", 8, &PassRTTI::getComputeProgram, &PassRTTI::setComputeProgram);
 		}
 
 		virtual const String& getRTTIName()

+ 5 - 1
CamelotRenderer/Include/CmPrerequisites.h

@@ -240,7 +240,11 @@ namespace CamelotEngine
 		TID_MaterialParamMat3 = 1030,
 		TID_MaterialParamMat4 = 1031,
 		TID_MaterialParamTexture = 1032,
-		TID_MaterialParamSamplerState = 1033
+		TID_MaterialParamSamplerState = 1033,
+		TID_BLEND_STATE_DESC = 1034,
+		TID_SHADER_DATA_PARAM_DESC = 1035,
+		TID_SHADER_OBJECT_PARAM_DESC = 1036,
+		TID_SHADER_PARAM_BLOCK_DESC = 1047
 	};
 }
 

+ 138 - 0
CamelotRenderer/Include/CmShaderRTTI.h

@@ -6,6 +6,144 @@
 
 namespace CamelotEngine
 {
+	template<> struct SerializableSimpleType<SHADER_DATA_PARAM_DESC>
+	{	
+		enum { id = TID_SHADER_DATA_PARAM_DESC }; enum { hasDynamicSize = 1 };
+
+		static void toMemory(SHADER_DATA_PARAM_DESC& data, char* memory)
+		{ 
+			UINT32 size = getDynamicSize(data);
+
+			UINT32 curSize = sizeof(UINT32);
+			memcpy(memory, &size, curSize);
+			memory += curSize;
+
+			memory = rttiWriteElem(data.arraySize, memory);
+			memory = rttiWriteElem(data.hidden, memory);
+			memory = rttiWriteElem(data.type, memory);
+			memory = rttiWriteElem(data.name, memory);
+			memory = rttiWriteElem(data.gpuVariableName, memory);
+		}
+
+		static void fromMemory(SHADER_DATA_PARAM_DESC& data, char* memory)
+		{ 
+			UINT32 size;
+			memcpy(&size, memory, sizeof(UINT32)); 
+			memory += sizeof(UINT32);
+
+			memory = rttiReadElem(data.arraySize, memory);
+			memory = rttiReadElem(data.hidden, memory);
+			memory = rttiReadElem(data.type, memory);
+			memory = rttiReadElem(data.name, memory);
+			memory = rttiReadElem(data.gpuVariableName, memory);
+		}
+
+		static UINT32 getDynamicSize(SHADER_DATA_PARAM_DESC& data)	
+		{ 
+			UINT64 dataSize = rttiGetElemSize(data.arraySize) + rttiGetElemSize(data.hidden) + rttiGetElemSize(data.type) + 
+				rttiGetElemSize(data.name) + rttiGetElemSize(data.gpuVariableName) + sizeof(UINT32);
+
+#if CM_DEBUG_MODE
+			if(dataSize > std::numeric_limits<UINT32>::max())
+			{
+				CM_EXCEPT(InternalErrorException, "Data overflow! Size doesn't fit into 32 bits.");
+			}
+#endif
+
+			return (UINT32)dataSize;
+		}	
+	}; 
+
+	template<> struct SerializableSimpleType<SHADER_OBJECT_PARAM_DESC>
+	{	
+		enum { id = TID_SHADER_OBJECT_PARAM_DESC }; enum { hasDynamicSize = 1 };
+
+		static void toMemory(SHADER_OBJECT_PARAM_DESC& data, char* memory)
+		{ 
+			UINT32 size = getDynamicSize(data);
+
+			UINT32 curSize = sizeof(UINT32);
+			memcpy(memory, &size, curSize);
+			memory += curSize;
+
+			memory = rttiWriteElem(data.hidden, memory);
+			memory = rttiWriteElem(data.type, memory);
+			memory = rttiWriteElem(data.name, memory);
+			memory = rttiWriteElem(data.gpuVariableName, memory);
+		}
+
+		static void fromMemory(SHADER_OBJECT_PARAM_DESC& data, char* memory)
+		{ 
+			UINT32 size;
+			memcpy(&size, memory, sizeof(UINT32)); 
+			memory += sizeof(UINT32);
+
+			memory = rttiReadElem(data.hidden, memory);
+			memory = rttiReadElem(data.type, memory);
+			memory = rttiReadElem(data.name, memory);
+			memory = rttiReadElem(data.gpuVariableName, memory);
+		}
+
+		static UINT32 getDynamicSize(SHADER_OBJECT_PARAM_DESC& data)	
+		{ 
+			UINT64 dataSize = rttiGetElemSize(data.hidden) + rttiGetElemSize(data.type) + 
+				rttiGetElemSize(data.name) + rttiGetElemSize(data.gpuVariableName) + sizeof(UINT32);
+
+#if CM_DEBUG_MODE
+			if(dataSize > std::numeric_limits<UINT32>::max())
+			{
+				CM_EXCEPT(InternalErrorException, "Data overflow! Size doesn't fit into 32 bits.");
+			}
+#endif
+
+			return (UINT32)dataSize;
+		}	
+	}; 
+
+	template<> struct SerializableSimpleType<SHADER_PARAM_BLOCK_DESC>
+	{	
+		enum { id = TID_SHADER_PARAM_BLOCK_DESC }; enum { hasDynamicSize = 1 };
+
+		static void toMemory(SHADER_PARAM_BLOCK_DESC& data, char* memory)
+		{ 
+			UINT32 size = getDynamicSize(data);
+
+			UINT32 curSize = sizeof(UINT32);
+			memcpy(memory, &size, curSize);
+			memory += curSize;
+
+			memory = rttiWriteElem(data.shared, memory);
+			memory = rttiWriteElem(data.usage, memory);
+			memory = rttiWriteElem(data.name, memory);
+		}
+
+		static void fromMemory(SHADER_PARAM_BLOCK_DESC& data, char* memory)
+		{ 
+			UINT32 size;
+			memcpy(&size, memory, sizeof(UINT32)); 
+			memory += sizeof(UINT32);
+
+			memory = rttiReadElem(data.shared, memory);
+			memory = rttiReadElem(data.usage, memory);
+			memory = rttiReadElem(data.name, memory);
+		}
+
+		static UINT32 getDynamicSize(SHADER_PARAM_BLOCK_DESC& data)	
+		{ 
+			UINT64 dataSize = rttiGetElemSize(data.shared) + rttiGetElemSize(data.usage) + 
+				rttiGetElemSize(data.name) + sizeof(UINT32);
+
+#if CM_DEBUG_MODE
+			if(dataSize > std::numeric_limits<UINT32>::max())
+			{
+				CM_EXCEPT(InternalErrorException, "Data overflow! Size doesn't fit into 32 bits.");
+			}
+#endif
+
+			return (UINT32)dataSize;
+		}	
+	}; 
+
 	class CM_EXPORT ShaderRTTI : public RTTIType<Shader, Resource, ShaderRTTI>
 	{
 	private:

+ 87 - 154
CamelotRenderer/Source/CmMaterial.cpp

@@ -105,7 +105,9 @@ namespace CamelotEngine
 			}
 
 			// Fill out various helper structures
-			set<String>::type validParameters = determineValidParameters(allParamDescs);
+			map<String, const GpuParamDataDesc*>::type validDataParameters = determineValidDataParameters(allParamDescs);
+			set<String>::type validObjectParameters = determineValidObjectParameters(allParamDescs);
+
 			set<String>::type validShareableParamBlocks = determineValidShareableParamBlocks(allParamDescs);
 			map<String, String>::type paramToParamBlockMap = determineParameterToBlockMapping(allParamDescs);
 			map<String, GpuParamBlockPtr>::type paramBlocks;
@@ -148,19 +150,33 @@ namespace CamelotEngine
 			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);
+				auto findIter = validDataParameters.find(iter->second.gpuVariableName);
 
 				// Not valid so we skip it
-				if(findIter == validParameters.end())
+				if(findIter == validDataParameters.end())
+					continue;
+
+				if(findIter->second->type != iter->second.type)
+				{
+					LOGWRN("Ignoring shader parameter " + iter->first  +". Type doesn't match the one defined in the gpu program. "
+						+ "Shader defined type: " + toString(iter->second.type) + " - Gpu program defined type: " + toString(findIter->second->type));
+					continue;
+				}
+
+				if(findIter->second->arraySize != iter->second.arraySize)
+				{
+					LOGWRN("Ignoring shader parameter " + iter->first  +". Array size doesn't match the one defined in the gpu program."
+						+ "Shader defined array size: " + toString(iter->second.arraySize) + " - Gpu program defined array size: " + toString(findIter->second->arraySize));
 					continue;
+				}
 
-				auto findBlockIter = paramToParamBlockMap.find(iter->first);
+				auto findBlockIter = paramToParamBlockMap.find(iter->second.gpuVariableName);
 
 				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);
+				mValidParams[iter->first] = iter->second.gpuVariableName;
 
 				switch(iter->second.type)
 				{
@@ -191,13 +207,13 @@ namespace CamelotEngine
 			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);
+				auto findIter = validObjectParameters.find(iter->second.gpuVariableName);
 
 				// Not valid so we skip it
-				if(findIter == validParameters.end())
+				if(findIter == validObjectParameters.end())
 					continue;
 
-				mValidParams.insert(iter->first);
+				mValidParams[iter->first] = iter->second.gpuVariableName;
 
 				if(Shader::isSampler(iter->second.type))
 				{
@@ -287,12 +303,10 @@ namespace CamelotEngine
 		}
 	}
 
-	set<String>::type Material::determineValidParameters(const vector<const GpuParamDesc*>::type& paramDescs) const
+	map<String, const GpuParamDataDesc*>::type Material::determineValidDataParameters(const vector<const GpuParamDesc*>::type& paramDescs) const
 	{
 		map<String, const GpuParamDataDesc*>::type foundDataParams;
-		map<String, const GpuParamObjectDesc*>::type foundObjectParams;
-
-		map<String, bool>::type validParameters;
+		map<String, bool>::type validParams;
 
 		for(auto iter = paramDescs.begin(); iter != paramDescs.end(); ++iter)
 		{
@@ -304,149 +318,64 @@ namespace CamelotEngine
 				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 = validParams.find(iter2->first);
+				if(dataFindIter == validParams.end())
 				{
-					auto dataFindIter = foundDataParams.find(iter2->first);
-					if(dataFindIter == foundDataParams.end())
-					{
-						validParameters[iter2->first] = true;
-						foundDataParams[iter2->first] = &curParam;
-					}
-					else
+					validParams[iter2->first] = true;
+					foundDataParams[iter2->first] = &curParam;
+				}
+				else
+				{
+					if(validParams[iter2->first])
 					{
-						const GpuParamDataDesc* otherParam = dataFindIter->second;
+						auto dataFindIter2 = foundDataParams.find(iter2->first);
+
+						const GpuParamDataDesc* otherParam = dataFindIter2->second;
 						if(!areParamsEqual(curParam, *otherParam, true))
-							isParameterValid = false;
+						{
+							validParams[iter2->first] = false;
+							foundDataParams.erase(dataFindIter2);
+						}
 					}
 				}
+			}
+		}
 
-				if(!isParameterValid)
-				{
-					if(validParameters[iter2->first]) // Do this check so we only report this error once
-						LOGWRN("Found two parameters with the same name but different contents: " + iter2->first);
+		return foundDataParams;
+	}
 
-					validParameters[iter2->first] = false;
-				}
-			}
+	
+	set<String>::type Material::determineValidObjectParameters(const vector<const GpuParamDesc*>::type& paramDescs) const
+	{
+		set<String>::type validParams;
+
+		for(auto iter = paramDescs.begin(); iter != paramDescs.end(); ++iter)
+		{
+			const GpuParamDesc& curDesc = **iter;
 
 			// 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[iter2->first] = true;
-						foundObjectParams[iter2->first] = &curParam;
-					}
-					else
-					{
-						const GpuParamObjectDesc* otherParam = objectFindIter->second;
-						if(!areParamsEqual(curParam, *otherParam))
-							isParameterValid = false;
-					}
-				}
-
-				if(!isParameterValid)
-				{
-					if(validParameters[iter2->first]) // Do this check so we only report this error once
-						LOGWRN("Found two parameters with the same name but different contents: " + iter2->first);
-
-					validParameters[iter2->first] = false;
-				}
+				if(validParams.find(iter2->first) == validParams.end())
+					validParams.insert(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[iter2->first] = true;
-						foundObjectParams[iter2->first] = &curParam;
-					}
-					else
-					{
-						const GpuParamObjectDesc* otherParam = objectFindIter->second;
-						if(!areParamsEqual(curParam, *otherParam))
-							isParameterValid = false;
-					}
-				}
-
-				if(!isParameterValid)
-				{
-					if(validParameters[iter2->first]) // Do this check so we only report this error once
-						LOGWRN("Found two parameters with the same name but different contents: " + iter2->first);
-
-					validParameters[iter2->first] = false;
-				}
+				if(validParams.find(iter2->first) == validParams.end())
+					validParams.insert(iter2->first);
 			}
 
 			// Check buffer params
 			for(auto iter2 = curDesc.buffers.begin(); iter2 != curDesc.buffers.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[iter2->first] = true;
-						foundObjectParams[iter2->first] = &curParam;
-					}
-					else
-					{
-						const GpuParamObjectDesc* otherParam = objectFindIter->second;
-						if(!areParamsEqual(curParam, *otherParam))
-							isParameterValid = false;
-					}
-				}
-
-				if(!isParameterValid)
-				{
-					if(validParameters[iter2->first]) // Do this check so we only report this error once
-						LOGWRN("Found two parameters with the same name but different contents: " + iter2->first);
-
-					validParameters[iter2->first] = false;
-				}
+				if(validParams.find(iter2->first) == validParams.end())
+					validParams.insert(iter2->first);
 			}
 		}
 
-		set<String>::type validParamsReturn;
-		for(auto iter = validParameters.begin(); iter != validParameters.end(); ++iter)
-		{
-			if(iter->second)
-				validParamsReturn.insert(iter->first);
-		}
-
-		return validParamsReturn;
+		return validParams;
 	}
 
 	set<String>::type Material::determineValidShareableParamBlocks(const vector<const GpuParamDesc*>::type& paramDescs) const
@@ -562,11 +491,6 @@ namespace CamelotEngine
 		return equal;
 	}
 
-	bool Material::areParamsEqual(const GpuParamObjectDesc& paramA, const GpuParamObjectDesc& paramB) const
-	{
-		return paramA.type == paramB.type;
-	}
-
 	void Material::throwIfNotInitialized() const
 	{
 		if(mShader == nullptr)
@@ -591,6 +515,7 @@ namespace CamelotEngine
 			return;
 		}
 
+		String& gpuVarName = iterFind->second;
 		for(auto iter = mParametersPerPass.begin(); iter != mParametersPerPass.end(); ++iter)
 		{
 			PassParametersPtr params = *iter;
@@ -600,8 +525,8 @@ namespace CamelotEngine
 				GpuParamsPtr& paramPtr = params->getParamByIdx(i);
 				if(paramPtr)
 				{
-					if(paramPtr->hasTexture(name))
-						paramPtr->setTexture(name, value);
+					if(paramPtr->hasTexture(gpuVarName))
+						paramPtr->setTexture(gpuVarName, value);
 				}
 			}
 		}
@@ -620,6 +545,7 @@ namespace CamelotEngine
 			return;
 		}
 
+		String& gpuVarName = iterFind->second;
 		for(auto iter = mParametersPerPass.begin(); iter != mParametersPerPass.end(); ++iter)
 		{
 			PassParametersPtr params = *iter;
@@ -629,8 +555,8 @@ namespace CamelotEngine
 				GpuParamsPtr& paramPtr = params->getParamByIdx(i);
 				if(paramPtr)
 				{
-					if(paramPtr->hasSamplerState(name))
-						paramPtr->setSamplerState(name, samplerState);
+					if(paramPtr->hasSamplerState(gpuVarName))
+						paramPtr->setSamplerState(gpuVarName, samplerState);
 				}
 			}
 		}
@@ -649,9 +575,10 @@ namespace CamelotEngine
 			return;
 		}
 
-		setParam(name, value, arrayIdx);
+		String& gpuVarName = iterFind->second;
+		setParam(gpuVarName, value, arrayIdx);
 
-		auto savedValue = mFloatValues[name];
+		auto& savedValue = mFloatValues[name];
 		savedValue[arrayIdx] = value;
 	}
 
@@ -666,9 +593,10 @@ namespace CamelotEngine
 			return;
 		}
 
-		setParam(name, value, arrayIdx);
+		String& gpuVarName = iterFind->second;
+		setParam(gpuVarName, value, arrayIdx);
 
-		auto savedValue = mVec4Values[name];
+		auto& savedValue = mVec4Values[name];
 		savedValue[arrayIdx] = Vector4(value.r, value.g, value.b, value.a);
 	}
 
@@ -683,9 +611,10 @@ namespace CamelotEngine
 			return;
 		}
 
-		setParam(name, value, arrayIdx);
+		String& gpuVarName = iterFind->second;
+		setParam(gpuVarName, value, arrayIdx);
 
-		auto savedValue = mVec2Values[name];
+		auto& savedValue = mVec2Values[name];
 		savedValue[arrayIdx] = value;
 	}
 
@@ -700,9 +629,10 @@ namespace CamelotEngine
 			return;
 		}
 
-		setParam(name, value, arrayIdx);
+		String& gpuVarName = iterFind->second;
+		setParam(gpuVarName, value, arrayIdx);
 
-		auto savedValue = mVec3Values[name];
+		auto& savedValue = mVec3Values[name];
 		savedValue[arrayIdx] = value;
 	}
 
@@ -717,9 +647,10 @@ namespace CamelotEngine
 			return;
 		}
 
-		setParam(name, value, arrayIdx);
+		String& gpuVarName = iterFind->second;
+		setParam(gpuVarName, value, arrayIdx);
 
-		auto savedValue = mVec4Values[name];
+		auto& savedValue = mVec4Values[name];
 		savedValue[arrayIdx] = value;
 	}
 
@@ -734,9 +665,10 @@ namespace CamelotEngine
 			return;
 		}
 
-		setParam(name, value, arrayIdx);
+		String& gpuVarName = iterFind->second;
+		setParam(gpuVarName, value, arrayIdx);
 
-		auto savedValue = mMat3Values[name];
+		auto& savedValue = mMat3Values[name];
 		savedValue[arrayIdx] = value;
 	}
 
@@ -751,9 +683,10 @@ namespace CamelotEngine
 			return;
 		}
 
-		setParam(name, value, arrayIdx);
+		String& gpuVarName = iterFind->second;
+		setParam(gpuVarName, value, arrayIdx);
 
-		auto savedValue = mMat4Values[name];
+		auto& savedValue = mMat4Values[name];
 		savedValue[arrayIdx] = value;
 	}
 

+ 20 - 20
CamelotRenderer/Source/CmMaterialRTTI.cpp

@@ -38,15 +38,15 @@ namespace CamelotEngine
 		ShaderPtr shader = material->getShader();
 		if(shader != nullptr)
 		{
-			const set<String>::type& validParamNames = material->getValidParamNames();
+			const map<String, String>::type& validParamNames = material->getValidParamNames();
 
 			for(auto iter = validParamNames.begin(); iter != validParamNames.end(); ++iter)
 			{
-				GpuParamType type = shader->getParamType(*iter);
+				GpuParamType type = shader->getParamType(iter->first);
 
 				if(type == GPT_DATA)
 				{
-					const SHADER_DATA_PARAM_DESC& paramDesc = shader->getDataParamDesc(*iter);
+					const SHADER_DATA_PARAM_DESC& paramDesc = shader->getDataParamDesc(iter->first);
 
 					switch(paramDesc.type)
 					{
@@ -55,8 +55,8 @@ namespace CamelotEngine
 							for(UINT32 i = 0; i < paramDesc.arraySize; i++)
 							{
 								MaterialFloatParam param;
-								param.name = *iter;
-								param.value = material->getFloat(*iter, i);
+								param.name = iter->first;
+								param.value = material->getFloat(iter->first, i);
 								param.arrayIdx = i;
 
 								params->floatParams.push_back(param);
@@ -68,8 +68,8 @@ namespace CamelotEngine
 							for(UINT32 i = 0; i < paramDesc.arraySize; i++)
 							{
 								MaterialVec2Param param;
-								param.name = *iter;
-								param.value = material->getVec2(*iter, i);
+								param.name = iter->first;
+								param.value = material->getVec2(iter->first, i);
 								param.arrayIdx = i;
 
 								params->vec2Params.push_back(param);
@@ -81,8 +81,8 @@ namespace CamelotEngine
 							for(UINT32 i = 0; i < paramDesc.arraySize; i++)
 							{
 								MaterialVec3Param param;
-								param.name = *iter;
-								param.value = material->getVec3(*iter, i);
+								param.name = iter->first;
+								param.value = material->getVec3(iter->first, i);
 								param.arrayIdx = i;
 
 								params->vec3Params.push_back(param);
@@ -94,8 +94,8 @@ namespace CamelotEngine
 							for(UINT32 i = 0; i < paramDesc.arraySize; i++)
 							{
 								MaterialVec4Param param;
-								param.name = *iter;
-								param.value = material->getVec4(*iter, i);
+								param.name = iter->first;
+								param.value = material->getVec4(iter->first, i);
 								param.arrayIdx = i;
 
 								params->vec4Params.push_back(param);
@@ -107,8 +107,8 @@ namespace CamelotEngine
 							for(UINT32 i = 0; i < paramDesc.arraySize; i++)
 							{
 								MaterialMat3Param param;
-								param.name = *iter;
-								param.value = material->getMat3(*iter, i);
+								param.name = iter->first;
+								param.value = material->getMat3(iter->first, i);
 								param.arrayIdx = i;
 
 								params->mat3Params.push_back(param);
@@ -120,8 +120,8 @@ namespace CamelotEngine
 							for(UINT32 i = 0; i < paramDesc.arraySize; i++)
 							{
 								MaterialMat4Param param;
-								param.name = *iter;
-								param.value = material->getMat4(*iter, i);
+								param.name = iter->first;
+								param.value = material->getMat4(iter->first, i);
 								param.arrayIdx = i;
 
 								params->mat4Params.push_back(param);
@@ -134,19 +134,19 @@ namespace CamelotEngine
 				}
 				else if(type == GPT_OBJECT)
 				{
-					const SHADER_OBJECT_PARAM_DESC& paramDesc = shader->getObjectParamDesc(*iter);
+					const SHADER_OBJECT_PARAM_DESC& paramDesc = shader->getObjectParamDesc(iter->first);
 
 					if(Shader::isSampler(paramDesc.type))
 					{
 						MaterialSamplerStateParam param;
-						param.name = *iter;
-						param.value = material->getSamplerState(*iter);
+						param.name = iter->first;
+						param.value = material->getSamplerState(iter->first);
 					}
 					else if(Shader::isTexture(paramDesc.type))
 					{
 						MaterialTextureParam param;
-						param.name = *iter;
-						param.value = material->getTexture(*iter);
+						param.name = iter->first;
+						param.value = material->getTexture(iter->first);
 					}
 					else if(Shader::isBuffer(paramDesc.type))
 					{

+ 9 - 6
CamelotRenderer/Source/CmPass.cpp

@@ -33,6 +33,9 @@ namespace CamelotEngine
 		mVertexProgram = oth.mVertexProgram;
 		mFragmentProgram = oth.mFragmentProgram;
 		mGeometryProgram = oth.mGeometryProgram;
+		mHullProgram = oth.mHullProgram;
+		mDomainProgram = oth.mDomainProgram;
+		mComputeProgram = oth.mComputeProgram;
 
 		return *this;
     }
@@ -60,32 +63,32 @@ namespace CamelotEngine
 		return transparent;
     }
 	//----------------------------------------------------------------------
-	void Pass::setBlendState(BlendStatePtr blendState)
+	void Pass::setBlendState(BlendStateHandle& blendState)
 	{
 		mBlendState = blendState;
 	}
 	//----------------------------------------------------------------------
-	BlendStatePtr Pass::getBlendState() const
+	BlendStateHandle Pass::getBlendState() const
 	{
 		return mBlendState;
 	}
 	//----------------------------------------------------------------------
-	void Pass::setRasterizerState(RasterizerStatePtr rasterizerState)
+	void Pass::setRasterizerState(RasterizerStateHandle& rasterizerState)
 	{
 		mRasterizerState = rasterizerState;
 	}
 	//----------------------------------------------------------------------
-	RasterizerStatePtr Pass::getRasterizerState() const
+	RasterizerStateHandle Pass::getRasterizerState() const
 	{
 		return mRasterizerState;
 	}
 	//-----------------------------------------------------------------------
-	void Pass::setDepthStencilState(DepthStencilStatePtr depthStencilState)
+	void Pass::setDepthStencilState(DepthStencilStateHandle& depthStencilState)
 	{
 		mDepthStencilState = depthStencilState;
 	}
 	//-----------------------------------------------------------------------
-	DepthStencilStatePtr Pass::getDepthStencilState() const
+	DepthStencilStateHandle Pass::getDepthStencilState() const
 	{
 		return mDepthStencilState;
 	}

+ 5 - 2
CamelotRenderer/TODO.txt

@@ -50,6 +50,10 @@ Stuff that needs destroy():
   - Shader
   - Technique
 
+Calling destroy() and then immediately releasing last reference to an object will delete the object before it is destroyed. (Since destroy()) gets queued.
+
+Upon calling destroy() I should keep a temporary reference to the object until it actually is destroyed.
+
   Material RTTI should also serialize shared buffers (they need to be made into a resource)
 
 DX9 will have the same name for sampler and texture. This will cause an error in Material param checking.
@@ -58,8 +62,7 @@ Add support for include file resource
 Make sure we can add an include file to a HighLevelGpuProgram, and make sure it uses it
  - Also a way to list all referenced includes, and a way to remove them
 
-Make Raster/DepthStencil/Blend/Sampler states resources
-Make Shader a resource
+Loading material should also load attached shader and textures/sampler states
 
  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?)

+ 48 - 0
CamelotUtility/Include/CmRTTIField.h

@@ -16,6 +16,53 @@ namespace CamelotEngine
 	class RTTITypeBase;
 	struct RTTIField;
 
+	/**
+	* @brief	Helper method when serializing known data types that have valid
+	* 			SerializableSimpleType specializations.
+	* 			
+	*			Returns the size of the element. If elements serializable type is 
+	*			specialized with hasDynamicSize == true, the dynamic size is calculated, 
+	*			otherwise sizeof() is used.
+	 */
+	template<class ElemType>
+	UINT32 rttiGetElemSize(ElemType& data)
+	{
+		if(SerializableSimpleType<ElemType>::hasDynamicSize == 1)
+			return SerializableSimpleType<ElemType>::getDynamicSize(data);
+		else
+			return sizeof(ElemType);
+	}
+
+	/**
+	 * @brief	Helper method when serializing known data types that have valid
+	 * 			SerializableSimpleType specializations.
+	 * 			
+	 *			Writes the specified data into memory, advances the memory pointer by the
+	 *			bytes written and returns pointer to new memory.
+	 */
+	template<class ElemType>
+	char* rttiWriteElem(ElemType& data, char* memory)
+	{
+		SerializableSimpleType<ElemType>::toMemory(data, memory);
+
+		return memory + rttiGetElemSize(data);
+	}
+
+	/**
+	 * @brief	Helper method when serializing known data types that have valid
+	 * 			SerializableSimpleType specializations.
+	 * 			
+	 *			Reads the specified data into memory, advances the memory pointer by the
+	 *			bytes read and returns pointer to new memory.
+	 */
+	template<class ElemType>
+	char* rttiReadElem(ElemType& data, char* memory)
+	{
+		SerializableSimpleType<ElemType>::fromMemory(data, memory);
+
+		return memory + rttiGetElemSize(data);
+	}
+
 	template<class T>
 	struct SerializableSimpleType 
 	{ 
@@ -78,6 +125,7 @@ namespace CamelotEngine
 
 			memcpy(memory, &size, sizeof(UINT32));
 			memory += sizeof(UINT32);
+			size -= sizeof(UINT32);
 			memcpy(memory, data.data(), size); 
 		}