Browse Source

Added MaterialParams as a Material equivalent of GpuParam used by GpuPrograms

Marko Pintera 11 years ago
parent
commit
630f8908a3

+ 2 - 0
BansheeCore/BansheeCore.vcxproj

@@ -274,6 +274,7 @@
   <ItemGroup>
     <ClInclude Include="Include\BsCameraProxy.h" />
     <ClInclude Include="Include\BsDrawList.h" />
+    <ClInclude Include="Include\BsMaterialParam.h" />
     <ClInclude Include="Include\BsMaterialProxy.h" />
     <ClInclude Include="Include\BsMeshProxy.h" />
     <ClInclude Include="Include\BsRenderStats.h" />
@@ -425,6 +426,7 @@
     <ClCompile Include="Source\BsCameraProxy.cpp" />
     <ClCompile Include="Source\BsCoreThread.cpp" />
     <ClCompile Include="Source\BsDrawList.cpp" />
+    <ClCompile Include="Source\BsMaterialParam.cpp" />
     <ClCompile Include="Source\BsMaterialProxy.cpp" />
     <ClCompile Include="Source\BsProfilerCPU.cpp" />
     <ClCompile Include="Source\BsDeferredCallManager.cpp" />

+ 6 - 0
BansheeCore/BansheeCore.vcxproj.filters

@@ -534,6 +534,9 @@
     <ClInclude Include="Include\BsViewportRTTI.h">
       <Filter>Header Files\RTTI</Filter>
     </ClInclude>
+    <ClInclude Include="Include\BsMaterialParam.h">
+      <Filter>Header Files\Material</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="Source\BsCoreApplication.cpp">
@@ -839,5 +842,8 @@
     <ClCompile Include="Source\BsMaterialProxy.cpp">
       <Filter>Source Files</Filter>
     </ClCompile>
+    <ClCompile Include="Source\BsMaterialParam.cpp">
+      <Filter>Source Files\Material</Filter>
+    </ClCompile>
   </ItemGroup>
 </Project>

+ 18 - 12
BansheeCore/Include/BsGpuParam.h

