瀏覽代碼

Mark material parameters as dirty when they are modified
Mark material data as dirty (requiring sync) when its parameters are modified

BearishSun 9 年之前
父節點
當前提交
78a144768e

+ 8 - 0
Source/BansheeCore/Include/BsCommonTypes.h

@@ -489,6 +489,14 @@ namespace BansheeEngine
 
 	typedef Map<String, String> NameValuePairList;
 
+	template<bool Core> struct TMeshType {};
+	template<> struct TMeshType < false > { typedef HMesh Type; };
+	template<> struct TMeshType < true > { typedef SPtr<MeshCore> Type; };
+
+	template<bool Core> struct TMaterialPtrType {};
+	template<> struct TMaterialPtrType < false > { typedef HMaterial Type; };
+	template<> struct TMaterialPtrType < true > { typedef SPtr<MaterialCore> Type; };
+
 	/** @cond SPECIALIZATIONS */
 	BS_ALLOW_MEMCPY_SERIALIZATION(TextureSurface);
 	/** @endcond */

+ 14 - 4
Source/BansheeCore/Include/BsMaterial.h

@@ -75,10 +75,15 @@ namespace BansheeEngine
 		MaterialBase() { }
 		virtual ~MaterialBase() { }
 
-	protected:
+		/** @name Internal
+		 *  @{
+		 */
+
 		/** Marks the contents of the sim thread object as dirty, causing it to sync with its core thread counterpart. */
 		virtual void _markCoreDirty() { }
 
+		/** @} */
+	protected:
 		/** @copydoc CoreObject::markDependenciesDirty */
 		virtual void _markDependenciesDirty() { }
 
@@ -627,6 +632,14 @@ namespace BansheeEngine
 		/** Creates a new material with the specified shader. */
 		static HMaterial create(const HShader& shader);
 
+		/** @name Internal
+		 *  @{
+		 */
+
+		/** @copydoc CoreObject::markCoreDirty */
+		void _markCoreDirty() override;
+
+		/** @} */
 	private:
 		friend class MaterialManager;
 
@@ -642,9 +655,6 @@ namespace BansheeEngine
 		/** @copydoc CoreObject::getCoreDependencies */
 		void getCoreDependencies(Vector<CoreObject*>& dependencies) override;
 
-		/** @copydoc CoreObject::markCoreDirty */
-		void _markCoreDirty() override;
-
 		/** @copydoc CoreObject::markDependenciesDirty */
 		void _markDependenciesDirty() override;
 

+ 31 - 18
Source/BansheeCore/Include/BsMaterialParam.h