@@ -123,6 +123,9 @@ namespace BansheeEngine
 		 */
 		void set(const T& value, UINT32 arrayIdx = 0)
 		{
+			if (mInternalData == nullptr)
+				return;
+
 			if (isDestroyed())
 				BS_EXCEPT(InternalErrorException, "Trying to access a destroyed gpu parameter.");
 
@@ -167,6 +170,9 @@ namespace BansheeEngine
 		 */
 		T get(UINT32 arrayIdx = 0)
 		{
+			if (mInternalData == nullptr)
+				return T();
+
 			if (isDestroyed())
 				BS_EXCEPT(InternalErrorException, "Trying to access a destroyed gpu parameter.");
 
@@ -217,7 +223,7 @@ namespace BansheeEngine
 	template class TGpuDataParam<Matrix4>;
 
 	/**
-	 * @copydoc GpuDataParamBase
+	 * @copydoc TGpuDataParam
 	 */
 	class BS_CORE_EXPORT GpuParamStruct
 	{
@@ -228,12 +234,12 @@ namespace BansheeEngine
 		GpuParamStruct();
 
 		/**
-		 * @copydoc	GpuDataParamBase::set
+		 * @copydoc	TGpuDataParam::set
 		 */
 		void set(const void* value, UINT32 sizeBytes, UINT32 arrayIdx = 0);
 
 		/**
-		 * @copydoc	GpuDataParamBase::get
+		 * @copydoc	TGpuDataParam::get
 		 */
 		void get(void* value, UINT32 sizeBytes, UINT32 arrayIdx = 0);
 
@@ -251,7 +257,7 @@ namespace BansheeEngine
 	};
 
 	/**
-	 * @copydoc GpuDataParamBase
+	 * @copydoc TGpuDataParam
 	 */
 	class BS_CORE_EXPORT GpuParamTexture
 	{
@@ -262,12 +268,12 @@ namespace BansheeEngine
 		GpuParamTexture();
 
 		/**
-		 * @copydoc	GpuDataParamBase::set
+		 * @copydoc	TGpuDataParam::set
 		 */
 		void set(const HTexture& texture);
 
 		/**
-		 * @copydoc	GpuDataParamBase::get
+		 * @copydoc	TGpuDataParam::get
 		 */
 		HTexture get();
 		
@@ -280,7 +286,7 @@ namespace BansheeEngine
 	};
 
 	/**
-	 * @copydoc GpuDataParamBase
+	 * @copydoc TGpuDataParam
 	 */
 	class BS_CORE_EXPORT GpuParamLoadStoreTexture
 	{
@@ -291,12 +297,12 @@ namespace BansheeEngine
 		GpuParamLoadStoreTexture();
 
 		/**
-		 * @copydoc	GpuDataParamBase::set
+		 * @copydoc	TGpuDataParam::set
 		 */
 		void set(const HTexture& texture, const TextureSurface& surface);
 
 		/**
-		 * @copydoc	GpuDataParamBase::get
+		 * @copydoc	TGpuDataParam::get
 		 */
 		HTexture get();
 		
@@ -309,7 +315,7 @@ namespace BansheeEngine
 	};
 
 	/**
-	 * @copydoc GpuDataParamBase
+	 * @copydoc TGpuDataParam
 	 */
 	class BS_CORE_EXPORT GpuParamSampState
 	{
@@ -320,12 +326,12 @@ namespace BansheeEngine
 		GpuParamSampState();
 
 		/**
-		 * @copydoc	GpuDataParamBase::set
+		 * @copydoc	TGpuDataParam::set
 		 */
 		void set(const HSamplerState& texture);
 
 		/**
-		 * @copydoc	GpuDataParamBase::get
+		 * @copydoc	TGpuDataParam::get
 		 */
 		HSamplerState get();
 

+ 42 - 21
BansheeCore/Include/BsGpuParams.h

@@ -138,9 +138,12 @@ namespace BansheeEngine
 			auto iterFind = mParamDesc->params.find(name);
 
 			if (iterFind == mParamDesc->params.end() || iterFind->second.type != GPDT_FLOAT1)
-				BS_EXCEPT(InvalidParametersException, "Cannot find float parameter with the name '" + name + "'");
-
-			output = GpuParamFloat(&iterFind->second, mInternalData);
+			{
+				output = GpuParamFloat(&iterFind->second, nullptr);
+				LOGWRN("Cannot find float parameter with the name '" + name + "'");
+			}
+			else
+				output = GpuParamFloat(&iterFind->second, mInternalData);
 		}
 
 		/**
@@ -152,9 +155,12 @@ namespace BansheeEngine
 			auto iterFind = mParamDesc->params.find(name);
 
 			if (iterFind == mParamDesc->params.end() || iterFind->second.type != GPDT_FLOAT2)
-				BS_EXCEPT(InvalidParametersException, "Cannot find vector (2) parameter with the name '" + name + "'");
-
-			output = GpuParamVec2(&iterFind->second, mInternalData);
+			{
+				output = GpuParamVec2(&iterFind->second, nullptr);
+				LOGWRN("Cannot find vector (2) parameter with the name '" + name + "'");
+			}
+			else
+				output = GpuParamVec2(&iterFind->second, mInternalData);
 		}
 
 		/**
@@ -166,9 +172,12 @@ namespace BansheeEngine
 			auto iterFind = mParamDesc->params.find(name);
 
 			if (iterFind == mParamDesc->params.end() || iterFind->second.type != GPDT_FLOAT3)
-				BS_EXCEPT(InvalidParametersException, "Cannot find vector (3) parameter with the name '" + name + "'");
-
-			output = GpuParamVec3(&iterFind->second, mInternalData);
+			{
+				output = GpuParamVec3(&iterFind->second, nullptr);
+				LOGWRN("Cannot find vector (3) parameter with the name '" + name + "'");
+			}
+			else
+				output = GpuParamVec3(&iterFind->second, mInternalData);
 		}
 
 		/**
@@ -180,9 +189,12 @@ namespace BansheeEngine
 			auto iterFind = mParamDesc->params.find(name);
 
 			if (iterFind == mParamDesc->params.end() || iterFind->second.type != GPDT_FLOAT4)
-				BS_EXCEPT(InvalidParametersException, "Cannot find vector (4) parameter with the name '" + name + "'");
-
-			output = GpuParamVec4(&iterFind->second, mInternalData);
+			{
+				output = GpuParamVec4(&iterFind->second, nullptr);
+				LOGWRN("Cannot find vector (4) parameter with the name '" + name + "'");
+			}
+			else
+				output = GpuParamVec4(&iterFind->second, mInternalData);
 		}
 
 		/**
@@ -194,9 +206,12 @@ namespace BansheeEngine
 			auto iterFind = mParamDesc->params.find(name);
 
 			if (iterFind == mParamDesc->params.end() || iterFind->second.type != GPDT_FLOAT4)
-				BS_EXCEPT(InvalidParametersException, "Cannot find color parameter with the name '" + name + "'");
-
-			output = GpuParamColor(&iterFind->second, mInternalData);
+			{
+				output = GpuParamColor(&iterFind->second, nullptr);
+				LOGWRN("Cannot find color parameter with the name '" + name + "'");
+			}
+			else
+				output = GpuParamColor(&iterFind->second, mInternalData);
 		}
 
 		/**
@@ -208,9 +223,12 @@ namespace BansheeEngine
 			auto iterFind = mParamDesc->params.find(name);
 
 			if (iterFind == mParamDesc->params.end() || iterFind->second.type != GPDT_MATRIX_3X3)
-				BS_EXCEPT(InvalidParametersException, "Cannot find matrix (3x3) parameter with the name '" + name + "'");
-
-			output = GpuParamMat3(&iterFind->second, mInternalData);
+			{
+				output = GpuParamMat3(&iterFind->second, nullptr);
+				LOGWRN("Cannot find matrix (3x3) parameter with the name '" + name + "'");
+			}
+			else
+				output = GpuParamMat3(&iterFind->second, mInternalData);
 		}
 
 		/**
@@ -222,9 +240,12 @@ namespace BansheeEngine
 			auto iterFind = mParamDesc->params.find(name);
 
 			if (iterFind == mParamDesc->params.end() || iterFind->second.type != GPDT_MATRIX_4X4)
-				BS_EXCEPT(InvalidParametersException, "Cannot find matrix (4x4) parameter with the name '" + name + "'");
-
-			output = GpuParamMat4(&iterFind->second, mInternalData);
+			{
+				output = GpuParamMat4(&iterFind->second, nullptr);
+				LOGWRN("Cannot find matrix (4x4) parameter with the name '" + name + "'");
+			}
+			else
+				output = GpuParamMat4(&iterFind->second, mInternalData);
 		}
 
 		/**

+ 33 - 30
BansheeCore/Include/BsMaterial.h

@@ -2,7 +2,7 @@
 
 #include "BsCorePrerequisites.h"
 #include "BsResource.h"
-#include "BsGpuParam.h"
+#include "BsMaterialParam.h"
 #include "BsMaterialProxy.h"
 #include "BsVector2.h"
 #include "BsVector3.h"
@@ -278,7 +278,7 @@ namespace BansheeEngine
 		 * 			
 		 *			If material shader changes this handle will be invalidated.
 		 */
-		GpuParamFloat getParamFloat(const String& name) const;
+		MaterialParamFloat getParamFloat(const String& name) const;
 
 		/**
 		 * @brief	Returns a color GPU parameter. This parameter may be used for
@@ -291,7 +291,7 @@ namespace BansheeEngine
 		 * 			
 		 *			If material shader changes this handle will be invalidated.
 		 */
-		GpuParamColor getParamColor(const String& name) const;
+		MaterialParamColor getParamColor(const String& name) const;
 
 		/**
 		 * @brief	Returns a 2D vector GPU parameter. This parameter may be used for
@@ -304,7 +304,7 @@ namespace BansheeEngine
 		 * 			
 		 *			If material shader changes this handle will be invalidated.
 		 */
-		GpuParamVec2 getParamVec2(const String& name) const;
+		MaterialParamVec2 getParamVec2(const String& name) const;
 
 		/**
 		 * @brief	Returns a 3D vector GPU parameter. This parameter may be used for
@@ -317,7 +317,7 @@ namespace BansheeEngine
 		 * 			
 		 *			If material shader changes this handle will be invalidated.
 		 */
-		GpuParamVec3 getParamVec3(const String& name) const;
+		MaterialParamVec3 getParamVec3(const String& name) const;
 
 		/**
 		 * @brief	Returns a 4D vector GPU parameter. This parameter may be used for
@@ -330,7 +330,7 @@ namespace BansheeEngine
 		 * 			
 		 *			If material shader changes this handle will be invalidated.
 		 */
-		GpuParamVec4 getParamVec4(const String& name) const;
+		MaterialParamVec4 getParamVec4(const String& name) const;
 
 		/**
 		 * @brief	Returns a 3x3 matrix GPU parameter. This parameter may be used for
@@ -343,7 +343,7 @@ namespace BansheeEngine
 		 * 			
 		 *			If material shader changes this handle will be invalidated.
 		 */
-		GpuParamMat3 getParamMat3(const String& name) const;
+		MaterialParamMat3 getParamMat3(const String& name) const;
 
 		/**
 		 * @brief	Returns a 4x4 matrix GPU parameter. This parameter may be used for
@@ -356,7 +356,7 @@ namespace BansheeEngine
 		 * 			
 		 *			If material shader changes this handle will be invalidated.
 		 */
-		GpuParamMat4 getParamMat4(const String& name) const;
+		MaterialParamMat4 getParamMat4(const String& name) const;
 
 		/**
 		 * @brief	Returns a structure GPU parameter. This parameter may be used for
@@ -369,7 +369,7 @@ namespace BansheeEngine
 		 * 			
 		 *			If material shader changes this handle will be invalidated.
 		 */
-		GpuParamStruct getParamStruct(const String& name) const;
+		MaterialParamStruct getParamStruct(const String& name) const;
 
 		/**
 		 * @brief	Returns a texture GPU parameter. This parameter may be used for
@@ -382,7 +382,7 @@ namespace BansheeEngine
 		 * 			
 		 *			If material shader changes this handle will be invalidated.
 		 */
-		GpuParamTexture getParamTexture(const String& name) const;
+		MaterialParamTexture getParamTexture(const String& name) const;
 
 		/**
 		 * @brief	Returns a GPU parameter for binding a load/store texture. This parameter 
@@ -395,7 +395,7 @@ namespace BansheeEngine
 		 * 			
 		 *			If material shader changes this handle will be invalidated.
 		 */
-		GpuParamLoadStoreTexture getParamLoadStoreTexture(const String& name) const;
+		MaterialParamLoadStoreTexture getParamLoadStoreTexture(const String& name) const;
 
 		/**
 		 * @brief	Returns a sampler state GPU parameter. This parameter may be used for
@@ -408,7 +408,7 @@ namespace BansheeEngine
 		 * 			
 		 *			If material shader changes this handle will be invalidated.
 		 */
-		GpuParamSampState getParamSamplerState(const String& name) const;
+		MaterialParamSampState getParamSamplerState(const String& name) const;
 
 		/**
 		 * @brief	Returns the number of passes that are used
@@ -501,7 +501,7 @@ namespace BansheeEngine
 		 * 			caller to keep track of that.
 		 */
 		template <typename T>
-		void getParam(const String& name, TGpuDataParam<T>& output) const
+		void getParam(const String& name, TMaterialDataParam<T>& output) const
 		{
 			throwIfNotInitialized();
 
@@ -513,9 +513,27 @@ namespace BansheeEngine
 			}
 
 			const String& gpuVarName = iterFind->second;
-			GpuParamsPtr params = findParamsWithName(gpuVarName);
+			Vector<TGpuDataParam<T>> gpuParams;
 
-			params->getParam<T>(gpuVarName, output);
+			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->hasParam(gpuVarName))
+						{
+							gpuParams.push_back(TGpuDataParam<T>());
+							paramPtr->getParam<T>(gpuVarName, gpuParams.back());
+						}
+					}
+				}
+			}
+
+			output = TMaterialDataParam<T>(gpuParams);
 		}
 
 	private:
@@ -594,21 +612,6 @@ namespace BansheeEngine
 		 */
 		void freeParamBuffers();
 
-		/**
-		 * @brief	Finds a set of GPU parameters containing a data (e.g. float, vector2) parameter with the provided name.
-		 */
-		GpuParamsPtr findParamsWithName(const String& name) const;
-
-		/**
-		 * @brief	Finds a set of GPU parameters containing a texture parameter with the provided name.
-		 */
-		GpuParamsPtr findTexWithName(const String& name) const;
-
-		/**
-		 * @brief	Finds a set of GPU parameters containing a sampler state parameter with the provided name.
-		 */
-		GpuParamsPtr findSamplerStateWithName(const String& name) const;
-
 		/************************************************************************/
 		/* 								RTTI		                     		*/
 		/************************************************************************/

+ 167 - 0
BansheeCore/Include/BsMaterialParam.h

@@ -0,0 +1,167 @@
+#pragma once
+
+#include "BsCorePrerequisites.h"
+#include "BsGpuParam.h"
+
+namespace BansheeEngine
+{
+	/**
+	 * @brief	A wrapper class that allows you to manage multiple GPU parameters
+	 *			at once.
+	 *
+	 * @see		TGpuDataParam
+	 */
+	template<class T>
+	class BS_CORE_EXPORT TMaterialDataParam
+	{
+	public:
+		TMaterialDataParam() { }
+		
+		/**
+		 * @copydoc	TGpuDataParam::set
+		 */
+		void set(const T& value, UINT32 arrayIdx = 0)
+		{
+			for (auto& param : mParams)
+				param.set(value, arrayIdx);
+		}
+
+		/**
+		 * @copydoc	TGpuDataParam::set
+		 */
+		T get(UINT32 arrayIdx = 0)
+		{
+			if (mParams.size() == 0)
+				return T();
+
+			return mParams[0].get(arrayIdx); // They should all have the same value
+		}
+
+	private:
+		friend class Material;
+
+		TMaterialDataParam(const Vector<TGpuDataParam<T>>& params)
+			:mParams(params)
+		{ }
+	protected:
+		Vector<TGpuDataParam<T>> mParams;
+	};
+
+	typedef TMaterialDataParam<float> MaterialParamFloat;
+	typedef TMaterialDataParam<Color> MaterialParamColor;
+	typedef TMaterialDataParam<Vector2> MaterialParamVec2;
+	typedef TMaterialDataParam<Vector3> MaterialParamVec3;
+	typedef TMaterialDataParam<Vector4> MaterialParamVec4;
+	typedef TMaterialDataParam<Matrix3> MaterialParamMat3;
+	typedef TMaterialDataParam<Matrix4> MaterialParamMat4;
+
+	/**
+	 * @copydoc	TMaterialDataParam
+	 */
+	class BS_CORE_EXPORT MaterialParamStruct
+	{
+	public:
+		MaterialParamStruct() { }
+
+		/**
+		 * @copydoc	GpuParamStruct::set
+		 */
+		void set(const void* value, UINT32 sizeBytes, UINT32 arrayIdx = 0);
+
+		/**
+		 * @copydoc	GpuParamStruct::get
+		 */
+		void get(void* value, UINT32 sizeBytes, UINT32 arrayIdx = 0);
+
+		/**
+		 * @copydoc	GpuParamStruct::getElementSize
+		 */
+		UINT32 getElementSize() const;
+
+	private:
+		friend class Material;
+
+		MaterialParamStruct(const Vector<GpuParamStruct>& params);
+	protected:
+		Vector<GpuParamStruct> mParams;
+	};
+
+	/**
+	 * @copydoc	TMaterialDataParam
+	 */
+	class BS_CORE_EXPORT MaterialParamTexture
+	{
+	public:
+		MaterialParamTexture() { }
+
+		/**
+		 * @copydoc	GpuParamTexture::set
+		 */
+		void set(const HTexture& texture);
+
+		/**
+		 * @copydoc	GpuParamTexture::get
+		 */
+		HTexture get();
+
+	private:
+		friend class Material;
+
+		MaterialParamTexture(const Vector<GpuParamTexture>& params);
+
+	protected:
+		Vector<GpuParamTexture> mParams;
+	};
+
+	/**
+	 * @copydoc	TMaterialDataParam
+	 */
+	class BS_CORE_EXPORT MaterialParamLoadStoreTexture
+	{
+	public:
+		MaterialParamLoadStoreTexture() { }
+
+		/**
+		 * @copydoc	GpuParamLoadStoreTexture::set
+		 */
+		void set(const HTexture& texture, const TextureSurface& surface);
+
+		/**
+		 * @copydoc	GpuParamLoadStoreTexture::get
+		 */
+		HTexture get();
+
+	private:
+		friend class Material;
+
+		MaterialParamLoadStoreTexture(const Vector<GpuParamLoadStoreTexture>& params);
+	protected:
+		Vector<GpuParamLoadStoreTexture> mParams;
+	};
+
+	/**
+	 * @copydoc	TMaterialDataParam
+	 */
+	class BS_CORE_EXPORT MaterialParamSampState
+	{
+	public:
+		MaterialParamSampState() { }
+
+		/**
+		 * @copydoc	GpuParamSampState::set
+		 */
+		void set(const HSamplerState& sampState);
+
+		/**
+		 * @copydoc	GpuParamSampState::get
+		 */
+		HSamplerState get();
+
+	private:
+		friend class Material;
+
+		MaterialParamSampState(const Vector<GpuParamSampState>& params);
+	protected:
+		Vector<GpuParamSampState> mParams;
+	};
+}