@@ -11,6 +11,13 @@ namespace BansheeEngine
 	 *  @{
 	 */
 
+	class Material;
+	class MaterialCore;
+
+	template<bool Core> struct TMaterialType { };
+	template<> struct TMaterialType<false> { typedef SPtr<Material> Type; };
+	template<> struct TMaterialType<true> { typedef SPtr<MaterialCore> Type; };
+
 	class MaterialParams;
 	class MaterialParamsCore;
 
@@ -37,10 +44,11 @@ namespace BansheeEngine
 	template<class T, bool Core>
 	class BS_CORE_EXPORT TMaterialDataParam
 	{
+		typedef typename TMaterialType<Core>::Type MaterialPtrType;
 		typedef typename TMaterialParamsType<Core>::Type MaterialParamsType;
 
 	public:
-		TMaterialDataParam(const String& name, const SPtr<MaterialParamsType>& params);
+		TMaterialDataParam(const String& name, const MaterialPtrType& material);
 		TMaterialDataParam() { }
 
 		/** @copydoc TGpuDataParam::set */
@@ -52,23 +60,24 @@ namespace BansheeEngine
 		/** Checks if param is initialized. */
 		bool operator==(const nullptr_t& nullval) const
 		{
-			return mMaterialParams == nullptr;
+			return mMaterial == nullptr;
 		}
 
 	protected:
 		UINT32 mParamIndex;
 		UINT32 mArraySize;
-		SPtr<MaterialParamsType> mMaterialParams;
+		MaterialPtrType mMaterial;
 	};
 	
 	/** @copydoc TMaterialDataParam */
 	template<bool Core>
 	class BS_CORE_EXPORT TMaterialParamStruct
 	{
+		typedef typename TMaterialType<Core>::Type MaterialPtrType;
 		typedef typename TMaterialParamsType<Core>::Type MaterialParamsType;
 
 	public:
-		TMaterialParamStruct(const String& name, const SPtr<MaterialParamsType>& params);
+		TMaterialParamStruct(const String& name, const MaterialPtrType& material);
 		TMaterialParamStruct() { }
 
 		/** @copydoc TGpuParamStruct::set */
@@ -83,24 +92,25 @@ namespace BansheeEngine
 		/** Checks if param is initialized. */
 		bool operator==(const nullptr_t& nullval) const
 		{
-			return mMaterialParams == nullptr;
+			return mMaterial == nullptr;
 		}
 
 	protected:
 		UINT32 mParamIndex;
 		UINT32 mArraySize;
-		SPtr<MaterialParamsType> mMaterialParams;
+		MaterialPtrType mMaterial;
 	};
 
 	/** @copydoc TMaterialDataParam */
 	template<bool Core>
 	class BS_CORE_EXPORT TMaterialParamTexture
 	{
+		typedef typename TMaterialType<Core>::Type MaterialPtrType;
 		typedef typename TMaterialParamsType<Core>::Type MaterialParamsType;
 		typedef typename TGpuParamTextureType<Core>::Type TextureType;
 
 	public:
-		TMaterialParamTexture(const String& name, const SPtr<MaterialParamsType>& params);
+		TMaterialParamTexture(const String& name, const MaterialPtrType& material);
 		TMaterialParamTexture() { }
 
 		/** @copydoc GpuParamTexture::set */
@@ -112,23 +122,24 @@ namespace BansheeEngine
 		/** Checks if param is initialized. */
 		bool operator==(const nullptr_t& nullval) const
 		{
-			return mMaterialParams == nullptr;
+			return mMaterial == nullptr;
 		}
 
 	protected:
 		UINT32 mParamIndex;
-		SPtr<MaterialParamsType> mMaterialParams;
+		MaterialPtrType mMaterial;
 	};
 
 	/** @copydoc TMaterialDataParam */
 	template<bool Core>
 	class BS_CORE_EXPORT TMaterialParamLoadStoreTexture
 	{
+		typedef typename TMaterialType<Core>::Type MaterialPtrType;
 		typedef typename TMaterialParamsType<Core>::Type MaterialParamsType;
 		typedef typename TGpuParamTextureType<Core>::Type TextureType;
 
 	public:
-		TMaterialParamLoadStoreTexture(const String& name, const SPtr<MaterialParamsType>& params);
+		TMaterialParamLoadStoreTexture(const String& name, const MaterialPtrType& material);
 		TMaterialParamLoadStoreTexture() { }
 
 		/** @copydoc GpuParamLoadStoreTexture::set */
@@ -140,23 +151,24 @@ namespace BansheeEngine
 		/** Checks if param is initialized. */
 		bool operator==(const nullptr_t& nullval) const
 		{
-			return mMaterialParams == nullptr;
+			return mMaterial == nullptr;
 		}
 
 	protected:
 		UINT32 mParamIndex;
-		SPtr<MaterialParamsType> mMaterialParams;
+		MaterialPtrType mMaterial;
 	};
 	
 	/** @copydoc TMaterialDataParam */
 	template<bool Core>
 	class BS_CORE_EXPORT TMaterialParamBuffer
 	{
+		typedef typename TMaterialType<Core>::Type MaterialPtrType;
 		typedef typename TMaterialParamsType<Core>::Type MaterialParamsType;
 		typedef typename TGpuBufferType<Core>::Type BufferType;
 
 	public:
-		TMaterialParamBuffer(const String& name, const SPtr<MaterialParamsType>& params);
+		TMaterialParamBuffer(const String& name, const MaterialPtrType& material);
 		TMaterialParamBuffer() { }
 
 		/** @copydoc GpuParamBuffer::set */
@@ -168,23 +180,24 @@ namespace BansheeEngine
 		/** Checks if param is initialized. */
 		bool operator==(const nullptr_t& nullval) const
 		{
-			return mMaterialParams == nullptr;
+			return mMaterial == nullptr;
 		}
 
 	protected:
 		UINT32 mParamIndex;
-		SPtr<MaterialParamsType> mMaterialParams;
+		MaterialPtrType mMaterial;
 	};
 
 	/** @copydoc TMaterialDataParam */
 	template<bool Core>
 	class BS_CORE_EXPORT TMaterialParamSampState
 	{
+		typedef typename TMaterialType<Core>::Type MaterialPtrType;
 		typedef typename TMaterialParamsType<Core>::Type MaterialParamsType;
 		typedef typename TGpuParamSamplerStateType<Core>::Type SamplerStateType;
 
 	public:
-		TMaterialParamSampState(const String& name, const SPtr<MaterialParamsType>& params);
+		TMaterialParamSampState(const String& name, const MaterialPtrType& material);
 		TMaterialParamSampState() { }
 
 		/** @copydoc GpuParamSampState::set */
@@ -196,12 +209,12 @@ namespace BansheeEngine
 		/** Checks if param is initialized. */
 		bool operator==(const nullptr_t& nullval) const
 		{
-			return mMaterialParams == nullptr;
+			return mMaterial == nullptr;
 		}
 
 	protected:
 		UINT32 mParamIndex;
-		SPtr<MaterialParamsType> mMaterialParams;
+		MaterialPtrType mMaterial;
 	};
 
 	/** @} */

+ 24 - 3
Source/BansheeCore/Include/BsMaterialParams.h

@@ -43,7 +43,7 @@ namespace BansheeEngine
 			GpuParamDataType dataType;
 			UINT32 index;
 			UINT32 arraySize;
-			UINT32 dirtyFlags;
+			mutable UINT32 dirtyFlags;
 		};
 
 		/** 
@@ -113,9 +113,31 @@ namespace BansheeEngine
 			memcpy(&mDataParamsBuffer[param->index + arrayIdx * paramTypeSize], input, sizeof(paramTypeSize));
 		}
 
-		/** Returns an index of the parameter with the specified name. Returns -1 if parameter cannot be found. */
+		/** 
+		 * Returns an index of the parameter with the specified name. Index can be used in a call to getParamData(UINT32) to
+		 * get the actual parameter data.
+		 *
+		 * @param[in]	name		Name of the shader parameter.
+		 * @return					Index of the parameter, or -1 if not found.
+		 */
 		UINT32 getParamIndex(const String& name) const;
 