+ 27 - 0
BansheeCore/Source/BsGpuParam.cpp

@@ -45,6 +45,9 @@ namespace BansheeEngine
 
 	void GpuParamStruct::set(const void* value, UINT32 sizeBytes, UINT32 arrayIdx)
 	{
+		if (mInternalData == nullptr)
+			return;
+
 		if (mInternalData->mIsDestroyed)
 			BS_EXCEPT(InternalErrorException, "Trying to access a destroyed gpu parameter.");
 
@@ -81,6 +84,9 @@ namespace BansheeEngine
 
 	void GpuParamStruct::get(void* value, UINT32 sizeBytes, UINT32 arrayIdx)
 	{
+		if (mInternalData == nullptr)
+			return;
+
 		if (mInternalData->mIsDestroyed)
 			BS_EXCEPT(InternalErrorException, "Trying to access a destroyed gpu parameter.");
 
@@ -107,6 +113,9 @@ namespace BansheeEngine
 
 	UINT32 GpuParamStruct::getElementSize() const
 	{
+		if (mInternalData == nullptr)
+			return 0;
+
 		if(mInternalData->mIsDestroyed)
 			BS_EXCEPT(InternalErrorException, "Trying to access a destroyed gpu parameter.");
 
@@ -127,6 +136,9 @@ namespace BansheeEngine
 
 	void GpuParamTexture::set(const HTexture& texture)
 	{
+		if (mInternalData == nullptr)
+			return;
+
 		if (mInternalData->mIsDestroyed)
 			BS_EXCEPT(InternalErrorException, "Trying to access a destroyed gpu parameter.");
 
@@ -137,6 +149,9 @@ namespace BansheeEngine
 
 	HTexture GpuParamTexture::get()
 	{
+		if (mInternalData == nullptr)
+			return HTexture();
+
 		if (mInternalData->mIsDestroyed)
 			BS_EXCEPT(InternalErrorException, "Trying to access a destroyed gpu parameter.");
 
@@ -157,6 +172,9 @@ namespace BansheeEngine
 
 	void GpuParamLoadStoreTexture::set(const HTexture& texture, const TextureSurface& surface)
 	{
+		if (mInternalData == nullptr)
+			return;
+
 		if (mInternalData->mIsDestroyed)
 			BS_EXCEPT(InternalErrorException, "Trying to access a destroyed gpu parameter.");
 
@@ -168,6 +186,9 @@ namespace BansheeEngine
 
 	HTexture GpuParamLoadStoreTexture::get()
 	{
+		if (mInternalData == nullptr)
+			return HTexture();
+
 		if (mInternalData->mIsDestroyed)
 			BS_EXCEPT(InternalErrorException, "Trying to access a destroyed gpu parameter.");
 
@@ -188,6 +209,9 @@ namespace BansheeEngine
 
 	void GpuParamSampState::set(const HSamplerState& samplerState)
 	{
+		if (mInternalData == nullptr)
+			return;
+
 		if (mInternalData->mIsDestroyed)
 			BS_EXCEPT(InternalErrorException, "Trying to access a destroyed gpu parameter.");
 
@@ -197,6 +221,9 @@ namespace BansheeEngine
 
 	HSamplerState GpuParamSampState::get()
 	{
+		if (mInternalData == nullptr)
+			return HSamplerState();
+
 		if (mInternalData->mIsDestroyed)
 			BS_EXCEPT(InternalErrorException, "Trying to access a destroyed gpu parameter.");
 

+ 24 - 12
BansheeCore/Source/BsGpuParams.cpp

@@ -150,9 +150,12 @@ namespace BansheeEngine
 		auto iterFind = mParamDesc->params.find(name);
 
 		if (iterFind == mParamDesc->params.end() || iterFind->second.type != GPDT_STRUCT)
-			BS_EXCEPT(InvalidParametersException, "Cannot find struct parameter with the name '" + name + "'");
-
-		output = GpuParamStruct(&iterFind->second, mInternalData);
+		{
+			output = GpuParamStruct(&iterFind->second, nullptr);
+			LOGWRN("Cannot find struct parameter with the name '" + name + "'");
+		}
+		else
+			output = GpuParamStruct(&iterFind->second, mInternalData);
 	}
 
 	void GpuParams::getTextureParam(const String& name, GpuParamTexture& output) const
@@ -160,9 +163,12 @@ namespace BansheeEngine
 		auto iterFind = mParamDesc->textures.find(name);
 
 		if (iterFind == mParamDesc->textures.end())
-			BS_EXCEPT(InvalidParametersException, "Cannot find texture parameter with the name '" + name + "'");
-
-		output = GpuParamTexture(&iterFind->second, mInternalData);
+		{
+			output = GpuParamTexture(&iterFind->second, nullptr);
+			LOGWRN("Cannot find texture parameter with the name '" + name + "'");
+		}
+		else
+			output = GpuParamTexture(&iterFind->second, mInternalData);
 	}
 
 	void GpuParams::getLoadStoreTextureParam(const String& name, GpuParamLoadStoreTexture& output) const
@@ -170,9 +176,12 @@ namespace BansheeEngine
 		auto iterFind = mParamDesc->textures.find(name);
 
 		if (iterFind == mParamDesc->textures.end())
-			BS_EXCEPT(InvalidParametersException, "Cannot find texture parameter with the name '" + name + "'");
-
-		output = GpuParamLoadStoreTexture(&iterFind->second, mInternalData);
+		{
+			output = GpuParamLoadStoreTexture(&iterFind->second, nullptr);
+			LOGWRN("Cannot find texture parameter with the name '" + name + "'");
+		}
+		else
+			output = GpuParamLoadStoreTexture(&iterFind->second, mInternalData);
 	}
 
 	void GpuParams::getSamplerStateParam(const String& name, GpuParamSampState& output) const
@@ -180,9 +189,12 @@ namespace BansheeEngine
 		auto iterFind = mParamDesc->samplers.find(name);
 
 		if (iterFind == mParamDesc->samplers.end())
-			BS_EXCEPT(InvalidParametersException, "Cannot find sampler state parameter with the name '" + name + "'");
-
-		output = GpuParamSampState(&iterFind->second, mInternalData);
+		{
+			output = GpuParamSampState(&iterFind->second, nullptr);
+			LOGWRN("Cannot find sampler state parameter with the name '" + name + "'");
+		}
+		else
+			output = GpuParamSampState(&iterFind->second, mInternalData);
 	}
 
 	GpuParamDataDesc* GpuParams::getParamDesc(const String& name) const

+ 87 - 88
BansheeCore/Source/BsMaterial.cpp

@@ -525,7 +525,7 @@ namespace BansheeEngine
 
 	Material::StructData Material::getStructData(const String& name, UINT32 arrayIdx) const
 	{
-		GpuParamStruct structParam = getParamStruct(name);
+		MaterialParamStruct structParam = getParamStruct(name);
 
 		StructData data(structParam.getElementSize());
 		structParam.get(data.data.get(), structParam.getElementSize(), arrayIdx);
@@ -533,200 +533,199 @@ namespace BansheeEngine
 		return data;
 	}
 
-	GpuParamFloat Material::getParamFloat(const String& name) const
+	MaterialParamFloat Material::getParamFloat(const String& name) const
 	{
-		TGpuDataParam<float> gpuParam;
+		TMaterialDataParam<float> gpuParam;
 		getParam(name, gpuParam);
 
 		return gpuParam;
 	}
 
-	GpuParamColor Material::getParamColor(const String& name) const
+	MaterialParamColor Material::getParamColor(const String& name) const
 	{
-		TGpuDataParam<Color> gpuParam;
+		TMaterialDataParam<Color> gpuParam;
 		getParam(name, gpuParam);
 
 		return gpuParam;
 	}
 
-	GpuParamVec2 Material::getParamVec2(const String& name) const
+	MaterialParamVec2 Material::getParamVec2(const String& name) const
 	{
-		TGpuDataParam<Vector2> gpuParam;
+		TMaterialDataParam<Vector2> gpuParam;
 		getParam(name, gpuParam);
 
 		return gpuParam;
 	}
 
-	GpuParamVec3 Material::getParamVec3(const String& name) const
+	MaterialParamVec3 Material::getParamVec3(const String& name) const
 	{
-		TGpuDataParam<Vector3> gpuParam;
+		TMaterialDataParam<Vector3> gpuParam;
 		getParam(name, gpuParam);
 
 		return gpuParam;
 	}
 
-	GpuParamVec4 Material::getParamVec4(const String& name) const
+	MaterialParamVec4 Material::getParamVec4(const String& name) const
 	{
-		TGpuDataParam<Vector4> gpuParam;
+		TMaterialDataParam<Vector4> gpuParam;
 		getParam(name, gpuParam);
 
 		return gpuParam;
 	}
 
-	GpuParamMat3 Material::getParamMat3(const String& name) const
+	MaterialParamMat3 Material::getParamMat3(const String& name) const
 	{
-		TGpuDataParam<Matrix3> gpuParam;
+		TMaterialDataParam<Matrix3> gpuParam;
 		getParam(name, gpuParam);
 
 		return gpuParam;
 	}
 
-	GpuParamMat4 Material::getParamMat4(const String& name) const
+	MaterialParamMat4 Material::getParamMat4(const String& name) const
 	{
-		TGpuDataParam<Matrix4> gpuParam;
+		TMaterialDataParam<Matrix4> gpuParam;
 		getParam(name, gpuParam);
 
 		return gpuParam;
 	}
 
-	GpuParamStruct Material::getParamStruct(const String& name) const
+	MaterialParamStruct Material::getParamStruct(const String& name) const
 	{
 		throwIfNotInitialized();
 
-		GpuParamStruct gpuParam;
-
 		auto iterFind = mValidParams.find(name);
 		if(iterFind == mValidParams.end())
 		{
 			LOGWRN("Material doesn't have a parameter named " + name);
-			return gpuParam;
+			return MaterialParamStruct();
 		}
 
 		const String& gpuVarName = iterFind->second;
-		GpuParamsPtr params = findParamsWithName(gpuVarName);
+		Vector<GpuParamStruct> gpuParams;
 
-		params->getStructParam(gpuVarName, gpuParam);
-		return gpuParam;
+		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->hasParam(gpuVarName))
+					{
+						gpuParams.push_back(GpuParamStruct());
+						paramPtr->getStructParam(gpuVarName, gpuParams.back());
+					}
+				}
+			}
+		}
+
+		return MaterialParamStruct(gpuParams);
 	}
 
-	GpuParamTexture Material::getParamTexture(const String& name) const
+	MaterialParamTexture Material::getParamTexture(const String& name) const
 	{
 		throwIfNotInitialized();
 
-		GpuParamTexture gpuParam;
-
 		auto iterFind = mValidParams.find(name);
 		if(iterFind == mValidParams.end())
 		{
 			LOGWRN("Material doesn't have a parameter named " + name);
-			return gpuParam;
+			return MaterialParamTexture();
 		}
 
 		const String& gpuVarName = iterFind->second;
-		GpuParamsPtr params = findTexWithName(gpuVarName);
+		Vector<GpuParamTexture> gpuParams;
 
-		params->getTextureParam(gpuVarName, gpuParam);
-		return gpuParam;
-	}
-
-	GpuParamLoadStoreTexture Material::getParamLoadStoreTexture(const String& name) const
-	{
-		throwIfNotInitialized();
-
-		GpuParamLoadStoreTexture gpuParam;
-
-		auto iterFind = mValidParams.find(name);
-		if (iterFind == mValidParams.end())
+		for (auto iter = mParametersPerPass.begin(); iter != mParametersPerPass.end(); ++iter)
 		{
-			LOGWRN("Material doesn't have a parameter named " + name);
-			return gpuParam;
-		}
+			PassParametersPtr params = *iter;
 
-		const String& gpuVarName = iterFind->second;
-		GpuParamsPtr params = findTexWithName(gpuVarName);
+			for (UINT32 i = 0; i < params->getNumParams(); i++)
+			{
+				GpuParamsPtr& paramPtr = params->getParamByIdx(i);
+				if (paramPtr)
+				{
+					if (paramPtr->hasTexture(gpuVarName))
+					{
+						gpuParams.push_back(GpuParamTexture());
+						paramPtr->getTextureParam(gpuVarName, gpuParams.back());
+					}
+				}
+			}
+		}
 
-		params->getLoadStoreTextureParam(gpuVarName, gpuParam);
-		return gpuParam;
+		return MaterialParamTexture(gpuParams);
 	}
 
-	GpuParamSampState Material::getParamSamplerState(const String& name) const
+	MaterialParamLoadStoreTexture Material::getParamLoadStoreTexture(const String& name) const
 	{
 		throwIfNotInitialized();
 
-		GpuParamSampState gpuParam;
-
 		auto iterFind = mValidParams.find(name);
-		if(iterFind == mValidParams.end())
+		if (iterFind == mValidParams.end())
 		{
 			LOGWRN("Material doesn't have a parameter named " + name);
-			return gpuParam;
+			return MaterialParamLoadStoreTexture();
 		}
 
 		const String& gpuVarName = iterFind->second;
-		GpuParamsPtr params = findSamplerStateWithName(gpuVarName);
+		Vector<GpuParamLoadStoreTexture> gpuParams;
 
-		params->getSamplerStateParam(gpuVarName, gpuParam);
-		return gpuParam;
-	}
-
-	GpuParamsPtr Material::findParamsWithName(const String& name) const
-	{
-		for(auto iter = mParametersPerPass.begin(); iter != mParametersPerPass.end(); ++iter)
+		for (auto iter = mParametersPerPass.begin(); iter != mParametersPerPass.end(); ++iter)
 		{
 			PassParametersPtr params = *iter;
 
-			for(UINT32 i = 0; i < params->getNumParams(); i++)
+			for (UINT32 i = 0; i < params->getNumParams(); i++)
 			{
 				GpuParamsPtr& paramPtr = params->getParamByIdx(i);
-				if(paramPtr)
+				if (paramPtr)
 				{
-					if(paramPtr->hasParam(name))
-						return paramPtr;
+					if (paramPtr->hasTexture(gpuVarName))
+					{
+						gpuParams.push_back(GpuParamLoadStoreTexture());
+						paramPtr->getLoadStoreTextureParam(gpuVarName, gpuParams.back());
+					}
 				}
 			}
 		}
 
-		BS_EXCEPT(InternalErrorException, "Shader has no parameter with the name: " + name);
+		return MaterialParamLoadStoreTexture(gpuParams);
 	}
 