+		/** 
+		 * Returns an index of the parameter with the specified name. Index can be used in a call to getParamData(UINT32) to
+		 * get the actual parameter data.
+		 *
+		 * @param[in]	name		Name of the shader parameter.
+		 * @param[in]	type		Type of the parameter retrieve. Error will be logged if actual type of the parameter
+		 *							doesn't match.
+		 * @param[in]	dataType	Only relevant if the parameter is a data type. Determines exact data type of the parameter
+		 *							to retrieve.
+		 * @param[in]	arrayIdx	Array index of the entry to retrieve.
+		 * @param[out]	output		Index of the requested parameter, only valid if success is returned.
+		 * @return					Success or error state of the request.
+		 */
+		GetParamResult getParamIndex(const String& name, ParamType type, GpuParamDataType dataType, UINT32 arrayIdx,
+			UINT32& output) const;
+
 		/**
 		 * Returns data about a parameter and reports an error if there is a type or size mismatch, or if the parameter
 		 * does exist.
@@ -129,7 +151,6 @@ namespace BansheeEngine
 		 * @param[out]	output		Object describing the parameter with an index to its data. If the parameter was not found
 		 *							this value is undefined. This value will still be valid if parameter was found but
 		 *							some other error was reported.
-		 *
 		 * @return					Success or error state of the request.
 		 */
 		GetParamResult getParamData(const String& name, ParamType type, GpuParamDataType dataType, UINT32 arrayIdx,

+ 4 - 3
Source/BansheeCore/Source/BsGpuParamsSet.cpp

@@ -543,7 +543,7 @@ namespace BansheeEngine
 							UINT32 paramIdx = params->getParamIndex(dataParam.first);
 
 							// Parameter shouldn't be in the valid parameter list if it cannot be found
-							assert(paramIdx != (UINT32)-1);
+							assert(paramIdx != -1);
 
 							mDataParamInfos.push_back(DataParamInfo());
 							DataParamInfo& paramInfo = mDataParamInfos.back();
@@ -587,10 +587,11 @@ namespace BansheeEngine
 							if (validParams.count(param.first) == 0)
 								continue;
 
-							UINT32 paramIdx = params->getParamIndex(param.first);
+							UINT32 paramIdx;
+							auto result = params->getParamIndex(param.first, paramType, GPDT_UNKNOWN, 0, paramIdx);
 
 							// Parameter shouldn't be in the valid parameter list if it cannot be found
-							assert(paramIdx != (UINT32)-1);
+							assert(result == MaterialParams::GetParamResult::Success);
 
 							objParamInfos.push_back(ObjectParamInfo());
 							ObjectParamInfo& paramInfo = objParamInfos.back();

+ 16 - 6
Source/BansheeCore/Source/BsMaterial.cpp

@@ -33,6 +33,16 @@ namespace BansheeEngine
 	template<>
 	bool isShaderValid(const SPtr<ShaderCore>& shader) { return shader != nullptr; }
 
+	template<bool Core> struct TMatType { };
+	template<> struct TMatType<false> { typedef Material Type; };
+	template<> struct TMatType<true> { typedef MaterialCore Type; };
+
+	template<bool Core>
+	SPtr<typename TMatType<Core>::Type> getMaterialPtr(const TMaterial<Core>* material)
+	{
+		return std::static_pointer_cast<typename TMatType<Core>::Type>(static_cast<const typename TMatType<Core>::Type*>(material)->getThisPtr());
+	}
+
 	template<bool Core>
 	SPtr<typename TMaterial<Core>::GpuParamsSetType> TMaterial<Core>::createParamsSet(UINT32 techniqueIdx)
 	{
@@ -95,7 +105,7 @@ namespace BansheeEngine
 	{
 		throwIfNotInitialized();
 
-		return TMaterialParamStruct<Core>(name, mParams);
+		return TMaterialParamStruct<Core>(name, getMaterialPtr(this));
 	}
 
 	template<bool Core>
@@ -103,7 +113,7 @@ namespace BansheeEngine
 	{
 		throwIfNotInitialized();
 
-		return TMaterialParamTexture<Core>(name, mParams);
+		return TMaterialParamTexture<Core>(name, getMaterialPtr(this));
 	}
 
 	template<bool Core>
@@ -111,7 +121,7 @@ namespace BansheeEngine
 	{
 		throwIfNotInitialized();
 
-		return TMaterialParamLoadStoreTexture<Core>(name, mParams);
+		return TMaterialParamLoadStoreTexture<Core>(name, getMaterialPtr(this));
 	}
 
 	template<bool Core>
@@ -119,7 +129,7 @@ namespace BansheeEngine
 	{
 		throwIfNotInitialized();
 
-		return TMaterialParamBuffer<Core>(name, mParams);
+		return TMaterialParamBuffer<Core>(name, getMaterialPtr(this));
 	}
 
 	template<bool Core>
@@ -127,7 +137,7 @@ namespace BansheeEngine
 	{
 		throwIfNotInitialized();
 
-		return TMaterialParamSampState<Core>(name, mParams);
+		return TMaterialParamSampState<Core>(name, getMaterialPtr(this));
 	}
 
 	template<bool Core>
@@ -280,7 +290,7 @@ namespace BansheeEngine
 	{
 		throwIfNotInitialized();
 
-		output = TMaterialDataParam<T, Core>(name, mParams);
+		output = TMaterialDataParam<T, Core>(name, getMaterialPtr(this));
 	}
 
 	template<bool Core>

+ 139 - 70
Source/BansheeCore/Source/BsMaterialParam.cpp

@@ -4,23 +4,28 @@
 #include "BsVector2I.h"
 #include "BsVectorNI.h"
 #include "BsMaterialParams.h"
+#include "BsMaterial.h"
 
 namespace BansheeEngine
 {
 	template<class T, bool Core>
-	TMaterialDataParam<T, Core>::TMaterialDataParam(const String& name, const SPtr<MaterialParamsType>& params)
-		:mParamIndex(0), mArraySize(0), mMaterialParams(nullptr)
+	TMaterialDataParam<T, Core>::TMaterialDataParam(const String& name, const MaterialPtrType& material)
+		:mParamIndex(0), mArraySize(0), mMaterial(nullptr)
 	{
-		if(params != nullptr)
+		if(material != nullptr)
 		{
-			const MaterialParams::ParamData* data = nullptr;
-			auto result = params->getParamData(name, MaterialParams::ParamType::Data, 
-				(GpuParamDataType)TGpuDataParamInfo<T>::TypeId, 0, &data);
+			SPtr<MaterialParamsType> params = material->_getInternalParams();
+
+			UINT32 paramIndex;
+			auto result = params->getParamIndex(name, MaterialParams::ParamType::Data, 
+				(GpuParamDataType)TGpuDataParamInfo<T>::TypeId, 0, paramIndex);
 
 			if (result == MaterialParams::GetParamResult::Success)
 			{
-				mMaterialParams = params;
-				mParamIndex = data->index;
+				const MaterialParams::ParamData* data = params->getParamData(paramIndex);
+
+				mMaterial = material;
+				mParamIndex = paramIndex;
 				mArraySize = data->arraySize;
 			}
 			else
@@ -31,7 +36,7 @@ namespace BansheeEngine
 	template<class T, bool Core>
 	void TMaterialDataParam<T, Core>::set(const T& value, UINT32 arrayIdx) const
 	{
-		if (mMaterialParams == nullptr)
+		if (mMaterial == nullptr)
 			return;
 
 		if(arrayIdx >= mArraySize)
@@ -41,33 +46,45 @@ namespace BansheeEngine
 			return;
 		}
 
-		mMaterialParams->setDataParam(mParamIndex, arrayIdx, value);
+		SPtr<MaterialParamsType> params = mMaterial->_getInternalParams();
+		const MaterialParams::ParamData* data = params->getParamData(mParamIndex);
+		data->dirtyFlags = 0xFFFFFFFF;
+
+		params->setDataParam(data->index, arrayIdx, value);
+		mMaterial->_markCoreDirty();
 	}
 
 	template<class T, bool Core>
 	T TMaterialDataParam<T, Core>::get(UINT32 arrayIdx) const
 	{
 		T output = T();
-		if (mMaterialParams == nullptr || arrayIdx >= mArraySize)
+		if (mMaterial == nullptr || arrayIdx >= mArraySize)
 			return output;
 
-		mMaterialParams->getDataParam(mParamIndex, arrayIdx, output);
+		SPtr<MaterialParamsType> params = mMaterial->_getInternalParams();
+		const MaterialParams::ParamData* data = params->getParamData(mParamIndex);
+
+		params->getDataParam(data->index, arrayIdx, output);
 		return output;
 	}
 
 	template<bool Core>
-	TMaterialParamStruct<Core>::TMaterialParamStruct(const String& name, const SPtr<MaterialParamsType>& params)
-		:mParamIndex(0), mArraySize(0), mMaterialParams(nullptr)
+	TMaterialParamStruct<Core>::TMaterialParamStruct(const String& name, const MaterialPtrType& material)
+		:mParamIndex(0), mArraySize(0), mMaterial(nullptr)
 	{
-		if (params != nullptr)
+		if (material != nullptr)
 		{
-			const MaterialParams::ParamData* data = nullptr;
-			auto result = params->getParamData(name, MaterialParams::ParamType::Data, GPDT_STRUCT, 0, &data);
+			SPtr<MaterialParamsType> params = material->_getInternalParams();
+
+			UINT32 paramIndex;
+			auto result = params->getParamIndex(name, MaterialParams::ParamType::Data, GPDT_STRUCT, 0, paramIndex);
 
 			if (result == MaterialParams::GetParamResult::Success)
 			{
-				mMaterialParams = params;
-				mParamIndex = data->index;
+				const MaterialParams::ParamData* data = params->getParamData(paramIndex);
+
+				mMaterial = material;
+				mParamIndex = paramIndex;
 				mArraySize = data->arraySize;
 			}
 			else
@@ -78,7 +95,7 @@ namespace BansheeEngine
 	template<bool Core>
 	void TMaterialParamStruct<Core>::set(const void* value, UINT32 sizeBytes, UINT32 arrayIdx) const
 	{
-		if (mMaterialParams == nullptr)
+		if (mMaterial == nullptr)
 			return;
 
 		if (arrayIdx >= mArraySize)
@@ -88,37 +105,53 @@ namespace BansheeEngine
 			return;
 		}
 
-		mMaterialParams->setStructData(mParamIndex + arrayIdx, value, sizeBytes);
+		SPtr<MaterialParamsType> params = mMaterial->_getInternalParams();
+		const MaterialParams::ParamData* data = params->getParamData(mParamIndex);
+		data->dirtyFlags = 0xFFFFFFFF;
+
+		params->setStructData(data->index + arrayIdx, value, sizeBytes);
+		mMaterial->_markCoreDirty();
 	}
 
 	template<bool Core>
 	void TMaterialParamStruct<Core>::get(void* value, UINT32 sizeBytes, UINT32 arrayIdx) const
 	{
-		if (mMaterialParams == nullptr || arrayIdx >= mArraySize)
+		if (mMaterial == nullptr || arrayIdx >= mArraySize)
 			return;
 
-		mMaterialParams->getStructData(mParamIndex + arrayIdx, value, sizeBytes);
+		SPtr<MaterialParamsType> params = mMaterial->_getInternalParams();
+		const MaterialParams::ParamData* data = params->getParamData(mParamIndex);
+
+		params->getStructData(data->index + arrayIdx, value, sizeBytes);
 	}
 
 	template<bool Core>
 	UINT32 TMaterialParamStruct<Core>::getElementSize() const
 	{
-		return mMaterialParams->getStructSize(mParamIndex);
+		if (mMaterial == nullptr)
+			return 0;
+
+		SPtr<MaterialParamsType> params = mMaterial->_getInternalParams();
+		const MaterialParams::ParamData* data = params->getParamData(mParamIndex);
+
+		return params->getStructSize(data->index);
 	}
 
 	template<bool Core>
-	TMaterialParamTexture<Core>::TMaterialParamTexture(const String& name, const SPtr<MaterialParamsType>& params)
-		:mParamIndex(0), mMaterialParams(nullptr)
+	TMaterialParamTexture<Core>::TMaterialParamTexture(const String& name, const MaterialPtrType& material)
+		:mParamIndex(0), mMaterial(nullptr)
 	{
-		if (params != nullptr)
+		if (material != nullptr)
 		{
-			const MaterialParams::ParamData* data = nullptr;
-			auto result = params->getParamData(name, MaterialParams::ParamType::Texture, GPDT_UNKNOWN, 0, &data);
+			SPtr<MaterialParamsType> params = material->_getInternalParams();
+
+			UINT32 paramIndex;
+			auto result = params->getParamIndex(name, MaterialParams::ParamType::Texture, GPDT_UNKNOWN, 0, paramIndex);
 
 			if (result == MaterialParams::GetParamResult::Success)
 			{
-				mMaterialParams = params;
-				mParamIndex = data->index;
+				mMaterial = material;
+				mParamIndex = paramIndex;
 			}
 			else
 				params->reportGetParamError(result, name, 0);
@@ -128,43 +161,52 @@ namespace BansheeEngine
 	template<bool Core>
 	void TMaterialParamTexture<Core>::set(const TextureType& texture) const
 	{
-		if (mMaterialParams == nullptr)
+		if (mMaterial == nullptr)
 			return;
 
+		SPtr<MaterialParamsType> params = mMaterial->_getInternalParams();
+		const MaterialParams::ParamData* data = params->getParamData(mParamIndex);
+		data->dirtyFlags = 0xFFFFFFFF;
+
 		// If there is a default value, assign that instead of null
 		TextureType newValue = texture;
 		if (newValue == nullptr)
-			mMaterialParams->getDefaultTexture(mParamIndex, newValue);
+			params->getDefaultTexture(data->index, newValue);
 
-		mMaterialParams->setTexture(mParamIndex, newValue);
+		params->setTexture(data->index, newValue);
+		mMaterial->_markCoreDirty();
 	}
 
 	template<bool Core>
 	typename TMaterialParamTexture<Core>::TextureType TMaterialParamTexture<Core>::get() const
 	{
 		TextureType texture;
-		if (mMaterialParams == nullptr)
+		if (mMaterial == nullptr)
 			return texture;
 
-		mMaterialParams->getTexture(mParamIndex, texture);
+		SPtr<MaterialParamsType> params = mMaterial->_getInternalParams();
+		const MaterialParams::ParamData* data = params->getParamData(mParamIndex);
 
+		params->getTexture(data->index, texture);
 		return texture;
 	}
 	
 	template<bool Core>
 	TMaterialParamLoadStoreTexture<Core>::TMaterialParamLoadStoreTexture(const String& name, 
-		const SPtr<MaterialParamsType>& params)
-		:mParamIndex(0), mMaterialParams(nullptr)
+		const MaterialPtrType& material)
+		:mParamIndex(0), mMaterial(nullptr)
 	{
-		if (params != nullptr)
+		if (material != nullptr)
 		{
-			const MaterialParams::ParamData* data = nullptr;
-			auto result = params->getParamData(name, MaterialParams::ParamType::Texture, GPDT_UNKNOWN, 0, &data);
+			SPtr<MaterialParamsType> params = material->_getInternalParams();
+
+			UINT32 paramIndex;
+			auto result = params->getParamIndex(name, MaterialParams::ParamType::Texture, GPDT_UNKNOWN, 0, paramIndex);
 
 			if (result == MaterialParams::GetParamResult::Success)
 			{
-				mMaterialParams = params;
-				mParamIndex = data->index;
+				mMaterial = material;
+				mParamIndex = paramIndex;
 			}
 			else
 				params->reportGetParamError(result, name, 0);
@@ -174,38 +216,48 @@ namespace BansheeEngine
 	template<bool Core>
 	void TMaterialParamLoadStoreTexture<Core>::set(const TextureType& texture, const TextureSurface& surface) const
 	{
-		if (mMaterialParams == nullptr)
+		if (mMaterial == nullptr)
 			return;
 
-		mMaterialParams->setLoadStoreTexture(mParamIndex, texture, surface);
+		SPtr<MaterialParamsType> params = mMaterial->_getInternalParams();
+		const MaterialParams::ParamData* data = params->getParamData(mParamIndex);
+		data->dirtyFlags = 0xFFFFFFFF;
+
+		params->setLoadStoreTexture(data->index, texture, surface);
+		mMaterial->_markCoreDirty();
 	}
 
 	template<bool Core>
 	typename TMaterialParamLoadStoreTexture<Core>::TextureType TMaterialParamLoadStoreTexture<Core>::get() const
 	{
 		TextureType texture;
-		if (mMaterialParams == nullptr)
+		if (mMaterial == nullptr)
 			return texture;
 
 		TextureSurface surface;
-		mMaterialParams->getLoadStoreTexture(mParamIndex, texture, surface);
+
+		SPtr<MaterialParamsType> params = mMaterial->_getInternalParams();
+		const MaterialParams::ParamData* data = params->getParamData(mParamIndex);
+		params->getLoadStoreTexture(data->index, texture, surface);
 
 		return texture;
 	}
 	
 	template<bool Core>
-	TMaterialParamBuffer<Core>::TMaterialParamBuffer(const String& name, const SPtr<MaterialParamsType>& params)
-		:mParamIndex(0), mMaterialParams(nullptr)
+	TMaterialParamBuffer<Core>::TMaterialParamBuffer(const String& name, const MaterialPtrType& material)
+		:mParamIndex(0), mMaterial(nullptr)
 	{
-		if (params != nullptr)
+		if (material != nullptr)
 		{
-			const MaterialParams::ParamData* data = nullptr;
-			auto result = params->getParamData(name, MaterialParams::ParamType::Buffer, GPDT_UNKNOWN, 0, &data);
+			SPtr<MaterialParamsType> params = material->_getInternalParams();
+
+			UINT32 paramIndex;
+			auto result = params->getParamIndex(name, MaterialParams::ParamType::Buffer, GPDT_UNKNOWN, 0, paramIndex);
 
 			if (result == MaterialParams::GetParamResult::Success)
 			{
-				mMaterialParams = params;
-				mParamIndex = data->index;
+				mMaterial = material;
+				mParamIndex = paramIndex;
 			}
 			else
 				params->reportGetParamError(result, name, 0);
@@ -215,37 +267,46 @@ namespace BansheeEngine
 	template<bool Core>
 	void TMaterialParamBuffer<Core>::set(const BufferType& buffer) const
 	{
-		if (mMaterialParams == nullptr)
+		if (mMaterial == nullptr)
 			return;
 
-		mMaterialParams->setBuffer(mParamIndex, buffer);
+		SPtr<MaterialParamsType> params = mMaterial->_getInternalParams();
+		const MaterialParams::ParamData* data = params->getParamData(mParamIndex);
+		data->dirtyFlags = 0xFFFFFFFF;
+
+		params->setBuffer(data->index, buffer);
+		mMaterial->_markCoreDirty();
 	}
 
 	template<bool Core>
 	typename TMaterialParamBuffer<Core>::BufferType TMaterialParamBuffer<Core>::get() const
 	{
 		BufferType buffer;
-		if (mMaterialParams == nullptr)
+		if (mMaterial == nullptr)
 			return buffer;
 
-		mMaterialParams->getBuffer(mParamIndex, buffer);
+		SPtr<MaterialParamsType> params = mMaterial->_getInternalParams();
+		const MaterialParams::ParamData* data = params->getParamData(mParamIndex);
+		params->getBuffer(data->index, buffer);
 
 		return buffer;
 	}
 
 	template<bool Core>
-	TMaterialParamSampState<Core>::TMaterialParamSampState(const String& name, const SPtr<MaterialParamsType>& params)
-		:mParamIndex(0), mMaterialParams(nullptr)
+	TMaterialParamSampState<Core>::TMaterialParamSampState(const String& name, const MaterialPtrType& material)
+		:mParamIndex(0), mMaterial(nullptr)
 	{
-		if (params != nullptr)
+		if (material != nullptr)
 		{
-			const MaterialParams::ParamData* data = nullptr;
-			auto result = params->getParamData(name, MaterialParams::ParamType::Sampler, GPDT_UNKNOWN, 0, &data);
+			SPtr<MaterialParamsType> params = material->_getInternalParams();
+
+			UINT32 paramIndex;
+			auto result = params->getParamIndex(name, MaterialParams::ParamType::Sampler, GPDT_UNKNOWN, 0, paramIndex);
 
 			if (result == MaterialParams::GetParamResult::Success)
 			{
-				mMaterialParams = params;
-				mParamIndex = data->index;
+				mMaterial = material;
+				mParamIndex = paramIndex;
 			}
 			else
 				params->reportGetParamError(result, name, 0);
@@ -255,25 +316,33 @@ namespace BansheeEngine
 	template<bool Core>
 	void TMaterialParamSampState<Core>::set(const SamplerStateType& sampState) const
 	{
-		if (mMaterialParams == nullptr)
+		if (mMaterial == nullptr)
 			return;
 
+		SPtr<MaterialParamsType> params = mMaterial->_getInternalParams();
+		const MaterialParams::ParamData* data = params->getParamData(mParamIndex);
+		data->dirtyFlags = 0xFFFFFFFF;
+
 		// If there is a default value, assign that instead of null
 		SamplerStateType newValue = sampState;
 		if (newValue == nullptr)
-			mMaterialParams->getDefaultSamplerState(mParamIndex, newValue);
+			params->getDefaultSamplerState(data->index, newValue);
 
-		mMaterialParams->setSamplerState(mParamIndex, newValue);
+		params->setSamplerState(data->index, newValue);
+		mMaterial->_markCoreDirty();
 	}
 
 	template<bool Core>
 	typename TMaterialParamSampState<Core>::SamplerStateType TMaterialParamSampState<Core>::get() const
 	{
 		SamplerStateType samplerState;
-		if (mMaterialParams == nullptr)
+		if (mMaterial == nullptr)
 			return samplerState;
 
-		mMaterialParams->getSamplerState(mParamIndex, samplerState);
+		SPtr<MaterialParamsType> params = mMaterial->_getInternalParams();
+		const MaterialParams::ParamData* data = params->getParamData(mParamIndex);
+
+		params->getSamplerState(data->index, samplerState);
 		return samplerState;
 	}
 

+ 23 - 2
Source/BansheeCore/Source/BsMaterialParams.cpp

@@ -127,13 +127,34 @@ namespace BansheeEngine
 		return iterFind->second;
 	}
 
+	MaterialParamsBase::GetParamResult MaterialParamsBase::getParamIndex(const String& name, ParamType type,
+		GpuParamDataType dataType, UINT32 arrayIdx, UINT32& output) const
+	{
+		auto iterFind = mParamLookup.find(name);
+		if (iterFind == mParamLookup.end())
+			return GetParamResult::NotFound;
+
+		UINT32 index = iterFind->second;
+		const ParamData& param = mParams[index];
+		
+		if (param.type != type || (type == ParamType::Data && param.dataType != dataType))
+			return GetParamResult::InvalidType;
+
+		if (arrayIdx >= param.arraySize)
+			return GetParamResult::IndexOutOfBounds;
+
+		output = index;
+		return GetParamResult::Success;
+	}
+
 	MaterialParamsBase::GetParamResult MaterialParamsBase::getParamData(const String& name, ParamType type, 
 		GpuParamDataType dataType, UINT32 arrayIdx, const ParamData** output) const
 	{
-		UINT32 index = getParamIndex(name);
-		if(index == -1)
+		auto iterFind = mParamLookup.find(name);
+		if (iterFind == mParamLookup.end())
 			return GetParamResult::NotFound;
 
+		UINT32 index = iterFind->second;
 		const ParamData& param = mParams[index];
 		*output = &param;
 

+ 1 - 9
Source/BansheeEngine/Include/BsRenderable.h

@@ -22,14 +22,6 @@ namespace BansheeEngine
 		Everything = 0x02
 	};
 
-	template<bool Core> struct TMeshType {};
-	template<> struct TMeshType < false > { typedef HMesh Type; };
-	template<> struct TMeshType < true > { typedef SPtr<MeshCore> Type; };
-
-	template<bool Core> struct TMaterialType {};
-	template<> struct TMaterialType < false > { typedef HMaterial Type; };
-	template<> struct TMaterialType < true > { typedef SPtr<MaterialCore> Type; };
-
 	/**
 	 * Renderable represents any visible object in the scene. It has a mesh, bounds and a set of materials. Renderer will
 	 * render any Renderable objects visible by a camera.
@@ -38,7 +30,7 @@ namespace BansheeEngine
 	class BS_EXPORT TRenderable
 	{
 		typedef typename TMeshType<Core>::Type MeshType;
-		typedef typename TMaterialType<Core>::Type MaterialType;
+		typedef typename TMaterialPtrType<Core>::Type MaterialType;
 
 	public:
 		TRenderable();

+ 6 - 1
Source/RenderBeast/Source/BsSamplerOverrides.cpp

@@ -30,7 +30,12 @@ namespace BansheeEngine
 			auto& samplerParams = shader->getSamplerParams();
 			for(auto& samplerParam : samplerParams)
 			{
-				UINT32 paramIdx = params->getParamIndex(samplerParam.first);
+				UINT32 paramIdx;
+				auto result = params->getParamIndex(samplerParam.first, MaterialParams::ParamType::Sampler, GPDT_UNKNOWN, 
+					0, paramIdx);
+
+				// Parameter shouldn't be in the valid parameter list if it cannot be found
+				assert(result == MaterialParams::GetParamResult::Success);
 				const MaterialParamsBase::ParamData* materialParamData = params->getParamData(paramIdx);
 
 				UINT32 overrideIdx = (UINT32)overrides.size();