-	GpuParamsPtr Material::findTexWithName(const String& name) const
+	MaterialParamSampState Material::getParamSamplerState(const String& name) const
 	{
-		for(auto iter = mParametersPerPass.begin(); iter != mParametersPerPass.end(); ++iter)
-		{
-			PassParametersPtr params = *iter;
+		throwIfNotInitialized();
 
-			for(UINT32 i = 0; i < params->getNumParams(); i++)
-			{
-				GpuParamsPtr& paramPtr = params->getParamByIdx(i);
-				if(paramPtr)
-				{
-					if(paramPtr->hasTexture(name))
-						return paramPtr;
-				}
-			}
+		auto iterFind = mValidParams.find(name);
+		if(iterFind == mValidParams.end())
+		{
+			LOGWRN("Material doesn't have a parameter named " + name);
+			return MaterialParamSampState();
 		}
 
-		BS_EXCEPT(InternalErrorException, "Shader has no parameter with the name: " + name);
-	}
-
-	GpuParamsPtr Material::findSamplerStateWithName(const String& name) const
-	{
-		for(auto iter = mParametersPerPass.begin(); iter != mParametersPerPass.end(); ++iter)
+		const String& gpuVarName = iterFind->second;
+		Vector<GpuParamSampState> gpuParams;
+		for (auto iter = mParametersPerPass.begin(); iter != mParametersPerPass.end(); ++iter)
 		{
 			PassParametersPtr params = *iter;
 
-			for(UINT32 i = 0; i < params->getNumParams(); i++)
+			for (UINT32 i = 0; i < params->getNumParams(); i++)
 			{
 				GpuParamsPtr& paramPtr = params->getParamByIdx(i);
-				if(paramPtr)
+				if (paramPtr)
 				{
-					if(paramPtr->hasSamplerState(name))
-						return paramPtr;
+					if (paramPtr->hasSamplerState(gpuVarName))
+					{
+						gpuParams.push_back(GpuParamSampState());
+						paramPtr->getSamplerStateParam(gpuVarName, gpuParams.back());
+					}
 				}
 			}
 		}
 
-		BS_EXCEPT(InternalErrorException, "Shader has no parameter with the name: " + name);
+		return MaterialParamSampState(gpuParams);
 	}
 
 	bool Material::_isCoreDirty(MaterialDirtyFlag flag) const

+ 87 - 0
BansheeCore/Source/BsMaterialParam.cpp

@@ -0,0 +1,87 @@
+#include "BsMaterialParam.h"
+
+namespace BansheeEngine
+{
+	void MaterialParamStruct::set(const void* value, UINT32 sizeBytes, UINT32 arrayIdx)
+	{
+		for (auto& param : mParams)
+			param.set(value, sizeBytes, arrayIdx);
+	}
+
+	void MaterialParamStruct::get(void* value, UINT32 sizeBytes, UINT32 arrayIdx)
+	{
+		if (mParams.size() == 0)
+		{
+			value = nullptr;
+			return;
+		}
+
+		return mParams[0].get(value, sizeBytes, arrayIdx); // They should all have the same value
+	}
+
+	UINT32 MaterialParamStruct::getElementSize() const
+	{
+		if (mParams.size() == 0)
+			return 0;
+
+		return mParams[0].getElementSize();
+	}
+
+	MaterialParamStruct::MaterialParamStruct(const Vector<GpuParamStruct>& params)
+		:mParams(params)
+	{ }
+
+	void MaterialParamTexture::set(const HTexture& texture)
+	{
+		for (auto& param : mParams)
+			param.set(texture);
+	}
+
+	HTexture MaterialParamTexture::get()
+	{
+		if (mParams.size() == 0)
+			return HTexture();
+
+		return mParams[0].get(); // They should all have the same value
+	}
+
+	MaterialParamTexture::MaterialParamTexture(const Vector<GpuParamTexture>& params)
+		:mParams(params)
+	{ }
+
+	void MaterialParamLoadStoreTexture::set(const HTexture& texture, const TextureSurface& surface)
+	{
+		for (auto& param : mParams)
+			param.set(texture, surface);
+	}
+
+	HTexture MaterialParamLoadStoreTexture::get()
+	{
+		if (mParams.size() == 0)
+			return HTexture();
+
+		return mParams[0].get(); // They should all have the same value
+	}
+
+	MaterialParamLoadStoreTexture::MaterialParamLoadStoreTexture(const Vector<GpuParamLoadStoreTexture>& params)
+		:mParams(params)
+	{ }
+
+	void MaterialParamSampState::set(const HSamplerState& sampState)
+	{
+		for (auto& param : mParams)
+			param.set(sampState);
+	}
+
+	HSamplerState MaterialParamSampState::get()
+	{
+		if (mParams.size() == 0)
+			return HSamplerState();
+
+		return mParams[0].get(); // They should all have the same value
+	}
+
+	MaterialParamSampState::MaterialParamSampState(const Vector<GpuParamSampState>& params)
+		:mParams(params)
+	{ }
+}

+ 1 - 1
BansheeEditor/Include/BsSceneGrid.h

@@ -24,7 +24,7 @@ namespace BansheeEngine
 
 		HMesh mGridMesh;
 		HMaterial mGridMaterial;
-		GpuParamMat4 mViewProjParam;
+		MaterialParamMat4 mViewProjParam;
 		VertexDataDescPtr mVertexDesc;
 
 		Vector3 mOrigin;

+ 7 - 7
BansheeEngine/Include/BsGUIMaterialInfo.h

@@ -1,7 +1,7 @@
 #pragma once
 
 #include "BsPrerequisites.h"
-#include "BsGpuParam.h"
+#include "BsMaterialParam.h"
 
 namespace BansheeEngine
 {
@@ -11,11 +11,11 @@ namespace BansheeEngine
 	struct GUIMaterialInfo
 	{
 		HMaterial material;
-		GpuParamMat4 worldTransform;
-		GpuParamFloat invViewportWidth;
-		GpuParamFloat invViewportHeight;
-		GpuParamSampState mainTexSampler;
-		GpuParamTexture mainTexture;
-		GpuParamVec4 tint;
+		MaterialParamMat4 worldTransform;
+		MaterialParamFloat invViewportWidth;
+		MaterialParamFloat invViewportHeight;
+		MaterialParamSampState mainTexSampler;
+		MaterialParamTexture mainTexture;
+		MaterialParamVec4 tint;
 	};
 }

+ 10 - 10
SceneView.txt

@@ -38,6 +38,16 @@ LATER:
  - Add drag to select
  - Need a better system to catch broken shaders. DX11 just draws nothing with depth, DX9 draws all white.
 
+---------------------------------------------------------------------
+Render textures in C#:
+ - In C# have Texture2D, TextureCube, TextureVolume, Texture2DArray. They should have a common Texture base.
+   - Each of those can be created with a Renderable flag
+ - Render textures mirror what we have in C++
+   - RenderTexture and MultiRenderTexture (since we have these separate representation we don't need RenderBuffer that Unity has)
+   - You can provide an existing texture from types listed above, or create a new render target and
+      create a basic 2D texture (multiple constructors)
+ - Both RT types should have their color buffer (s) and depth buffer accessible as a texture to be used for rendering, or for reading
+
 ----------------------------------------------------------------------
 Handles
 
@@ -89,16 +99,6 @@ Find ones with Renderable components
 Retrieve Meshes, and world transforms from them
 Draw that same mesh with either a wireframe or a grayed out shader with a slight depth bias
 
----------------------------------------------------------------------
-Render textures in C#:
- - In C# have Texture2D, TextureCube, TextureVolume, Texture2DArray. They should have a common Texture base.
-   - Each of those can be created with a Renderable flag
- - Render textures mirror what we have in C++
-   - RenderTexture and MultiRenderTexture (since we have these separate representation we don't need RenderBuffer that Unity has)
-   - You can provide an existing texture from types listed above, or create a new render target and
-      create a basic 2D texture (multiple constructors)
- - Both RT types should have their color buffer (s) and depth buffer accessible as a texture to be used for rendering, or for reading
-
 ---------------------------------------------------------------------
 Multi-resources