Просмотр исходного кода

More work on preparing documentation for doxygen generation

BearishSun 10 лет назад
Родитель
Сommit
8a20899902

+ 8 - 0
BansheeCore/Include/BsCorePrerequisites.h

@@ -20,6 +20,14 @@
  *	Functionality for dealing with input (mouse, keyboard, gamepad, etc.).
  */
 
+/** @defgroup Localization Localization
+ *	Functionality for dealing with GUI localization.
+ */
+
+/** @defgroup Material Material
+ *	Functionality for dealing with materials, shaders, and in general how objects are rendered.
+ */
+
 /** @} */
 
 #define BS_MAX_MULTIPLE_RENDER_TARGETS 8

+ 73 - 72
BansheeCore/Include/BsHString.h

@@ -1,73 +1,74 @@
-#pragma once
-
-namespace BansheeEngine
-{
-	/**
-	 * @brief	String handle. Provides a wrapper around an Unicode string, primarily
-	 * 			for localization purposes.
-	 * 			
-	 *			Actual value for this string is looked up in a global string table based
-	 *			on the provided identifier string and currently active language. If such value 
-	 *			doesn't exist then the identifier is used as is.
-	 *			
-	 *			Use {0}, {1}, etc. in the string value for values that might change dynamically.
-	 */
-	class BS_CORE_EXPORT HString
-	{
-	public:
-		/**
-		 * @brief	Creates a new localized string with the specified identifier. If the identifier
-		 * 			doesn't previously exist in the string table, identifier value will also be used 
-		 * 			for initializing the default language version of the string.
-		 *
-		 * @param	identifier		String you can use for later referencing the localized string.
-		 * @param	stringTableId	Unique identifier of the string table to retrieve the string from.
-		 */
-		explicit HString(const WString& identifier, UINT32 stringTableId = 0);
-
-		/**
-		 * @brief	Creates a new localized string with the specified identifier and sets the default language version
-		 *			of the string. If a string with that identifier already exists default language string will be updated.
-		 *
-		 * @param	identifier		String you can use for later referencing the localized string.
-		 * @param	default			Default string to assign to the specified identifier. Language to which it
-		 *							will be assigned depends on the StringTable::DEFAULT_LANGUAGE value.
-		 * @param	stringTableId	Unique identifier of the string table to retrieve the string from.
-		 */
-		explicit HString(const WString& identifier, const WString& default, UINT32 stringTableId = 0);
-
-		/**
-		 * @brief	Creates a new empty localized string.
-		 *
-		 * @param	stringTableId	Unique identifier of the string table to retrieve the string from.
-		 */
-		HString(UINT32 stringTableId = 0);
-		HString(const HString& copy);
-		~HString();
-
-		HString& operator=(const HString& rhs);
-
-		operator const WString& () const;
-		const WString& getValue() const;
-
-		/**
-		 * @brief	Sets a value of a string parameter. Parameters are specified as bracketed values
-		 * 			within the string itself (e.g. {0}, {1}) etc. Use ^ as an escape character.
-		 *
-		 * @note	Useful for strings that have dynamically changing values, like numbers, embedded in them.
-		 */
-		void setParameter(UINT32 idx, const WString& value);
-		
-		/**
-		 * @brief	Returns an empty string.
-		 */
-		static const HString& dummy();
-	private:
-		SPtr<LocalizedStringData> mStringData;
-		WString* mParameters;
-
-		mutable bool mIsDirty;
-		mutable WString mCachedString;
-		mutable WString* mStringPtr;
-	};
+#pragma once
+
+namespace BansheeEngine
+{
+	/** @addtogroup Localization
+	 *  @{
+	 */
+
+	/**
+	 * String handle. Provides a wrapper around an Unicode string, primarily for localization purposes.
+	 * 			
+	 * Actual value for this string is looked up in a global string table based on the provided identifier string and 
+	 * currently active language. If such value doesn't exist then the identifier is used as is.
+	 *			
+	 * Use {0}, {1}, etc. in the string value for values that might change dynamically.
+	 */
+	class BS_CORE_EXPORT HString
+	{
+	public:
+		/**
+		 * Creates a new localized string with the specified identifier. If the identifier doesn't previously exist in the 
+		 * string table, identifier value will also be used for initializing the default language version of the string.
+		 *
+		 * @param[in]	identifier		String you can use for later referencing the localized string.
+		 * @param[in]	stringTableId	Unique identifier of the string table to retrieve the string from.
+		 */
+		explicit HString(const WString& identifier, UINT32 stringTableId = 0);
+
+		/**
+		 * Creates a new localized string with the specified identifier and sets the default language version of the 
+		 * string. If a string with that identifier already exists default language string will be updated.
+		 *
+		 * @param[in]	identifier		String you can use for later referencing the localized string.
+		 * @param[in]	default			Default string to assign to the specified identifier. Language to which it will be 
+		 *								assigned depends on the StringTable::DEFAULT_LANGUAGE value.
+		 * @param[in]	stringTableId	Unique identifier of the string table to retrieve the string from.
+		 */
+		explicit HString(const WString& identifier, const WString& default, UINT32 stringTableId = 0);
+
+		/**
+		 * Creates a new empty localized string.
+		 *
+		 * @param[in]	stringTableId	Unique identifier of the string table to retrieve the string from.
+		 */
+		HString(UINT32 stringTableId = 0);
+		HString(const HString& copy);
+		~HString();
+
+		HString& operator=(const HString& rhs);
+
+		operator const WString& () const;
+		const WString& getValue() const;
+
+		/**
+		 * Sets a value of a string parameter. Parameters are specified as bracketed values within the string itself 
+		 * (e.g. {0}, {1}) etc. Use ^ as an escape character.
+		 *
+		 * @note	This is useful for strings that have dynamically changing values, like numbers, embedded in them.
+		 */
+		void setParameter(UINT32 idx, const WString& value);
+		
+		/** Returns an empty string. */
+		static const HString& dummy();
+	private:
+		SPtr<LocalizedStringData> mStringData;
+		WString* mParameters;
+
+		mutable bool mIsDirty;
+		mutable WString mCachedString;
+		mutable WString* mStringPtr;
+	};
+
+	/** @} */
 }

+ 663 - 750
BansheeCore/Include/BsMaterial.h

@@ -1,751 +1,664 @@
-#pragma once
-
-#include "BsCorePrerequisites.h"
-#include "BsResource.h"
-#include "BsIResourceListener.h"
-#include "BsMaterialParam.h"
-#include "BsVector2.h"
-#include "BsVector3.h"
-#include "BsVector4.h"
-#include "BsMatrix3.h"
-#include "BsMatrix4.h"
-
-namespace BansheeEngine
-{
-	/**
-	 * @brief	Helper class containing parameters for all types
-	 * 			of GPU programs used in a pass.
-	 */
-	template<bool Core>
-	class TPassParameters
-	{
-	public:
-		typedef typename TGpuParamsPtrType<Core>::Type GpuParamsType;
-
-		/**
-		 * @brief	Returns a set of GPU parameters based on an index.
-		 *
-		 * @note	Useful when needing to iterate over all sets of GPU parameters.
-		 */
-		GpuParamsType& getParamByIdx(UINT32 idx)
-		{
-			GpuParamsType* paramArray[] = { &mVertParams, &mFragParams, &mGeomParams, &mHullParams, &mDomainParams, &mComputeParams };
-
-			return *paramArray[idx];
-		}
-
-		/**
-		 * @brief	Sets GPU parameters based on an index.
-		 *
-		 * @note	Useful when needing to iterate over all sets of GPU parameters.
-		 */
-		void setParamByIdx(UINT32 idx, const GpuParamsType& params)
-		{
-			GpuParamsType* paramArray[] = { &mVertParams, &mFragParams, &mGeomParams, &mHullParams, &mDomainParams, &mComputeParams };
-
-			(*paramArray[idx]) = params;
-		}
-
-		GpuParamsType mVertParams;
-		GpuParamsType mFragParams;
-		GpuParamsType mGeomParams;
-		GpuParamsType mHullParams;
-		GpuParamsType mDomainParams;
-		GpuParamsType mComputeParams;
-	};
-
-	template<bool Core> struct TGpuParamBlockBufferPtrType { };
-	template<> struct TGpuParamBlockBufferPtrType<false> { typedef SPtr<GpuParamBlockBuffer> Type; };
-	template<> struct TGpuParamBlockBufferPtrType<true> { typedef SPtr<GpuParamBlockBufferCore> Type; };
-
-	template<bool Core> struct TGpuProgramType { };
-	template<> struct TGpuProgramType<false> { typedef GpuProgramPtr Type; };
-	template<> struct TGpuProgramType<true> { typedef SPtr<GpuProgramCore> Type; };
-
-	/**
-	 * @brief	Contains sim thread pass parameters for each shader stage.
-	 */
-	class BS_CORE_EXPORT PassParameters : public TPassParameters<false>
-	{
-	public:
-		static const UINT32 NUM_PARAMS;
-	};
-
-	/**
-	 * @brief	Contains core thread pass parameters for each shader stage.
-	 */
-	class BS_CORE_EXPORT PassParametersCore : public TPassParameters<true>
-	{
-	public:
-		static const UINT32 NUM_PARAMS;
-	};
-
-	/**
-	 * @brief	Material that controls how objects are rendered. It is represented by a shader and 
-	 *			parameters used to set up that shader. It provides a simple interface for manipulating the parameters.
-	 */
-	class BS_CORE_EXPORT MaterialBase
-	{
-	public:
-		/**
-		 * @brief	Data used to described a structure defined within a shader.
-		 */
-		struct StructData
-		{
-			StructData()
-				:size(0), data(nullptr)
-			{ }
-
-			StructData(UINT32 _size)
-				:size(_size)
-			{
-				data = std::shared_ptr<void>(bs_alloc(_size), &bs_free);
-			}
-
-			/**
-			 * @brief	Writes the specified data to the internal buffer. Caller
-			 * 			must ensure size of the provided buffer is correct.
-			 */
-			void write(void* _data)
-			{
-				memcpy(data.get(), _data, size);
-			}
-
-			std::shared_ptr<void> data;
-			UINT32 size;
-		};
-
-		virtual ~MaterialBase() { }
-
-	protected:
-		/**
-		 * @brief	Retrieves a list of all shader GPU parameters, and the GPU program variable names they map to.
-		 */
-		const Map<String, String>& getValidParamNames() const { return mValidParams; }
-
-		/**
-		 * @copydoc	CoreObject::markCoreDirty
-		 */
-		virtual void _markCoreDirty() { }
-
-		/**
-		 * @copydoc	CoreObject::markDependenciesDirty
-		 */
-		virtual void _markDependenciesDirty() { }
-
-		/**
-		 * @copydoc	IResourceListener::markResourcesDirty
-		 */
-		virtual void _markResourcesDirty() { }
-
-		/**
-		 * @brief	Returns all GPU parameter descriptions in the specified technique.
-		 */
-		static Vector<GpuParamDescPtr> getAllParamDescs(const SPtr<Technique>& technique);
-
-		/**
-		 * @brief	Returns all GPU parameter descriptions in the specified technique.
-		 */
-		static Vector<GpuParamDescPtr> getAllParamDescs(const SPtr<TechniqueCore>& technique);
-
-		Set<String> mValidShareableParamBlocks;
-		Map<String, String> mValidParams; // Also maps Shader param name -> gpu variable name
-	};
-
-	/**
-	 * @copydoc	MaterialBase
-	 */
-	template<bool Core>
-	class BS_CORE_EXPORT TMaterial : public MaterialBase
-	{
-	public:
-		template<bool Core> struct TPassType {};
-		template<> struct TPassType < false > { typedef SPtr<Pass> Type; };
-		template<> struct TPassType < true > { typedef SPtr<PassCore> Type; };
-
-		template<bool Core> struct TTechniqueType {};
-		template<> struct TTechniqueType < false > { typedef SPtr<Technique> Type; };
-		template<> struct TTechniqueType < true > { typedef SPtr<TechniqueCore> Type; };
-
-		template<bool Core> struct TShaderType {};
-		template<> struct TShaderType < false > { typedef HShader Type; };
-		template<> struct TShaderType < true > { typedef SPtr<ShaderCore> Type; };
-
-		template<bool Core> struct TGpuParamBlockBufferType {};
-		template<> struct TGpuParamBlockBufferType < false > { typedef GpuParamBlockBuffer Type; };
-		template<> struct TGpuParamBlockBufferType < true > { typedef GpuParamBlockBufferCore Type; };
-
-		template<bool Core> struct TPassParamsType {};
-		template<> struct TPassParamsType < false > { typedef PassParameters Type; };
-		template<> struct TPassParamsType < true > { typedef PassParametersCore Type; };
-
-		typedef typename TGpuParamsPtrType<Core>::Type GpuParamsType;
-		typedef typename TGpuParamTextureType<Core>::Type TextureType;
-		typedef typename TGpuParamSamplerStateType<Core>::Type SamplerStateType;
-		typedef typename TGpuParamBlockBufferPtrType<Core>::Type ParamBlockPtrType;
-		typedef typename TGpuParamBlockBufferType<Core>::Type ParamBlockType;
-		typedef typename TGpuProgramType<Core>::Type GpuProgramType;
-		typedef typename TPassType<Core>::Type PassType;
-		typedef typename TTechniqueType<Core>::Type TechniqueType;
-		typedef typename TShaderType<Core>::Type ShaderType;
-		typedef typename TPassParamsType<Core>::Type PassParamsType;
-
-		virtual ~TMaterial() { }
-
-		/**
-		 * @brief	Returns the currently active shader.
-		 */
-		ShaderType getShader() const { return mShader; }
-
-		/**
-		 * @brief	Returns the number of passes that are used
-		 * 			by the shader used in the material.
-		 */
-		UINT32 getNumPasses() const;
-
-		/**
-		 * @brief	Retrieves a specific shader pass.
-		 */
-		PassType getPass(UINT32 passIdx) const;
-
-		/**   
-		 *  @brief	Assigns a float value to the shader parameter with the specified name. 
-		 *
-		 *			Optionally if the parameter is an array you may provide an array index to assign the value to.
-		 */
-		void setFloat(const String& name, float value, UINT32 arrayIdx = 0)	{ return getParamFloat(name).set(value, arrayIdx); }
-
-		/**   
-		 *  @brief	Assigns a color to the shader parameter with the specified name. 
-		 *
-		 *			Optionally if the parameter is an array you may provide an array index to assign the value to.
-		 */
-		void setColor(const String& name, const Color& value, UINT32 arrayIdx = 0) { return getParamColor(name).set(value, arrayIdx); }
-
-		/**   
-		 *  @brief	Assigns a 2D vector to the shader parameter with the specified name. 
-		 *
-		 *			Optionally if the parameter is an array you may provide an array index to assign the value to.
-		 */
-		void setVec2(const String& name, const Vector2& value, UINT32 arrayIdx = 0)	{ return getParamVec2(name).set(value, arrayIdx); }
-
-		/**   
-		 *  @brief	Assigns a 3D vector to the shader parameter with the specified name. 
-		 *
-		 *			Optionally if the parameter is an array you may provide an array index to assign the value to.
-		 */
-		void setVec3(const String& name, const Vector3& value, UINT32 arrayIdx = 0)	{ return getParamVec3(name).set(value, arrayIdx); }
-
-		/**   
-		 *  @brief	Assigns a 4D vector to the shader parameter with the specified name. 
-		 *
-		 *			Optionally if the parameter is an array you may provide an array index to assign the value to.
-		 */
-		void setVec4(const String& name, const Vector4& value, UINT32 arrayIdx = 0)	{ return getParamVec4(name).set(value, arrayIdx); }
-
-		/**   
-		 *  @brief	Assigns a 3x3 matrix to the shader parameter with the specified name. 
-		 *
-		 *			Optionally if the parameter is an array you may provide an array index to assign the value to.
-		 */
-		void setMat3(const String& name, const Matrix3& value, UINT32 arrayIdx = 0)	{ return getParamMat3(name).set(value, arrayIdx); }
-
-		/**   
-		 *  @brief	Assigns a 4x4 matrix to the shader parameter with the specified name. 
-		 *
-		 *			Optionally if the parameter is an array you may provide an array index to assign the value to.
-		 */
-		void setMat4(const String& name, const Matrix4& value, UINT32 arrayIdx = 0)	{ return getParamMat4(name).set(value, arrayIdx); }
-
-		/**   
-		 *  @brief	Assigns a structure to the shader parameter with the specified name.
-		 *  		
-		 *			Structure is provided as a raw buffer and caller must ensure structure in buffer
-		 *			matches what the shader expects.
-		 *
-		 *			Optionally if the parameter is an array you may provide an array index to assign the value to.
-		 */
-		void setStructData(const String& name, void* value, UINT32 size, UINT32 arrayIdx = 0) { return getParamStruct(name).set(value, size, arrayIdx); }
-
-		/** @brief	Assigns a texture to the shader parameter with the specified name. */
-		void setTexture(const String& name, const TextureType& value) { return getParamTexture(name).set(value); }
-
-		/** 
-		 * @brief	Assigns a texture to be used for random load/store operations to the
-		 *			shader parameter with the specified name.
-		 */
-		void setLoadStoreTexture(const String& name, const TextureType& value, const TextureSurface& surface)
-		{ 
-			return getParamLoadStoreTexture(name).set(value, surface); 
-		}
-
-		/** @brief	Assigns a sampler state to the shader parameter with the specified name. */
-		void setSamplerState(const String& name, const SamplerStateType& value) { return getParamSamplerState(name).set(value); }
-
-		/**
-		 * @brief	Returns a float value assigned with the parameter with the specified name.
-		 *
-		 *			Optionally if the parameter is an array you may provide an array index you which to retrieve.
-		 */
-		float getFloat(const String& name, UINT32 arrayIdx = 0) const { return getParamFloat(name).get(arrayIdx); }
-
-		/**
-		 * @brief	Returns a color assigned with the parameter with the specified name.
-		 *
-		 *			Optionally if the parameter is an array you may provide an array index you which to retrieve.
-		 */
-		Color getColor(const String& name, UINT32 arrayIdx = 0) const { return getParamColor(name).get(arrayIdx); }
-
-		/**
-		 * @brief	Returns a 2D vector assigned with the parameter with the specified name.
-		 *
-		 *			Optionally if the parameter is an array you may provide an array index you which to retrieve.
-		 */
-		Vector2 getVec2(const String& name, UINT32 arrayIdx = 0) const { return getParamVec2(name).get(arrayIdx); }
-
-		/**
-		 * @brief	Returns a 3D vector assigned with the parameter with the specified name.
-		 *
-		 *			Optionally if the parameter is an array you may provide an array index you which to retrieve.
-		 */
-		Vector3 getVec3(const String& name, UINT32 arrayIdx = 0) const { return getParamVec3(name).get(arrayIdx); }
-
-		/**
-		 * @brief	Returns a 4D vector assigned with the parameter with the specified name.
-		 *
-		 *			Optionally if the parameter is an array you may provide an array index you which to retrieve.
-		 */
-		Vector4 getVec4(const String& name, UINT32 arrayIdx = 0) const { return getParamVec4(name).get(arrayIdx); }
-
-		/**
-		 * @brief	Returns a 3x3 matrix assigned with the parameter with the specified name.
-		 *
-		 *			Optionally if the parameter is an array you may provide an array index you which to retrieve.
-		 */
-		Matrix3 getMat3(const String& name, UINT32 arrayIdx = 0) const { return getParamMat3(name).get(arrayIdx); }
-
-		/**
-		 * @brief	Returns a 4x4 matrix assigned with the parameter with the specified name.
-		 *
-		 *			Optionally if the parameter is an array you may provide an array index you which to retrieve.
-		 */
-		Matrix4 getMat4(const String& name, UINT32 arrayIdx = 0) const { return getParamMat4(name).get(arrayIdx); }
-
-		/** @brief	Returns a texture assigned with the parameter with the specified name. */
-		TextureType getTexture(const String& name) const { return getParamTexture(name).get(); }
-
-		/** @brief	Returns a sampler state assigned with the parameter with the specified name. */
-		SamplerStateType getSamplerState(const String& name) const	{ return getParamSamplerState(name).get(); }
-
-		/**
-		 * @brief	Returns a buffer representing a structure assigned to the parameter with the specified name.
-		 *
-		 *			Optionally if the parameter is an array you may provide an array index you which to retrieve.
-		 */
-		MaterialBase::StructData getStructData(const String& name, UINT32 arrayIdx = 0) const
-		{
-			TMaterialParamStruct<Core> structParam = getParamStruct(name);
-
-			MaterialBase::StructData data(structParam.getElementSize());
-			structParam.get(data.data.get(), structParam.getElementSize(), arrayIdx);
-
-			return data;
-		}
-
-		/**
-		 * @brief	Returns a float GPU parameter. This parameter may be used for
-		 * 			more efficiently getting/setting GPU parameter values than calling
-		 * 			Material::get* / Material::set* methods. 
-		 *
-		 * @note	Expected behavior is that you would retrieve this parameter when
-		 * 			initially constructing the material, and then use it throughout material
-		 * 			lifetime to assign and retrieve parameter values.
-		 * 			
-		 *			If material shader changes this handle will be invalidated.
-		 */
-		TMaterialDataParam<float, Core> getParamFloat(const String& name) const
-		{
-			TMaterialDataParam<float, Core> gpuParam;
-			getParam(name, gpuParam);
-
-			return gpuParam;
-		}
-
-		/**
-		 * @brief	Returns a color GPU parameter. This parameter may be used for
-		 * 			more efficiently getting/setting GPU parameter values than calling
-		 * 			Material::get* / Material::set* methods. 
-		 *
-		 * @note	Expected behavior is that you would retrieve this parameter when
-		 * 			initially constructing the material, and then use it throughout material
-		 * 			lifetime to assign and retrieve parameter values.
-		 * 			
-		 *			If material shader changes this handle will be invalidated.
-		 */
-		TMaterialDataParam<Color, Core> getParamColor(const String& name) const
-		{
-			TMaterialDataParam<Color, Core> gpuParam;
-			getParam(name, gpuParam);
-
-			return gpuParam;
-		}
-
-		/**
-		 * @brief	Returns a 2D vector GPU parameter. This parameter may be used for
-		 * 			more efficiently getting/setting GPU parameter values than calling
-		 * 			Material::get* / Material::set* methods. 
-		 *
-		 * @note	Expected behavior is that you would retrieve this parameter when
-		 * 			initially constructing the material, and then use it throughout material
-		 * 			lifetime to assign and retrieve parameter values.
-		 * 			
-		 *			If material shader changes this handle will be invalidated.
-		 */
-		TMaterialDataParam<Vector2, Core> getParamVec2(const String& name) const
-		{
-			TMaterialDataParam<Vector2, Core> gpuParam;
-			getParam(name, gpuParam);
-
-			return gpuParam;
-		}
-
-		/**
-		 * @brief	Returns a 3D vector GPU parameter. This parameter may be used for
-		 * 			more efficiently getting/setting GPU parameter values than calling
-		 * 			Material::get* / Material::set* methods. 
-		 *
-		 * @note	Expected behavior is that you would retrieve this parameter when
-		 * 			initially constructing the material, and then use it throughout material
-		 * 			lifetime to assign and retrieve parameter values.
-		 * 			
-		 *			If material shader changes this handle will be invalidated.
-		 */
-		TMaterialDataParam<Vector3, Core> getParamVec3(const String& name) const
-		{
-			TMaterialDataParam<Vector3, Core> gpuParam;
-			getParam(name, gpuParam);
-
-			return gpuParam;
-		}
-
-		/**
-		 * @brief	Returns a 4D vector GPU parameter. This parameter may be used for
-		 * 			more efficiently getting/setting GPU parameter values than calling
-		 * 			Material::get* / Material::set* methods. 
-		 *
-		 * @note	Expected behavior is that you would retrieve this parameter when
-		 * 			initially constructing the material, and then use it throughout material
-		 * 			lifetime to assign and retrieve parameter values.
-		 * 			
-		 *			If material shader changes this handle will be invalidated.
-		 */
-		TMaterialDataParam<Vector4, Core> getParamVec4(const String& name) const
-		{
-			TMaterialDataParam<Vector4, Core> gpuParam;
-			getParam(name, gpuParam);
-
-			return gpuParam;
-		}
-
-		/**
-		 * @brief	Returns a 3x3 matrix GPU parameter. This parameter may be used for
-		 * 			more efficiently getting/setting GPU parameter values than calling
-		 * 			Material::get* / Material::set* methods. 
-		 *
-		 * @note	Expected behavior is that you would retrieve this parameter when
-		 * 			initially constructing the material, and then use it throughout material
-		 * 			lifetime to assign and retrieve parameter values.
-		 * 			
-		 *			If material shader changes this handle will be invalidated.
-		 */
-		TMaterialDataParam<Matrix3, Core> getParamMat3(const String& name) const
-		{
-			TMaterialDataParam<Matrix3, Core> gpuParam;
-			getParam(name, gpuParam);
-
-			return gpuParam;
-		}
-
-		/**
-		 * @brief	Returns a 4x4 matrix GPU parameter. This parameter may be used for
-		 * 			more efficiently getting/setting GPU parameter values than calling
-		 * 			Material::get* / Material::set* methods. 
-		 *
-		 * @note	Expected behavior is that you would retrieve this parameter when
-		 * 			initially constructing the material, and then use it throughout material
-		 * 			lifetime to assign and retrieve parameter values.
-		 * 			
-		 *			If material shader changes this handle will be invalidated.
-		 */
-		TMaterialDataParam<Matrix4, Core> getParamMat4(const String& name) const
-		{
-			TMaterialDataParam<Matrix4, Core> gpuParam;
-			getParam(name, gpuParam);
-
-			return gpuParam;
-		}
-
-		/**
-		 * @brief	Returns a structure GPU parameter. This parameter may be used for
-		 * 			more efficiently getting/setting GPU parameter values than calling
-		 * 			Material::get* / Material::set* methods. 
-		 *
-		 * @note	Expected behavior is that you would retrieve this parameter when
-		 * 			initially constructing the material, and then use it throughout material
-		 * 			lifetime to assign and retrieve parameter values.
-		 * 			
-		 *			If material shader changes this handle will be invalidated.
-		 */
-		TMaterialParamStruct<Core> getParamStruct(const String& name) const;
-
-		/**
-		 * @brief	Returns a texture GPU parameter. This parameter may be used for
-		 * 			more efficiently getting/setting GPU parameter values than calling
-		 * 			Material::get* / Material::set* methods. 
-		 *
-		 * @note	Expected behavior is that you would retrieve this parameter when
-		 * 			initially constructing the material, and then use it throughout material
-		 * 			lifetime to assign and retrieve parameter values.
-		 * 			
-		 *			If material shader changes this handle will be invalidated.
-		 */
-		TMaterialParamTexture<Core> getParamTexture(const String& name) const;
-
-		/**
-		 * @brief	Returns a GPU parameter for binding a load/store texture. This parameter 
-		 *			may be used for more efficiently getting/setting GPU parameter values 
-		 *			than calling Material::get* / Material::set* methods. 
-		 *
-		 * @note	Expected behavior is that you would retrieve this parameter when
-		 * 			initially constructing the material, and then use it throughout material
-		 * 			lifetime to assign and retrieve parameter values.
-		 * 			
-		 *			If material shader changes this handle will be invalidated.
-		 */
-		TMaterialParamLoadStoreTexture<Core> getParamLoadStoreTexture(const String& name) const;
-
-		/**
-		 * @brief	Returns a sampler state GPU parameter. This parameter may be used for
-		 * 			more efficiently getting/setting GPU parameter values than calling
-		 * 			Material::get* / Material::set* methods. 
-		 *
-		 * @note	Expected behavior is that you would retrieve this parameter when
-		 * 			initially constructing the material, and then use it throughout material
-		 * 			lifetime to assign and retrieve parameter values.
-		 * 			
-		 *			If material shader changes this handle will be invalidated.
-		 */
-		TMaterialParamSampState<Core> getParamSamplerState(const String& name) const;
-
-		/**
-		 * @brief	Returns a set of parameters for all GPU programs
-		 * 			in the specified shader pass.
-		 */
-		SPtr<PassParamsType> getPassParameters(UINT32 passIdx) const { return mParametersPerPass[passIdx]; }
-
-		/**
-		 * @brief	Assign a parameter block buffer with the specified name.
-		 *
-		 * @note	Parameter block buffers can be used as quick way of setting multiple parameters on a material at once, or
-		 * 			potentially sharing parameters between multiple materials. This reduces driver overhead as the parameters
-		 * 			in the buffers need only be set once and then reused multiple times.
-		 */
-		void setParamBlockBuffer(const String& name, const ParamBlockPtrType& paramBlock);
-
-	protected:
-		/**
-		 * @brief	Allows you to retrieve a handle to a parameter that you can then use for quickly
-		 * 			setting and retrieving parameter data. This allows you to set/get parameter data
-		 * 			without all the cost of extra lookups otherwise required.
-		 * 			
-		 * @note	All of these handles will be invalidated if material shader ever changes. It is up to the
-		 * 			caller to keep track of that.
-		 */
-		template <typename T>
-		void getParam(const String& name, TMaterialDataParam<T, Core>& output) const;
-
-		/**
-		 * @brief	Assigns a value from a raw buffer to the parameter with the specified name.
-		 *			Buffer must be of sizeof(T) * numElements size and initialized.
-		 *
-		 * @note	Provided parameter must exist, no checking is done.
-		 */
-		template <typename T>
-		void setParamValue(const String& name, UINT8* buffer, UINT32 numElements);
-
-		/**
-		 * @brief	Initializes the material by using the best technique from the currently set shader. Shader
-		 * 			must contain the technique that matches the current renderer and render system.
-		 */
-		void initBestTechnique();
-
-		/**
-		 * @brief	Assigns all the default parameters specified in the shader to the material.
-		 */
-		void initDefaultParameters();
-
-		/**
-		 * @brief	Throw an exception if no shader is set, or no acceptable
-		 * 			technique was found.
-		 */
-		void throwIfNotInitialized() const;
-
-		Vector<SPtr<PassParamsType>> mParametersPerPass;
-		ShaderType mShader;
-		TechniqueType mBestTechnique;
-	};
-
-	/**
-	 * @copydoc	MaterialBase
-	 */
-	class BS_CORE_EXPORT MaterialCore : public CoreObjectCore, public TMaterial<true>
-	{
-	public:
-		~MaterialCore() { }
-
-		/**
-		 * @copydoc	Material::setShader
-		 */
-		void setShader(const SPtr<ShaderCore>& shader);
-
-		/**
-		 * @brief	Creates a new material with the specified shader.
-		 */
-		static SPtr<MaterialCore> create(const SPtr<ShaderCore>& shader);
-
-	private:
-		friend class Material;
-
-		MaterialCore() { }
-		MaterialCore(const SPtr<ShaderCore>& shader);
-		MaterialCore(const SPtr<ShaderCore>& shader, const SPtr<TechniqueCore>& bestTechnique, 
-			const Set<String>& validShareableParamBlocks, const Map<String, String>& validParams, 
-			const Vector<SPtr<PassParametersCore>>& passParams);
-
-		/**
-		 * @copydoc	CoreObjectCore::syncToCore
-		 */
-		void syncToCore(const CoreSyncData& data) override;
-	};
-
-	/**
-	 * @copydoc	MaterialBase
-	 */
-	class BS_CORE_EXPORT Material : public Resource, public TMaterial<false>, public IResourceListener
-	{
-	public:
-		~Material() { }
-
-		/**
-		 * @brief	Sets a shader that will be used by the material. Best technique within the
-		 * 			provided shader will be used for the material.
-		 *
-		 * @note	Shader must be set before doing any other operations with the material.
-		 * 			
-		 * 			After setting the shader if change any systems that a shader technique is 
-		 * 			dependent upon (render system, renderer, etc), you will need to call this 
-		 * 			method again on all your Materials to make sure technique used is updated.
-		 */
-		void setShader(const HShader& shader);
-
-		/**
-		 * @brief	Retrieves an implementation of a material usable only from the
-		 *			core thread.
-		 */
-		SPtr<MaterialCore> getCore() const;
-
-		/**
-		 * @copydoc	CoreObject::initialize
-		 */
-		void initialize() override;
-
-		/**
-		 * @brief	Creates a deep copy of the material and returns the new object.
-		 */
-		HMaterial Material::clone();
-
-		/**
-		 * @brief	Creates a new empty material.
-		 * 			
-		 * @note	Make sure you call Material::setShader before using it.
-		 */
-		static HMaterial create();
-
-		/**
-		 * @brief	Creates a new material with the specified shader.
-		 */
-		static HMaterial create(const HShader& shader);
-
-	private:
-		friend class MaterialManager;
-
-		Material();
-		Material(const HShader& shader);
-
-		/**
-		 * @copydoc	CoreObject::createCore
-		 */
-		SPtr<CoreObjectCore> createCore() const override;
-
-		/**
-		 * @copydoc	CoreObject::syncToCore
-		 */
-		CoreSyncData syncToCore(FrameAlloc* allocator) override;
-
-		/**
-		 * @copydoc	CoreObject::getCoreDependencies
-		 */
-		void getCoreDependencies(Vector<CoreObject*>& dependencies) override;
-
-		/**
-		 * @copydoc	CoreObject::markCoreDirty
-		 */
-		void _markCoreDirty() override;
-
-		/**
-		 * @copydoc	CoreObject::markDependenciesDirty
-		 */
-		void _markDependenciesDirty() override;
-
-		/**
-		 * @copydoc	IResourceListener::markResourcesDirty
-		 */
-		void _markResourcesDirty() override;
-
-		/**
-		 * @copydoc	IResourceListener::getListenerResources
-		 */
-		void getListenerResources(Vector<HResource>& resources) override;
-
-		/**
-		 * @copydoc IResourceListener::notifyResourceLoaded
-		 */
-		void notifyResourceLoaded(const HResource& resource) override;
-
-		/**
-		 * @copydoc IResourceListener::notifyResourceChanged
-		 */
-		void notifyResourceChanged(const HResource& resource) override;
-
-		/**
-		 * @copydoc	Resource::getResourceDependencies
-		 */
-		void getResourceDependencies(FrameVector<HResource>& dependencies) const override;
-
-		/**
-		 * @brief	Performs material initialization when all resources are ready.
-		 */
-		void initializeIfLoaded();
-
-		UINT32 mLoadFlags;
-
-		/************************************************************************/
-		/* 								RTTI		                     		*/
-		/************************************************************************/
-		
-	public:
-		friend class MaterialRTTI;
-		static RTTITypeBase* getRTTIStatic();
-		virtual RTTITypeBase* getRTTI() const override;
-	};
+#pragma once
+
+#include "BsCorePrerequisites.h"
+#include "BsResource.h"
+#include "BsIResourceListener.h"
+#include "BsMaterialParam.h"
+#include "BsVector2.h"
+#include "BsVector3.h"
+#include "BsVector4.h"
+#include "BsMatrix3.h"
+#include "BsMatrix4.h"
+
+namespace BansheeEngine
+{
+	/** @addtogroup Material
+	 *  @{
+	 */
+
+	/** Helper class containing parameters for all types of GPU programs used in a pass. */
+	template<bool Core>
+	class TPassParameters
+	{
+	public:
+		typedef typename TGpuParamsPtrType<Core>::Type GpuParamsType;
+
+		/**
+		 * Returns a set of GPU parameters based on an index.
+		 *
+		 * @note	Useful when needing to iterate over all sets of GPU parameters.
+		 */
+		GpuParamsType& getParamByIdx(UINT32 idx)
+		{
+			GpuParamsType* paramArray[] = { &mVertParams, &mFragParams, &mGeomParams, &mHullParams, &mDomainParams, &mComputeParams };
+
+			return *paramArray[idx];
+		}
+
+		/**
+		 * Sets GPU parameters based on an index.
+		 *
+		 * @note	Useful when needing to iterate over all sets of GPU parameters.
+		 */
+		void setParamByIdx(UINT32 idx, const GpuParamsType& params)
+		{
+			GpuParamsType* paramArray[] = { &mVertParams, &mFragParams, &mGeomParams, &mHullParams, &mDomainParams, &mComputeParams };
+
+			(*paramArray[idx]) = params;
+		}
+
+		GpuParamsType mVertParams;
+		GpuParamsType mFragParams;
+		GpuParamsType mGeomParams;
+		GpuParamsType mHullParams;
+		GpuParamsType mDomainParams;
+		GpuParamsType mComputeParams;
+	};
+
+	template<bool Core> struct TGpuParamBlockBufferPtrType { };
+	template<> struct TGpuParamBlockBufferPtrType<false> { typedef SPtr<GpuParamBlockBuffer> Type; };
+	template<> struct TGpuParamBlockBufferPtrType<true> { typedef SPtr<GpuParamBlockBufferCore> Type; };
+
+	template<bool Core> struct TGpuProgramType { };
+	template<> struct TGpuProgramType<false> { typedef GpuProgramPtr Type; };
+	template<> struct TGpuProgramType<true> { typedef SPtr<GpuProgramCore> Type; };
+
+	/** Contains sim thread pass parameters for each shader stage. */
+	class BS_CORE_EXPORT PassParameters : public TPassParameters<false>
+	{
+	public:
+		static const UINT32 NUM_PARAMS;
+	};
+
+	/** Contains core thread pass parameters for each shader stage. */
+	class BS_CORE_EXPORT PassParametersCore : public TPassParameters<true>
+	{
+	public:
+		static const UINT32 NUM_PARAMS;
+	};
+
+	/**
+	 * Material that controls how objects are rendered. It is represented by a shader and parameters used to set up that
+	 * shader. It provides a simple interface for manipulating the parameters.
+	 */
+	class BS_CORE_EXPORT MaterialBase
+	{
+	public:
+		/** Data used to described a structure defined within a shader. */
+		struct StructData
+		{
+			StructData()
+				:size(0), data(nullptr)
+			{ }
+
+			StructData(UINT32 _size)
+				:size(_size)
+			{
+				data = std::shared_ptr<void>(bs_alloc(_size), &bs_free);
+			}
+
+			/**
+			 * Writes the specified data to the internal buffer. Caller must ensure size of the provided buffer is correct.
+			 */
+			void write(void* _data)
+			{
+				memcpy(data.get(), _data, size);
+			}
+
+			std::shared_ptr<void> data;
+			UINT32 size;
+		};
+
+		virtual ~MaterialBase() { }
+
+	protected:
+		/** Retrieves a list of all shader GPU parameters, and the GPU program variable names they map to. */
+		const Map<String, String>& getValidParamNames() const { return mValidParams; }
+
+		/** @copydoc CoreObject::markCoreDirty */
+		virtual void _markCoreDirty() { }
+
+		/** @copydoc CoreObject::markDependenciesDirty */
+		virtual void _markDependenciesDirty() { }
+
+		/** @copydoc IResourceListener::markResourcesDirty */
+		virtual void _markResourcesDirty() { }
+
+		/** Returns all GPU parameter descriptions in the specified technique. */
+		static Vector<GpuParamDescPtr> getAllParamDescs(const SPtr<Technique>& technique);
+
+		/** Returns all GPU parameter descriptions in the specified technique. */
+		static Vector<GpuParamDescPtr> getAllParamDescs(const SPtr<TechniqueCore>& technique);
+
+		Set<String> mValidShareableParamBlocks;
+		Map<String, String> mValidParams; // Also maps Shader param name -> gpu variable name
+	};
+
+	/** @copydoc MaterialBase */
+	template<bool Core>
+	class BS_CORE_EXPORT TMaterial : public MaterialBase
+	{
+	public:
+		template<bool Core> struct TPassType {};
+		template<> struct TPassType < false > { typedef SPtr<Pass> Type; };
+		template<> struct TPassType < true > { typedef SPtr<PassCore> Type; };
+
+		template<bool Core> struct TTechniqueType {};
+		template<> struct TTechniqueType < false > { typedef SPtr<Technique> Type; };
+		template<> struct TTechniqueType < true > { typedef SPtr<TechniqueCore> Type; };
+
+		template<bool Core> struct TShaderType {};
+		template<> struct TShaderType < false > { typedef HShader Type; };
+		template<> struct TShaderType < true > { typedef SPtr<ShaderCore> Type; };
+
+		template<bool Core> struct TGpuParamBlockBufferType {};
+		template<> struct TGpuParamBlockBufferType < false > { typedef GpuParamBlockBuffer Type; };
+		template<> struct TGpuParamBlockBufferType < true > { typedef GpuParamBlockBufferCore Type; };
+
+		template<bool Core> struct TPassParamsType {};
+		template<> struct TPassParamsType < false > { typedef PassParameters Type; };
+		template<> struct TPassParamsType < true > { typedef PassParametersCore Type; };
+
+		typedef typename TGpuParamsPtrType<Core>::Type GpuParamsType;
+		typedef typename TGpuParamTextureType<Core>::Type TextureType;
+		typedef typename TGpuParamSamplerStateType<Core>::Type SamplerStateType;
+		typedef typename TGpuParamBlockBufferPtrType<Core>::Type ParamBlockPtrType;
+		typedef typename TGpuParamBlockBufferType<Core>::Type ParamBlockType;
+		typedef typename TGpuProgramType<Core>::Type GpuProgramType;
+		typedef typename TPassType<Core>::Type PassType;
+		typedef typename TTechniqueType<Core>::Type TechniqueType;
+		typedef typename TShaderType<Core>::Type ShaderType;
+		typedef typename TPassParamsType<Core>::Type PassParamsType;
+
+		virtual ~TMaterial() { }
+
+		/** Returns the currently active shader. */
+		ShaderType getShader() const { return mShader; }
+
+		/** Returns the number of passes that are used by the shader used in the material. */
+		UINT32 getNumPasses() const;
+
+		/** Retrieves a specific shader pass. */
+		PassType getPass(UINT32 passIdx) const;
+
+		/**   
+		 * Assigns a float value to the shader parameter with the specified name. 
+		 *
+		 * Optionally if the parameter is an array you may provide an array index to assign the value to.
+		 */
+		void setFloat(const String& name, float value, UINT32 arrayIdx = 0)	{ return getParamFloat(name).set(value, arrayIdx); }
+
+		/**   
+		 * Assigns a color to the shader parameter with the specified name. 
+		 *
+		 * Optionally if the parameter is an array you may provide an array index to assign the value to.
+		 */
+		void setColor(const String& name, const Color& value, UINT32 arrayIdx = 0) { return getParamColor(name).set(value, arrayIdx); }
+
+		/**   
+		 * Assigns a 2D vector to the shader parameter with the specified name. 
+		 *
+		 * Optionally if the parameter is an array you may provide an array index to assign the value to.
+		 */
+		void setVec2(const String& name, const Vector2& value, UINT32 arrayIdx = 0)	{ return getParamVec2(name).set(value, arrayIdx); }
+
+		/**   
+		 * Assigns a 3D vector to the shader parameter with the specified name. 
+		 *
+		 * Optionally if the parameter is an array you may provide an array index to assign the value to.
+		 */
+		void setVec3(const String& name, const Vector3& value, UINT32 arrayIdx = 0)	{ return getParamVec3(name).set(value, arrayIdx); }
+
+		/**   
+		 * Assigns a 4D vector to the shader parameter with the specified name. 
+		 *
+		 * Optionally if the parameter is an array you may provide an array index to assign the value to.
+		 */
+		void setVec4(const String& name, const Vector4& value, UINT32 arrayIdx = 0)	{ return getParamVec4(name).set(value, arrayIdx); }
+
+		/**   
+		 * Assigns a 3x3 matrix to the shader parameter with the specified name. 
+		 *
+		 * Optionally if the parameter is an array you may provide an array index to assign the value to.
+		 */
+		void setMat3(const String& name, const Matrix3& value, UINT32 arrayIdx = 0)	{ return getParamMat3(name).set(value, arrayIdx); }
+
+		/**   
+		 * Assigns a 4x4 matrix to the shader parameter with the specified name. 
+		 *
+		 * Optionally if the parameter is an array you may provide an array index to assign the value to.
+		 */
+		void setMat4(const String& name, const Matrix4& value, UINT32 arrayIdx = 0)	{ return getParamMat4(name).set(value, arrayIdx); }
+
+		/**   
+		 * Assigns a structure to the shader parameter with the specified name.
+		 *  		
+		 * Structure is provided as a raw buffer and caller must ensure structure in buffer matches what the shader expects.
+		 *
+		 * Optionally if the parameter is an array you may provide an array index to assign the value to.
+		 */
+		void setStructData(const String& name, void* value, UINT32 size, UINT32 arrayIdx = 0) { return getParamStruct(name).set(value, size, arrayIdx); }
+
+		/** Assigns a texture to the shader parameter with the specified name. */
+		void setTexture(const String& name, const TextureType& value) { return getParamTexture(name).set(value); }
+
+		/** Assigns a texture to be used for random load/store operations to the shader parameter with the specified name. */
+		void setLoadStoreTexture(const String& name, const TextureType& value, const TextureSurface& surface)
+		{ 
+			return getParamLoadStoreTexture(name).set(value, surface); 
+		}
+
+		/** Assigns a sampler state to the shader parameter with the specified name. */
+		void setSamplerState(const String& name, const SamplerStateType& value) { return getParamSamplerState(name).set(value); }
+
+		/**
+		 * Returns a float value assigned with the parameter with the specified name.
+		 *
+		 * Optionally if the parameter is an array you may provide an array index you which to retrieve.
+		 */
+		float getFloat(const String& name, UINT32 arrayIdx = 0) const { return getParamFloat(name).get(arrayIdx); }
+
+		/**
+		 * Returns a color assigned with the parameter with the specified name.
+		 *
+		 * Optionally if the parameter is an array you may provide an array index you which to retrieve.
+		 */
+		Color getColor(const String& name, UINT32 arrayIdx = 0) const { return getParamColor(name).get(arrayIdx); }
+
+		/**
+		 * Returns a 2D vector assigned with the parameter with the specified name.
+		 *
+		 * Optionally if the parameter is an array you may provide an array index you which to retrieve.
+		 */
+		Vector2 getVec2(const String& name, UINT32 arrayIdx = 0) const { return getParamVec2(name).get(arrayIdx); }
+
+		/**
+		 * Returns a 3D vector assigned with the parameter with the specified name.
+		 *
+		 * Optionally if the parameter is an array you may provide an array index you which to retrieve.
+		 */
+		Vector3 getVec3(const String& name, UINT32 arrayIdx = 0) const { return getParamVec3(name).get(arrayIdx); }
+
+		/**
+		 * Returns a 4D vector assigned with the parameter with the specified name.
+		 *
+		 * Optionally if the parameter is an array you may provide an array index you which to retrieve.
+		 */
+		Vector4 getVec4(const String& name, UINT32 arrayIdx = 0) const { return getParamVec4(name).get(arrayIdx); }
+
+		/**
+		 * Returns a 3x3 matrix assigned with the parameter with the specified name.
+		 *
+		 * Optionally if the parameter is an array you may provide an array index you which to retrieve.
+		 */
+		Matrix3 getMat3(const String& name, UINT32 arrayIdx = 0) const { return getParamMat3(name).get(arrayIdx); }
+
+		/**
+		 * Returns a 4x4 matrix assigned with the parameter with the specified name.
+		 *
+		 * Optionally if the parameter is an array you may provide an array index you which to retrieve.
+		 */
+		Matrix4 getMat4(const String& name, UINT32 arrayIdx = 0) const { return getParamMat4(name).get(arrayIdx); }
+
+		/** Returns a texture assigned with the parameter with the specified name. */
+		TextureType getTexture(const String& name) const { return getParamTexture(name).get(); }
+
+		/** Returns a sampler state assigned with the parameter with the specified name. */
+		SamplerStateType getSamplerState(const String& name) const	{ return getParamSamplerState(name).get(); }
+
+		/**
+		 * Returns a buffer representing a structure assigned to the parameter with the specified name.
+		 *
+		 * Optionally if the parameter is an array you may provide an array index you which to retrieve.
+		 */
+		MaterialBase::StructData getStructData(const String& name, UINT32 arrayIdx = 0) const
+		{
+			TMaterialParamStruct<Core> structParam = getParamStruct(name);
+
+			MaterialBase::StructData data(structParam.getElementSize());
+			structParam.get(data.data.get(), structParam.getElementSize(), arrayIdx);
+
+			return data;
+		}
+
+		/**
+		 * Returns a float GPU parameter. This parameter may be used for more efficiently getting/setting GPU parameter 
+		 * values than calling Material::get* / Material::set* methods. 
+		 *
+		 * @note	
+		 * Expected behavior is that you would retrieve this parameter when initially constructing the material, and then 
+		 * use it throughout material lifetime to assign and retrieve parameter values.
+		 * @note			
+		 * If material shader changes this handle will be invalidated.
+		 */
+		TMaterialDataParam<float, Core> getParamFloat(const String& name) const
+		{
+			TMaterialDataParam<float, Core> gpuParam;
+			getParam(name, gpuParam);
+
+			return gpuParam;
+		}
+
+		/**
+		 * Returns a color GPU parameter. This parameter may be used for more efficiently getting/setting GPU parameter 
+		 * values than calling Material::get* / Material::set* methods. 
+		 *
+		 * @note	
+		 * Expected behavior is that you would retrieve this parameter when initially constructing the material, 
+		 * and then use it throughout material lifetime to assign and retrieve parameter values.
+		 * @note
+		 * If material shader changes this handle will be invalidated.
+		 */
+		TMaterialDataParam<Color, Core> getParamColor(const String& name) const
+		{
+			TMaterialDataParam<Color, Core> gpuParam;
+			getParam(name, gpuParam);
+
+			return gpuParam;
+		}
+
+		/**
+		 * Returns a 2D vector GPU parameter. This parameter may be used for more efficiently getting/setting GPU parameter 
+		 * values than calling Material::get* / Material::set* methods. 
+		 *
+		 * @note	
+		 * Expected behavior is that you would retrieve this parameter when initially constructing the material, and then 
+		 * use it throughout material lifetime to assign and retrieve parameter values.
+		 * @note	
+		 * If material shader changes this handle will be invalidated.
+		 */
+		TMaterialDataParam<Vector2, Core> getParamVec2(const String& name) const
+		{
+			TMaterialDataParam<Vector2, Core> gpuParam;
+			getParam(name, gpuParam);
+
+			return gpuParam;
+		}
+
+		/**
+		 * Returns a 3D vector GPU parameter. This parameter may be used for more efficiently getting/setting GPU parameter
+		 * values than calling Material::get* / Material::set* methods. 
+		 *
+		 * @note	
+		 * Expected behavior is that you would retrieve this parameter when initially constructing the material, and then
+		 * use it throughout material lifetime to assign and retrieve parameter values.
+		 * @note			
+		 * If material shader changes this handle will be invalidated.
+		 */
+		TMaterialDataParam<Vector3, Core> getParamVec3(const String& name) const
+		{
+			TMaterialDataParam<Vector3, Core> gpuParam;
+			getParam(name, gpuParam);
+
+			return gpuParam;
+		}
+
+		/**
+		 * Returns a 4D vector GPU parameter. This parameter may be used for more efficiently getting/setting GPU parameter
+		 * values than calling Material::get* / Material::set* methods. 
+		 *
+		 * @note	
+		 * Expected behavior is that you would retrieve this parameter when initially constructing the material, and then 
+		 * use it throughout material lifetime to assign and retrieve parameter values.
+		 * @note	
+		 * If material shader changes this handle will be invalidated.
+		 */
+		TMaterialDataParam<Vector4, Core> getParamVec4(const String& name) const
+		{
+			TMaterialDataParam<Vector4, Core> gpuParam;
+			getParam(name, gpuParam);
+
+			return gpuParam;
+		}
+
+		/**
+		 * Returns a 3x3 matrix GPU parameter. This parameter may be used for more efficiently getting/setting GPU 
+		 * parameter values than calling Material::get* / Material::set* methods. 
+		 *
+		 * @note	
+		 * Expected behavior is that you would retrieve this parameter when initially constructing the material, and then 
+		 * use it throughout material lifetime to assign and retrieve parameter values.
+		 * @note	
+		 * If material shader changes this handle will be invalidated.
+		 */
+		TMaterialDataParam<Matrix3, Core> getParamMat3(const String& name) const
+		{
+			TMaterialDataParam<Matrix3, Core> gpuParam;
+			getParam(name, gpuParam);
+
+			return gpuParam;
+		}
+
+		/**
+		 * Returns a 4x4 matrix GPU parameter. This parameter may be used for more efficiently getting/setting GPU parameter
+		 * values than calling Material::get* / Material::set* methods. 
+		 *
+		 * @note	
+		 * Expected behavior is that you would retrieve this parameter when initially constructing the material, and then 
+		 * use it throughout material lifetime to assign and retrieve parameter values.
+		 * @note	
+		 * If material shader changes this handle will be invalidated.
+		 */
+		TMaterialDataParam<Matrix4, Core> getParamMat4(const String& name) const
+		{
+			TMaterialDataParam<Matrix4, Core> gpuParam;
+			getParam(name, gpuParam);
+
+			return gpuParam;
+		}
+
+		/**
+		 * Returns a structure GPU parameter. This parameter may be used for more efficiently getting/setting GPU parameter
+		 * values than calling Material::get* / Material::set* methods. 
+		 *
+		 * @note	
+		 * Expected behavior is that you would retrieve this parameter when initially constructing the material, and then 
+		 * use it throughout material lifetime to assign and retrieve parameter values.
+		 * @note			
+		 * If material shader changes this handle will be invalidated.
+		 */
+		TMaterialParamStruct<Core> getParamStruct(const String& name) const;
+
+		/**
+		 * Returns a texture GPU parameter. This parameter may be used for more efficiently getting/setting GPU parameter 
+		 * values than calling Material::get* / Material::set* methods. 
+		 *
+		 * @note	
+		 * Expected behavior is that you would retrieve this parameter when initially constructing the material, and then 
+		 * use it throughout material lifetime to assign and retrieve parameter values.
+		 * @note
+		 * If material shader changes this handle will be invalidated.
+		 */
+		TMaterialParamTexture<Core> getParamTexture(const String& name) const;
+
+		/**
+		 * Returns a GPU parameter for binding a load/store texture. This parameter may be used for more efficiently 
+		 * getting/setting GPU parameter values than calling Material::get* / Material::set* methods. 
+		 *
+		 * @note	
+		 * Expected behavior is that you would retrieve this parameter when initially constructing the material, and then 
+		 * use it throughout material lifetime to assign and retrieve parameter values.
+		 * @note			
+		 * If material shader changes this handle will be invalidated.
+		 */
+		TMaterialParamLoadStoreTexture<Core> getParamLoadStoreTexture(const String& name) const;
+
+		/**
+		 * Returns a sampler state GPU parameter. This parameter may be used for more efficiently getting/setting GPU 
+		 * parameter values than calling Material::get* / Material::set* methods. 
+		 *
+		 * @note	
+		 * Expected behavior is that you would retrieve this parameter when initially constructing the material, and then 
+		 * use it throughout material lifetime to assign and retrieve parameter values.
+		 * @note			
+		 * If material shader changes this handle will be invalidated.
+		 */
+		TMaterialParamSampState<Core> getParamSamplerState(const String& name) const;
+
+		/** Returns a set of parameters for all GPU programs in the specified shader pass. */
+		SPtr<PassParamsType> getPassParameters(UINT32 passIdx) const { return mParametersPerPass[passIdx]; }
+
+		/**
+		 * Assign a parameter block buffer with the specified name.
+		 *
+		 * @note	
+		 * Parameter block buffers can be used as quick way of setting multiple parameters on a material at once, or
+		 * potentially sharing parameters between multiple materials. This reduces driver overhead as the parameters
+		 * in the buffers need only be set once and then reused multiple times.
+		 */
+		void setParamBlockBuffer(const String& name, const ParamBlockPtrType& paramBlock);
+
+	protected:
+		/**
+		 * Allows you to retrieve a handle to a parameter that you can then use for quickly setting and retrieving parameter
+		 * data. This allows you to set/get parameter data without all the cost of extra lookups otherwise required.
+		 * 			
+		 * @note	
+		 * All of these handles will be invalidated if material shader ever changes. It is up to the caller to keep track 
+		 * of that.
+		 */
+		template <typename T>
+		void getParam(const String& name, TMaterialDataParam<T, Core>& output) const;
+
+		/**
+		 * Assigns a value from a raw buffer to the parameter with the specified name. Buffer must be of sizeof(T) * 
+		 * numElements size and initialized.
+		 *
+		 * @note	Provided parameter must exist, no checking is done.
+		 */
+		template <typename T>
+		void setParamValue(const String& name, UINT8* buffer, UINT32 numElements);
+
+		/**
+		 * Initializes the material by using the best technique from the currently set shader. Shader must contain the 
+		 * technique that matches the current renderer and render system.
+		 */
+		void initBestTechnique();
+
+		/** Assigns all the default parameters specified in the shader to the material. */
+		void initDefaultParameters();
+
+		/** Throw an exception if no shader is set, or no acceptable technique was found. */
+		void throwIfNotInitialized() const;
+
+		Vector<SPtr<PassParamsType>> mParametersPerPass;
+		ShaderType mShader;
+		TechniqueType mBestTechnique;
+	};
+
+	/** @copydoc MaterialBase */
+	class BS_CORE_EXPORT MaterialCore : public CoreObjectCore, public TMaterial<true>
+	{
+	public:
+		~MaterialCore() { }
+
+		/** @copydoc Material::setShader */
+		void setShader(const SPtr<ShaderCore>& shader);
+
+		/** Creates a new material with the specified shader. */
+		static SPtr<MaterialCore> create(const SPtr<ShaderCore>& shader);
+
+	private:
+		friend class Material;
+
+		MaterialCore() { }
+		MaterialCore(const SPtr<ShaderCore>& shader);
+		MaterialCore(const SPtr<ShaderCore>& shader, const SPtr<TechniqueCore>& bestTechnique, 
+			const Set<String>& validShareableParamBlocks, const Map<String, String>& validParams, 
+			const Vector<SPtr<PassParametersCore>>& passParams);
+
+		/** @copydoc CoreObjectCore::syncToCore */
+		void syncToCore(const CoreSyncData& data) override;
+	};
+
+	/** @copydoc MaterialBase */
+	class BS_CORE_EXPORT Material : public Resource, public TMaterial<false>, public IResourceListener
+	{
+	public:
+		~Material() { }
+
+		/**
+		 * Sets a shader that will be used by the material. Best technique within the provided shader will be used for the 
+		 * material.
+		 *
+		 * @note	
+		 * Shader must be set before doing any other operations with the material.
+		 * @note			
+		 * After setting the shader if change any systems that a shader technique is dependent upon (render system, 
+		 * renderer, etc), you will need to call this method again on all your Materials to make sure technique used is 
+		 * updated.
+		 */
+		void setShader(const HShader& shader);
+
+		/** Retrieves an implementation of a material usable only from the core thread. */
+		SPtr<MaterialCore> getCore() const;
+
+		/** @copydoc CoreObject::initialize */
+		void initialize() override;
+
+		/** Creates a deep copy of the material and returns the new object. */
+		HMaterial Material::clone();
+
+		/**
+		 * Creates a new empty material.
+		 * 			
+		 * @note	Make sure you call Material::setShader before using it.
+		 */
+		static HMaterial create();
+
+		/** Creates a new material with the specified shader. */
+		static HMaterial create(const HShader& shader);
+
+	private:
+		friend class MaterialManager;
+
+		Material();
+		Material(const HShader& shader);
+
+		/** @copydoc CoreObject::createCore */
+		SPtr<CoreObjectCore> createCore() const override;
+
+		/** @copydoc CoreObject::syncToCore */
+		CoreSyncData syncToCore(FrameAlloc* allocator) override;
+
+		/** @copydoc CoreObject::getCoreDependencies */
+		void getCoreDependencies(Vector<CoreObject*>& dependencies) override;
+
+		/** @copydoc CoreObject::markCoreDirty */
+		void _markCoreDirty() override;
+
+		/** @copydoc CoreObject::markDependenciesDirty */
+		void _markDependenciesDirty() override;
+
+		/** @copydoc IResourceListener::markResourcesDirty */
+		void _markResourcesDirty() override;
+
+		/** @copydoc IResourceListener::getListenerResources */
+		void getListenerResources(Vector<HResource>& resources) override;
+
+		/** @copydoc IResourceListener::notifyResourceLoaded */
+		void notifyResourceLoaded(const HResource& resource) override;
+
+		/** @copydoc IResourceListener::notifyResourceChanged */
+		void notifyResourceChanged(const HResource& resource) override;
+
+		/** @copydoc Resource::getResourceDependencies */
+		void getResourceDependencies(FrameVector<HResource>& dependencies) const override;
+
+		/**	Performs material initialization when all resources are ready. */
+		void initializeIfLoaded();
+
+		UINT32 mLoadFlags;
+
+		/************************************************************************/
+		/* 								RTTI		                     		*/
+		/************************************************************************/
+		
+	public:
+		friend class MaterialRTTI;
+		static RTTITypeBase* getRTTIStatic();
+		virtual RTTITypeBase* getRTTI() const override;
+	};
+
+	/** @} */
 }

+ 36 - 32
BansheeCore/Include/BsMaterialManager.h

@@ -1,33 +1,37 @@
-#pragma once
-
-#include "BsCorePrerequisites.h"
-#include "BsModule.h"
-
-namespace BansheeEngine
-{
-	/**
-	 * @brief	Material manager handles material creation.
-	 */
-	class BS_CORE_EXPORT MaterialManager : public Module<MaterialManager>
-	{
-	public:
-		/**
-		 * @brief	Creates a new material without any assigned shader.
-		 *
-		 * @note	Make sure to call Material::setShader before using it.
-		 */
-		MaterialPtr create() const;
-
-		/**
-		 * @brief	Creates a new material with the specified shader.
-		 */
-		MaterialPtr create(const HShader& shader) const;
-
-		/**
-		 * @brief	Creates a new empty material without initializing it.
-		 *
-		 * @note	You must manually call initialize() after creation.
-		 */
-		MaterialPtr createEmpty() const;
-	};
+#pragma once
+
+#include "BsCorePrerequisites.h"
+#include "BsModule.h"
+
+namespace BansheeEngine
+{
+	/** @cond INTERNAL */
+	/** @addtogroup Material
+	 *  @{
+	 */
+
+	/**	Material manager handles material creation. */
+	class BS_CORE_EXPORT MaterialManager : public Module<MaterialManager>
+	{
+	public:
+		/**
+		 * Creates a new material without any assigned shader.
+		 *
+		 * @note	Make sure to call Material::setShader() before using it.
+		 */
+		MaterialPtr create() const;
+
+		/** Creates a new material with the specified shader. */
+		MaterialPtr create(const HShader& shader) const;
+
+		/**
+		 * Creates a new empty material without initializing it.
+		 *
+		 * @note	You must manually call Material::initialize() after creation.
+		 */
+		MaterialPtr createEmpty() const;
+	};
+
+	/** @} */
+	/** @endcond */
 }

+ 143 - 168
BansheeCore/Include/BsMaterialParam.h

@@ -1,169 +1,144 @@
-#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, bool Core>
-	class BS_CORE_EXPORT TMaterialDataParam
-	{
-	public:
-		TMaterialDataParam(const SPtr<Vector<TGpuDataParam<T, Core>>>& params);
-		TMaterialDataParam() { }
-		
-		/**
-		 * @copydoc	TGpuDataParam::set
-		 */
-		void set(const T& value, UINT32 arrayIdx = 0);
-
-		/**
-		 * @copydoc	TGpuDataParam::set
-		 */
-		T get(UINT32 arrayIdx = 0);
-
-	protected:
-		SPtr<Vector<TGpuDataParam<T, Core>>> mParams;
-	};
-
-	/**
-	 * @copydoc	TMaterialDataParam
-	 */
-	template<bool Core>
-	class BS_CORE_EXPORT TMaterialParamStruct
-	{
-	public:
-		TMaterialParamStruct(const SPtr<Vector<TGpuParamStruct<Core>>>& params);
-		TMaterialParamStruct() { }
-
-		/**
-		 * @copydoc	TGpuParamStruct::set
-		 */
-		void set(const void* value, UINT32 sizeBytes, UINT32 arrayIdx = 0);
-
-		/**
-		 * @copydoc	TGpuParamStruct::get
-		 */
-		void get(void* value, UINT32 sizeBytes, UINT32 arrayIdx = 0);
-
-		/**
-		 * @copydoc	TGpuParamStruct::getElementSize
-		 */
-		UINT32 getElementSize() const;
-
-	protected:
-		SPtr<Vector<TGpuParamStruct<Core>>> mParams;
-	};
-
-	/**
-	 * @copydoc	TMaterialDataParam
-	 */
-	template<bool Core>
-	class BS_CORE_EXPORT TMaterialParamTexture
-	{
-	public:
-		typedef typename TGpuParamTextureType<Core>::Type TextureType;
-
-		TMaterialParamTexture(const SPtr<Vector<TGpuParamTexture<Core>>>& params);
-		TMaterialParamTexture() { }
-
-		/**
-		 * @copydoc	GpuParamTexture::set
-		 */
-		void set(const TextureType& texture);
-
-		/**
-		 * @copydoc	GpuParamTexture::get
-		 */
-		TextureType get();
-
-	protected:
-		SPtr<Vector<TGpuParamTexture<Core>>> mParams;
-	};
-
-	/**
-	 * @copydoc	TMaterialDataParam
-	 */
-	template<bool Core>
-	class BS_CORE_EXPORT TMaterialParamLoadStoreTexture
-	{
-	public:
-		typedef typename TGpuParamTextureType<Core>::Type TextureType;
-
-		TMaterialParamLoadStoreTexture(const SPtr<Vector<TGpuParamLoadStoreTexture<Core>>>& params);
-		TMaterialParamLoadStoreTexture() { }
-
-		/**
-		 * @copydoc	GpuParamLoadStoreTexture::set
-		 */
-		void set(const TextureType& texture, const TextureSurface& surface);
-
-		/**
-		 * @copydoc	GpuParamLoadStoreTexture::get
-		 */
-		TextureType get();
-
-	protected:
-		SPtr<Vector<TGpuParamLoadStoreTexture<Core>>> mParams;
-	};
-
-	/**
-	 * @copydoc	TMaterialDataParam
-	 */
-	template<bool Core>
-	class BS_CORE_EXPORT TMaterialParamSampState
-	{
-	public:
-		typedef typename TGpuParamSamplerStateType<Core>::Type SamplerType;
-
-		TMaterialParamSampState(const SPtr<Vector<TGpuParamSampState<Core>>>& params);
-		TMaterialParamSampState() { }
-
-		/**
-		 * @copydoc	GpuParamSampState::set
-		 */
-		void set(const SamplerType& sampState);
-
-		/**
-		 * @copydoc	GpuParamSampState::get
-		 */
-		SamplerType get();
-
-	protected:
-		SPtr<Vector<TGpuParamSampState<Core>>> mParams;
-	};
-
-	typedef TMaterialDataParam<float, false> MaterialParamFloat;
-	typedef TMaterialDataParam<Color, false> MaterialParamColor;
-	typedef TMaterialDataParam<Vector2, false> MaterialParamVec2;
-	typedef TMaterialDataParam<Vector3, false> MaterialParamVec3;
-	typedef TMaterialDataParam<Vector4, false> MaterialParamVec4;
-	typedef TMaterialDataParam<Matrix3, false> MaterialParamMat3;
-	typedef TMaterialDataParam<Matrix4, false> MaterialParamMat4;
-
-	typedef TMaterialDataParam<float, true> MaterialParamFloatCore;
-	typedef TMaterialDataParam<Color, true> MaterialParamColorCore;
-	typedef TMaterialDataParam<Vector2, true> MaterialParamVec2Core;
-	typedef TMaterialDataParam<Vector3, true> MaterialParamVec3Core;
-	typedef TMaterialDataParam<Vector4, true> MaterialParamVec4Core;
-	typedef TMaterialDataParam<Matrix3, true> MaterialParamMat3Core;
-	typedef TMaterialDataParam<Matrix4, true> MaterialParamMat4Core;
-
-	typedef TMaterialParamStruct<false> MaterialParamStruct;
-	typedef TMaterialParamStruct<true> MaterialParamStructCore;
-
-	typedef TMaterialParamTexture<false> MaterialParamTexture;
-	typedef TMaterialParamTexture<true> MaterialParamTextureCore;
-
-	typedef TMaterialParamLoadStoreTexture<false> MaterialParamLoadStoreTexture;
-	typedef TMaterialParamLoadStoreTexture<true> MaterialParamLoadStoreTextureCore;
-
-	typedef TMaterialParamSampState<false> MaterialParamSampState;
-	typedef TMaterialParamSampState<true> MaterialParamSampStateCore;
+#pragma once
+
+#include "BsCorePrerequisites.h"
+#include "BsGpuParam.h"
+
+namespace BansheeEngine
+{
+	/** @addtogroup Material
+	 *  @{
+	 */
+
+	/**
+	 * A wrapper class that allows you to manage multiple GPU parameters at once.
+	 *
+	 * @see		TGpuDataParam
+	 */
+	template<class T, bool Core>
+	class BS_CORE_EXPORT TMaterialDataParam
+	{
+	public:
+		TMaterialDataParam(const SPtr<Vector<TGpuDataParam<T, Core>>>& params);
+		TMaterialDataParam() { }
+		
+		/** @copydoc TGpuDataParam::set */
+		void set(const T& value, UINT32 arrayIdx = 0);
+
+		/** @copydoc TGpuDataParam::set */
+		T get(UINT32 arrayIdx = 0);
+
+	protected:
+		SPtr<Vector<TGpuDataParam<T, Core>>> mParams;
+	};
+
+	/** @copydoc TMaterialDataParam */
+	template<bool Core>
+	class BS_CORE_EXPORT TMaterialParamStruct
+	{
+	public:
+		TMaterialParamStruct(const SPtr<Vector<TGpuParamStruct<Core>>>& params);
+		TMaterialParamStruct() { }
+
+		/** @copydoc TGpuParamStruct::set */
+		void set(const void* value, UINT32 sizeBytes, UINT32 arrayIdx = 0);
+
+		/** @copydoc TGpuParamStruct::get */
+		void get(void* value, UINT32 sizeBytes, UINT32 arrayIdx = 0);
+
+		/** @copydoc TGpuParamStruct::getElementSize */
+		UINT32 getElementSize() const;
+
+	protected:
+		SPtr<Vector<TGpuParamStruct<Core>>> mParams;
+	};
+
+	/** @copydoc TMaterialDataParam */
+	template<bool Core>
+	class BS_CORE_EXPORT TMaterialParamTexture
+	{
+	public:
+		typedef typename TGpuParamTextureType<Core>::Type TextureType;
+
+		TMaterialParamTexture(const SPtr<Vector<TGpuParamTexture<Core>>>& params);
+		TMaterialParamTexture() { }
+
+		/** @copydoc GpuParamTexture::set */
+		void set(const TextureType& texture);
+
+		/** @copydoc GpuParamTexture::get */
+		TextureType get();
+
+	protected:
+		SPtr<Vector<TGpuParamTexture<Core>>> mParams;
+	};
+
+	/** @copydoc TMaterialDataParam */
+	template<bool Core>
+	class BS_CORE_EXPORT TMaterialParamLoadStoreTexture
+	{
+	public:
+		typedef typename TGpuParamTextureType<Core>::Type TextureType;
+
+		TMaterialParamLoadStoreTexture(const SPtr<Vector<TGpuParamLoadStoreTexture<Core>>>& params);
+		TMaterialParamLoadStoreTexture() { }
+
+		/** @copydoc GpuParamLoadStoreTexture::set */
+		void set(const TextureType& texture, const TextureSurface& surface);
+
+		/** @copydoc GpuParamLoadStoreTexture::get */
+		TextureType get();
+
+	protected:
+		SPtr<Vector<TGpuParamLoadStoreTexture<Core>>> mParams;
+	};
+
+	/** @copydoc TMaterialDataParam */
+	template<bool Core>
+	class BS_CORE_EXPORT TMaterialParamSampState
+	{
+	public:
+		typedef typename TGpuParamSamplerStateType<Core>::Type SamplerType;
+
+		TMaterialParamSampState(const SPtr<Vector<TGpuParamSampState<Core>>>& params);
+		TMaterialParamSampState() { }
+
+		/** @copydoc GpuParamSampState::set */
+		void set(const SamplerType& sampState);
+
+		/** @copydoc GpuParamSampState::get */
+		SamplerType get();
+
+	protected:
+		SPtr<Vector<TGpuParamSampState<Core>>> mParams;
+	};
+
+	typedef TMaterialDataParam<float, false> MaterialParamFloat;
+	typedef TMaterialDataParam<Color, false> MaterialParamColor;
+	typedef TMaterialDataParam<Vector2, false> MaterialParamVec2;
+	typedef TMaterialDataParam<Vector3, false> MaterialParamVec3;
+	typedef TMaterialDataParam<Vector4, false> MaterialParamVec4;
+	typedef TMaterialDataParam<Matrix3, false> MaterialParamMat3;
+	typedef TMaterialDataParam<Matrix4, false> MaterialParamMat4;
+
+	typedef TMaterialDataParam<float, true> MaterialParamFloatCore;
+	typedef TMaterialDataParam<Color, true> MaterialParamColorCore;
+	typedef TMaterialDataParam<Vector2, true> MaterialParamVec2Core;
+	typedef TMaterialDataParam<Vector3, true> MaterialParamVec3Core;
+	typedef TMaterialDataParam<Vector4, true> MaterialParamVec4Core;
+	typedef TMaterialDataParam<Matrix3, true> MaterialParamMat3Core;
+	typedef TMaterialDataParam<Matrix4, true> MaterialParamMat4Core;
+
+	typedef TMaterialParamStruct<false> MaterialParamStruct;
+	typedef TMaterialParamStruct<true> MaterialParamStructCore;
+
+	typedef TMaterialParamTexture<false> MaterialParamTexture;
+	typedef TMaterialParamTexture<true> MaterialParamTextureCore;
+
+	typedef TMaterialParamLoadStoreTexture<false> MaterialParamLoadStoreTexture;
+	typedef TMaterialParamLoadStoreTexture<true> MaterialParamLoadStoreTextureCore;
+
+	typedef TMaterialParamSampState<false> MaterialParamSampState;
+	typedef TMaterialParamSampState<true> MaterialParamSampStateCore;
+
+	/** @} */
 }

+ 189 - 214
BansheeCore/Include/BsPass.h

@@ -1,215 +1,190 @@
-#pragma once
-
-#include "BsCorePrerequisites.h"
-#include "BsColor.h"
-#include "BsIReflectable.h"
-#include "BsCoreObject.h"
-
-namespace BansheeEngine
-{
-	/**
-	 * @brief	Descriptor structure used for initializing a shader pass.
-	 */
-	struct PASS_DESC
-	{
-		BlendStatePtr blendState;
-		RasterizerStatePtr rasterizerState;
-		DepthStencilStatePtr depthStencilState;
-		UINT32 stencilRefValue;
-
-		GpuProgramPtr vertexProgram;
-		GpuProgramPtr fragmentProgram;
-		GpuProgramPtr geometryProgram;
-		GpuProgramPtr hullProgram;
-		GpuProgramPtr domainProgram;
-		GpuProgramPtr computeProgram;
-	};
-
-	/**
-	 * @brief	Descriptor structure used for initializing a core thread
-	 *			variant of a shader pass.
-	 */
-	struct PASS_DESC_CORE
-	{
-		SPtr<BlendStateCore> blendState;
-		SPtr<RasterizerStateCore> rasterizerState;
-		SPtr<DepthStencilStateCore> depthStencilState;
-		UINT32 stencilRefValue;
-
-		SPtr<GpuProgramCore> vertexProgram;
-		SPtr<GpuProgramCore> fragmentProgram;
-		SPtr<GpuProgramCore> geometryProgram;
-		SPtr<GpuProgramCore> hullProgram;
-		SPtr<GpuProgramCore> domainProgram;
-		SPtr<GpuProgramCore> computeProgram;
-	};
-
-	/**
-	 * @brief	Contains all data used by a pass, templated
-	 *			so it may contain both core and sim thread data.
-	 */
-	template<bool Core>
-	struct TPassTypes
-	{ };
-
-	template<>
-	struct TPassTypes < false >
-	{
-		typedef BlendStatePtr BlendStateType;
-		typedef RasterizerStatePtr RasterizerStateType;
-		typedef DepthStencilStatePtr DepthStencilStateType;
-		typedef GpuProgramPtr GpuProgramType;
-		typedef PASS_DESC PassDescType;
-	};
-
-	template<>
-	struct TPassTypes < true >
-	{
-		typedef SPtr<BlendStateCore> BlendStateType;
-		typedef SPtr<RasterizerStateCore> RasterizerStateType;
-		typedef SPtr<DepthStencilStateCore> DepthStencilStateType;
-		typedef SPtr<GpuProgramCore> GpuProgramType;
-		typedef PASS_DESC_CORE PassDescType;
-	};
-
-	/**
-	 * @brief	Class defining a single pass of a technique (of a material), i.e.
-	 * 			a single rendering call.
-	 *
-	 *			Pass may contain multiple GPU programs (vertex, fragment, geometry, etc.), and
-	 *			a set of pipeline states (blend, rasterizer, etc.).
-	 *
-	 * @note	Templated so it can be used for both core and non-core versions of a pass.
-	 */
-	template<bool Core>
-	class BS_CORE_EXPORT TPass
-    {
-    public:
-		typedef typename TPassTypes<Core>::BlendStateType BlendStateType;
-		typedef typename TPassTypes<Core>::RasterizerStateType RasterizerStateType;
-		typedef typename TPassTypes<Core>::DepthStencilStateType DepthStencilStateType;
-		typedef typename TPassTypes<Core>::GpuProgramType GpuProgramType;
-		typedef typename TPassTypes<Core>::PassDescType PassDescType;
-
-		virtual ~TPass() { }
-
-        bool hasVertexProgram() const { return mData.vertexProgram != nullptr; }
-		bool hasFragmentProgram() const { return mData.fragmentProgram != nullptr; }
-		bool hasGeometryProgram() const { return mData.geometryProgram != nullptr; }
-		bool hasHullProgram() const { return mData.hullProgram != nullptr; }
-		bool hasDomainProgram() const { return mData.domainProgram != nullptr; }
-		bool hasComputeProgram() const { return mData.computeProgram != nullptr; }
-
-		/**
-		 * @brief	Returns true if this pass has some element of transparency.
-		 */
-		bool hasBlending() const;
-
-		BlendStateType getBlendState() const { return mData.blendState; }
-		RasterizerStateType getRasterizerState() const { return mData.rasterizerState; }
-		DepthStencilStateType getDepthStencilState() const { return mData.depthStencilState; }
-
-		/**
-		 * @brief	Gets the stencil reference value that is used when performing operations using the
-		 * 			stencil buffer.
-		 */
-		UINT32 getStencilRefValue() const { return mData.stencilRefValue; }
-
-		const GpuProgramType& getVertexProgram() const { return mData.vertexProgram; }
-		const GpuProgramType& getFragmentProgram() const { return mData.fragmentProgram; }
-		const GpuProgramType& getGeometryProgram() const { return mData.geometryProgram; }
-		const GpuProgramType& getHullProgram(void) const { return mData.hullProgram; }
-		const GpuProgramType& getDomainProgram(void) const { return mData.domainProgram; }
-		const GpuProgramType& getComputeProgram(void) const { return mData.computeProgram; }
-
-	protected:
-		TPass();
-		TPass(const PassDescType& desc);
-
-		PassDescType mData;
-    };
-
-	/**
-	 * @copydoc	PassBase
-	 *
-	 * @note	Core thread.
-	 */
-	class BS_CORE_EXPORT PassCore : public CoreObjectCore, public TPass<true>
-    {
-    public:
-		virtual ~PassCore() { }
-
-		/**
-		 * @brief	Creates a new empty pass.
-		 */
-		static SPtr<PassCore> create(const PASS_DESC_CORE& desc);
-
-	protected:
-		friend class Pass;
-		friend class TechniqueCore;
-
-		PassCore() { }
-		PassCore(const PASS_DESC_CORE& desc);
-
-		/**
-		 * @copydoc	CoreObjectCore::syncToCore
-		 */
-		void syncToCore(const CoreSyncData& data) override;
-    };
-
-	/**
-	 * @copydoc	PassBase
-	 *
-	 * @note	Sim thread.
-	 */
-	class BS_CORE_EXPORT Pass : public IReflectable, public CoreObject, public TPass<false>
-    {
-    public:
-		virtual ~Pass() { }
-
-		/**
-		 * @brief	Retrieves an implementation of a pass usable only from the
-		 *			core thread.
-		 */
-		SPtr<PassCore> getCore() const;
-
-		/**
-		 * @brief	Creates a new empty pass.
-		 */
-		static PassPtr create(const PASS_DESC& desc);
-
-	protected:
-		friend class Technique;
-
-		Pass() { }
-		Pass(const PASS_DESC& desc);
-
-		/**
-		 * @copydoc	CoreObject::syncToCore
-		 */
-		CoreSyncData syncToCore(FrameAlloc* allocator) override;
-
-		/**
-		 * @copydoc	CoreObject::createCore
-		 */
-		SPtr<CoreObjectCore> createCore() const override;
-
-		/**
-		 * @copydoc	CoreObject::syncToCore
-		 */
-		void getCoreDependencies(Vector<CoreObject*>& dependencies) override;
-
-		/**
-		 * @brief	Creates a new empty pass but doesn't initialize it.
-		 */
-		static PassPtr createEmpty();
-
-		/************************************************************************/
-		/* 								RTTI		                     		*/
-		/************************************************************************/
-	public:
-		friend class PassRTTI;
-		static RTTITypeBase* getRTTIStatic();
-		virtual RTTITypeBase* getRTTI() const override;
-    };
+#pragma once
+
+#include "BsCorePrerequisites.h"
+#include "BsColor.h"
+#include "BsIReflectable.h"
+#include "BsCoreObject.h"
+
+namespace BansheeEngine
+{
+	/** @addtogroup Material
+	 *  @{
+	 */
+
+	/** Descriptor structure used for initializing a shader pass. */
+	struct PASS_DESC
+	{
+		BlendStatePtr blendState;
+		RasterizerStatePtr rasterizerState;
+		DepthStencilStatePtr depthStencilState;
+		UINT32 stencilRefValue;
+
+		GpuProgramPtr vertexProgram;
+		GpuProgramPtr fragmentProgram;
+		GpuProgramPtr geometryProgram;
+		GpuProgramPtr hullProgram;
+		GpuProgramPtr domainProgram;
+		GpuProgramPtr computeProgram;
+	};
+
+	/** Descriptor structure used for initializing a core thread variant of a shader pass. */
+	struct PASS_DESC_CORE
+	{
+		SPtr<BlendStateCore> blendState;
+		SPtr<RasterizerStateCore> rasterizerState;
+		SPtr<DepthStencilStateCore> depthStencilState;
+		UINT32 stencilRefValue;
+
+		SPtr<GpuProgramCore> vertexProgram;
+		SPtr<GpuProgramCore> fragmentProgram;
+		SPtr<GpuProgramCore> geometryProgram;
+		SPtr<GpuProgramCore> hullProgram;
+		SPtr<GpuProgramCore> domainProgram;
+		SPtr<GpuProgramCore> computeProgram;
+	};
+
+	/** Contains all data used by a pass, templated so it may contain both core and sim thread data. */
+	template<bool Core>
+	struct TPassTypes
+	{ };
+
+	template<>
+	struct TPassTypes < false >
+	{
+		typedef BlendStatePtr BlendStateType;
+		typedef RasterizerStatePtr RasterizerStateType;
+		typedef DepthStencilStatePtr DepthStencilStateType;
+		typedef GpuProgramPtr GpuProgramType;
+		typedef PASS_DESC PassDescType;
+	};
+
+	template<>
+	struct TPassTypes < true >
+	{
+		typedef SPtr<BlendStateCore> BlendStateType;
+		typedef SPtr<RasterizerStateCore> RasterizerStateType;
+		typedef SPtr<DepthStencilStateCore> DepthStencilStateType;
+		typedef SPtr<GpuProgramCore> GpuProgramType;
+		typedef PASS_DESC_CORE PassDescType;
+	};
+
+	/**
+	 * Class defining a single pass of a technique (of a material), i.e. a single rendering call.
+	 *
+	 * Pass may contain multiple GPU programs (vertex, fragment, geometry, etc.), and a set of pipeline states (blend, 
+	 * rasterizer, etc.).
+	 *
+	 * @note	Templated so it can be used for both core and non-core versions of a pass.
+	 */
+	template<bool Core>
+	class BS_CORE_EXPORT TPass
+    {
+    public:
+		typedef typename TPassTypes<Core>::BlendStateType BlendStateType;
+		typedef typename TPassTypes<Core>::RasterizerStateType RasterizerStateType;
+		typedef typename TPassTypes<Core>::DepthStencilStateType DepthStencilStateType;
+		typedef typename TPassTypes<Core>::GpuProgramType GpuProgramType;
+		typedef typename TPassTypes<Core>::PassDescType PassDescType;
+
+		virtual ~TPass() { }
+
+        bool hasVertexProgram() const { return mData.vertexProgram != nullptr; }
+		bool hasFragmentProgram() const { return mData.fragmentProgram != nullptr; }
+		bool hasGeometryProgram() const { return mData.geometryProgram != nullptr; }
+		bool hasHullProgram() const { return mData.hullProgram != nullptr; }
+		bool hasDomainProgram() const { return mData.domainProgram != nullptr; }
+		bool hasComputeProgram() const { return mData.computeProgram != nullptr; }
+
+		/**	Returns true if this pass has some element of transparency. */
+		bool hasBlending() const;
+
+		BlendStateType getBlendState() const { return mData.blendState; }
+		RasterizerStateType getRasterizerState() const { return mData.rasterizerState; }
+		DepthStencilStateType getDepthStencilState() const { return mData.depthStencilState; }
+
+		/** Gets the stencil reference value that is used when performing operations using the stencil buffer. */
+		UINT32 getStencilRefValue() const { return mData.stencilRefValue; }
+
+		const GpuProgramType& getVertexProgram() const { return mData.vertexProgram; }
+		const GpuProgramType& getFragmentProgram() const { return mData.fragmentProgram; }
+		const GpuProgramType& getGeometryProgram() const { return mData.geometryProgram; }
+		const GpuProgramType& getHullProgram(void) const { return mData.hullProgram; }
+		const GpuProgramType& getDomainProgram(void) const { return mData.domainProgram; }
+		const GpuProgramType& getComputeProgram(void) const { return mData.computeProgram; }
+
+	protected:
+		TPass();
+		TPass(const PassDescType& desc);
+
+		PassDescType mData;
+    };
+
+	/**
+	 * @copydoc	PassBase
+	 *
+	 * @note	Core thread.
+	 */
+	class BS_CORE_EXPORT PassCore : public CoreObjectCore, public TPass<true>
+    {
+    public:
+		virtual ~PassCore() { }
+
+		/**	Creates a new empty pass. */
+		static SPtr<PassCore> create(const PASS_DESC_CORE& desc);
+
+	protected:
+		friend class Pass;
+		friend class TechniqueCore;
+
+		PassCore() { }
+		PassCore(const PASS_DESC_CORE& desc);
+
+		/** @copydoc CoreObjectCore::syncToCore */
+		void syncToCore(const CoreSyncData& data) override;
+    };
+
+	/**
+	 * @copydoc	PassBase
+	 *
+	 * @note	Sim thread.
+	 */
+	class BS_CORE_EXPORT Pass : public IReflectable, public CoreObject, public TPass<false>
+    {
+    public:
+		virtual ~Pass() { }
+
+		/** Retrieves an implementation of a pass usable only from the core thread. */
+		SPtr<PassCore> getCore() const;
+
+		/**	Creates a new empty pass. */
+		static PassPtr create(const PASS_DESC& desc);
+
+	protected:
+		friend class Technique;
+
+		Pass() { }
+		Pass(const PASS_DESC& desc);
+
+		/** @copydoc CoreObject::syncToCore */
+		CoreSyncData syncToCore(FrameAlloc* allocator) override;
+
+		/** @copydoc CoreObject::createCore */
+		SPtr<CoreObjectCore> createCore() const override;
+
+		/** @copydoc CoreObject::syncToCore */
+		void getCoreDependencies(Vector<CoreObject*>& dependencies) override;
+
+		/**	Creates a new empty pass but doesn't initialize it. */
+		static PassPtr createEmpty();
+
+		/************************************************************************/
+		/* 								RTTI		                     		*/
+		/************************************************************************/
+	public:
+		friend class PassRTTI;
+		static RTTITypeBase* getRTTIStatic();
+		virtual RTTITypeBase* getRTTI() const override;
+    };
+
+	/** @} */
 }

+ 467 - 510
BansheeCore/Include/BsShader.h

@@ -1,511 +1,468 @@
-#pragma once
-
-#include "BsCorePrerequisites.h"
-#include "BsResource.h"
-#include "BsStringID.h"
-#include "BsResourceMetaData.h"
-
-namespace BansheeEngine
-{
-	/**
-	 * @brief Describes a single data (int, Vector2, etc.) shader parameter.
-	 *
-	 * @see	Shader::addParameter.
-	 */
-	struct SHADER_DATA_PARAM_DESC
-	{
-		String name;
-		String gpuVariableName;
-		GpuParamDataType type;
-		StringID rendererSemantic;
-		UINT32 arraySize;
-		UINT32 elementSize;
-		UINT32 defaultValueIdx;
-	};
-
-	/**
-	 * @brief Describes a single object (texture, sampler state, etc.) shader parameter.
-	 *
-	 * @see	Shader::addParameter.
-	 */
-	struct SHADER_OBJECT_PARAM_DESC
-	{
-		String name;
-		Vector<String> gpuVariableNames;
-		StringID rendererSemantic;
-		GpuParamObjectType type;
-		UINT32 defaultValueIdx;
-	};
-
-	/**
-	 * @brief Describes a shader parameter block.
-	 */
-	struct SHADER_PARAM_BLOCK_DESC
-	{
-		String name;
-		bool shared;
-		StringID rendererSemantic;
-		GpuParamBlockUsage usage;
-	};
-
-	/**
-	 * @brief Structure used for initializing a shader.
-	 */
-	template<bool Core>
-	struct BS_CORE_EXPORT TSHADER_DESC
-	{
-		template<bool Core> struct TTextureType {};
-		template<> struct TTextureType < false > { typedef HTexture Type; };
-		template<> struct TTextureType < true > { typedef SPtr<TextureCore> Type; };
-
-		template<bool Core> struct TSamplerStateType {};
-		template<> struct TSamplerStateType < false > { typedef SamplerStatePtr Type; };
-		template<> struct TSamplerStateType < true > { typedef SPtr<SamplerStateCore> Type; };
-
-		typedef typename TTextureType<Core>::Type TextureType;
-		typedef typename TSamplerStateType<Core>::Type SamplerStateType;
-
-		TSHADER_DESC();
-
-		/**
-		 * @brief	Registers a new data (int, Vector2, etc.) parameter you that you may then use 
-		 *			via Material by providing the parameter name. All parameters internally map to 
-		 *			variables defined in GPU programs.
-		 *
-		 * @param	name		   	 The name of the parameter. Name must be unique between all data and object parameters.
-		 * @param	gpuVariableName	 Name of the GPU variable in the GpuProgram that the parameter corresponds with.
-		 * @param	type		   	 The type of the parameter, must be the same as the type in GpuProgram.
-		 * @param	rendererSemantic (optional) Semantic that allows you to specify the use of this parameter in the renderer. The actual value of the semantic
-		 *							 depends on the current Renderer and its supported list of semantics. Elements with renderer semantics should not be updated
-		 *							 by the user, and will be updated by the renderer. These semantics will also be used to determine if a shader is compatible
-		 *							 with a specific renderer or not. Value of 0 signifies the parameter is not used by the renderer.
-		 * @param	arraySize	   	 (optional) If the parameter is an array, the number of elements in the array. Size of 1 means its not an array.
-		 * @param	elementSize	   	 (optional) Size of an individual element in the array, in bytes. You only need to set this if you are setting variable
-		 * 							 length parameters, like structs.
-		 * @param	defaultValue	 (optional) Pointer to the buffer containing the default value for this parameter (initial value that will be set
-		 *							 when a material is initialized with this shader). The provided buffer must be of the correct size (depending on the
-		 *							 element type and array size).
-		 *
-		 * @note	If multiple parameters are given with the same name but different types behavior is undefined.
-		 */
-		void addParameter(const String& name, const String& gpuVariableName, GpuParamDataType type, StringID rendererSemantic = StringID::NONE,
-			UINT32 arraySize = 1, UINT32 elementSize = 0, UINT8* defaultValue = nullptr);
-
-		/**
-		 * @brief	Registers a new object (texture, sampler state, etc.) parameter you that you may then use 
-		 *			via Material by providing the parameter name. All parameters internally map to variables defined in GPU programs.
-		 *			Multiple GPU variables may be mapped to a single parameter in which case the first variable actually found in the program
-		 *			will be used while others will be ignored.
-		 *
-		 * @param	name		   	The name of the parameter. Name must be unique between all data and object parameters.
-		 * @param	gpuVariableName	Name of the GPU variable in the GpuProgram that the parameter corresponds with.
-		 * @param	type		   	The type of the parameter, must be the same as the type in GpuProgram.
-		 * @param	rendererSemantic (optional) Semantic that allows you to specify the use of this parameter in the renderer. The actual value of the semantic
-		 *							 depends on the current Renderer and its supported list of semantics. Elements with renderer semantics should not be updated
-		 *							 by the user, and will be updated by the renderer. These semantics will also be used to determine if a shader is compatible
-		 *							 with a specific renderer or not. Value of 0 signifies the parameter is not used by the renderer.
-		 *
-		 * @note	If multiple parameters are given with the same name but different types behavior is undefined.
-		 *			You are allowed to call this method multiple times in order to map multiple GPU variable names to a single parameter, 
-		 *			but the default value (if any) will only be recognized on the first call. Mapping multiple GPU variables to a single parameter 
-		 *			is useful when you are defining a shader that supports techniques across different render systems where GPU variable names for 
-		 *			the same parameters might differ.
-		 */
-		void addParameter(const String& name, const String& gpuVariableName, GpuParamObjectType type, StringID rendererSemantic = StringID::NONE);
-
-		/**
-		 * @see	SHADER_DESC::addParameter(const String&, const String&, GpuParamObjectType, StringID)
-		 *
-		 * @note	Specialized version of addParameter that accepts a default sampler value that will be used for
-		 *			initializing the object parameter upon Material creation. Default sampler value is only valid
-		 *			if the object type is one of the sampler types.
-		 */
-		void addParameter(const String& name, const String& gpuVariableName, GpuParamObjectType type, 
-			const SamplerStateType& defaultValue, StringID rendererSemantic = StringID::NONE);
-
-		/**
-		 * @see	SHADER_DESC::addParameter(const String&, const String&, GpuParamObjectType, StringID)
-		 *
-		 * @note	Specialized version of addParameter that accepts a default texture value that will be used for
-		 *			initializing the object parameter upon Material creation. Default texture value is only valid
-		 *			if the object type is one of the texture types.
-		 */
-		void addParameter(const String& name, const String& gpuVariableName, GpuParamObjectType type, 
-			const TextureType& defaultValue, StringID rendererSemantic = StringID::NONE);
-
-		/**
-		 * @brief	Changes parameters of a parameter block with the specified name.
-		 *
-		 * @param	name	Name of the parameter block. This should correspond with the name specified in the GPU program code.
-		 * @param	shared	If parameter block is marked as shared it will not be automatically created by the Material. You will need
-		 *					to create it elsewhere and then assign it manually.
-		 * @param	usage	Specified how often do we plan on modifying the buffer, which determines how is the buffer internally stored
-		 *					for best performance.
-		 * @param	rendererSemantic (optional) Semantic that allows you to specify the use of this parameter block in the renderer. The actual value of the 
-		 *							 semantic depends on the current Renderer and its supported list of semantics. Elements with a renderer semantic
-		 *							 will not have their parameter block automatically created (similar to "shared" argument), but instead a Renderer will
-		 *							 create an assign it instead. Be aware that renderers have strict policies on what and how are parameters stored in the 
-		 *							 buffer and you will need to respect them. If you don't respect them your shader will be deemed incompatible and won't be used. 
-		 *							 Value of 0 signifies the parameter block is not used by the renderer.
-		 */
-		void setParamBlockAttribs(const String& name, bool shared, GpuParamBlockUsage usage, StringID rendererSemantic = StringID::NONE);
-
-		/**
-		 * @brief	sorting type to use when performing sort in the render queue. Default value is sort front to back
-		 *			which causes least overdraw and is preferable. Transparent objects need to be sorted back to front.
-		 *			You may also specify no sorting and the elements will be rendered in the order they were added to the
-		 *			render queue.
-		 */
-		QueueSortType queueSortType;
-
-		/**
-		 * @brief	Priority that allows you to control in what order are your shaders rendered.
-		 *			See "QueuePriority" for a list of initial values. Shaders with higher priority will be
-		 *			rendered before shaders with lower priority, and additionally render queue will only sort
-		 *			elements within the same priority group.
-		 *
-		 * @note	This is useful when you want all your opaque objects to be rendered before you start
-		 *			drawing your transparent ones. Or to render your overlays after everything else. Values
-		 *			provided in "QueuePriority" are just for general guidance and feel free to increase them
-		 *			or decrease them for finer tuning. (e.g. "QueuePriority::Opaque + 1").
-		 */
-		INT32 queuePriority;
-
-		/**
-		 * @brief	Enables or disables separable passes. When separable passes are disabled
-		 *			all shader passes will be executed in a sequence one after another. If it is disabled
-		 *			the renderer is free to mix and match passes from different objects to achieve best
-		 *			performance. (They will still be executed in sequence, but some other object may
-		 *			be rendered in-between passes)
-		 *
-		 * @note	Shaders with transparency generally can't be separable, while opaque can.
-		 */
-		bool separablePasses;
-
-		/**
-		 * @brief	Flags that let the renderer know how should it interpret the shader.
-		 */
-		UINT32 flags;
-
-		Map<String, SHADER_DATA_PARAM_DESC> dataParams;
-		Map<String, SHADER_OBJECT_PARAM_DESC> textureParams;
-		Map<String, SHADER_OBJECT_PARAM_DESC> bufferParams;
-		Map<String, SHADER_OBJECT_PARAM_DESC> samplerParams;
-		Map<String, SHADER_PARAM_BLOCK_DESC> paramBlocks;
-
-		Vector<UINT8> dataDefaultValues;
-		Vector<SamplerStateType> samplerDefaultValues;
-		Vector<TextureType> textureDefaultValues;
-
-	private:
-		/**
-		 * @copydoc	addParameter(const String&, const String&, GpuParamObjectType, StringID)
-		 *
-		 * @note	Common method shared by different addParameter overloads.
-		 */
-		void addParameterInternal(const String& name, const String& gpuVariableName, GpuParamObjectType type, StringID rendererSemantic, UINT32 defaultValueIdx);
-	};
-
-	typedef TSHADER_DESC<true> SHADER_DESC_CORE;
-	typedef TSHADER_DESC<false> SHADER_DESC;
-
-	/**
-	 * @brief	Shader represents a collection of techniques. They are used in Materials,
-	 * 			which can be considered as instances of a Shader. Multiple materials
-	 * 			may share the same shader but provide different parameters to it.
-	 *
-	 *			Shader will always choose the first supported technique based on the current render
-	 *			system, render manager and other properties. So make sure to add most important techniques
-	 *			first so you make sure they are used if they are supported.
-	 *
-	 * @note	Templated version of Shader used for implementing both 
-	 *			sim and core thread variants.
-	 */
-	template<bool Core>
-	class BS_CORE_EXPORT TShader
-	{
-	public:
-		template<bool Core> struct TTechniqueType {};
-		template<> struct TTechniqueType < false > { typedef Technique Type; };
-		template<> struct TTechniqueType < true > { typedef TechniqueCore Type; };
-
-		typedef typename TTechniqueType<Core>::Type TechniqueType;
-		typedef typename TSHADER_DESC<Core>::TextureType TextureType;
-		typedef typename TSHADER_DESC<Core>::SamplerStateType SamplerStateType;
-
-		TShader() { }
-		TShader(const String& name, const TSHADER_DESC<Core>& desc, const Vector<SPtr<TechniqueType>>& techniques, UINT32 id);
-		virtual ~TShader();
-	
-		/**
-		 * @brief	Returns the total number of techniques in this shader.
-		 */
-		UINT32 getNumTechniques() const { return (UINT32)mTechniques.size(); }
-
-		/**
-		 * @brief	Gets the best supported technique based on current render and other systems.
-		 * 			Returns null if not a single technique is supported.
-		 */
-		SPtr<TechniqueType> getBestTechnique() const;
-
-		/**
-		 * @brief	Returns currently active queue sort type.
-		 *
-		 * @see		SHADER_DESC::queueSortType
-		 */
-		QueueSortType getQueueSortType() const { return mDesc.queueSortType; }
-
-		/**
-		 * @brief	Returns currently active queue priority.
-		 *
-		 * @see		SHADER_DESC::queuePriority
-		 */
-		INT32 getQueuePriority() const { return mDesc.queuePriority; }
-
-		/**
-		 * @brief	Returns if separable passes are allowed.
-		 *
-		 * @see		SHADER_DESC::separablePasses
-		 */
-		bool getAllowSeparablePasses() const { return mDesc.separablePasses; }
-
-		/**
-		 * @brief	Returns flags that control how the renderer interprets the shader.
-		 *			Actual interpretation of the flags depends on the active renderer.
-		 */
-		UINT32 getFlags() const { return mDesc.flags; }
-
-		/**
-		 * @brief	Returns type of the parameter with the specified name. Throws exception if
-		 *			the parameter doesn't exist.
-		 */
-		GpuParamType getParamType(const String& name) const;
-
-		/**
-		 * @brief	Returns description for a data parameter with the specified name. Throws exception if
-		 *			the parameter doesn't exist.
-		 */
-		const SHADER_DATA_PARAM_DESC& getDataParamDesc(const String& name) const;
-
-		/**
-		 * @brief	Returns description for a texture parameter with the specified name. Throws exception if
-		 *			the parameter doesn't exist.
-		 */
-		const SHADER_OBJECT_PARAM_DESC& getTextureParamDesc(const String& name) const;
-
-		/**
-		 * @brief	Returns description for a sampler parameter with the specified name. Throws exception if
-		 *			the parameter doesn't exist.
-		 */
-		const SHADER_OBJECT_PARAM_DESC& getSamplerParamDesc(const String& name) const;
-
-		/**
-		 * @brief	Returns description for a buffer parameter with the specified name. Throws exception if
-		 *			the parameter doesn't exist.
-		 */
-		const SHADER_OBJECT_PARAM_DESC& getBufferParamDesc(const String& name) const;
-
-		/** 
-		 * @brief	Checks if the parameter with the specified name exists, and is a data parameter.
-		 */
-		bool hasDataParam(const String& name) const;
-
-		/** 
-		 * @brief	Checks if the parameter with the specified name exists, and is a texture parameter.
-		 */
-		bool hasTextureParam(const String& name) const;
-
-		/** 
-		 * @brief	Checks if the parameter with the specified name exists, and is a sampler parameter.
-		 */
-		bool hasSamplerParam(const String& name) const;
-
-		/** 
-		 * @brief	Checks if the parameter with the specified name exists, and is a buffer parameter.
-		 */
-		bool hasBufferParam(const String& name) const;
-
-		/** 
-		 * @brief	Returns a map of all data parameters in the shader.
-		 */
-		const Map<String, SHADER_DATA_PARAM_DESC>& getDataParams() const { return mDesc.dataParams; }
-
-		/** 
-		 * @brief	Returns a map of all texture parameters in the shader. 
-		 */
-		const Map<String, SHADER_OBJECT_PARAM_DESC>& getTextureParams() const { return mDesc.textureParams; }
-
-		/**
-		 * @brief	Returns a map of all buffer parameters in the shader.
-		 */
-		const Map<String, SHADER_OBJECT_PARAM_DESC>& getBufferParams() const { return mDesc.bufferParams; }
-
-		/**
-		 * @brief	Returns a map of all sampler parameters in the shader.
-		 */
-		const Map<String, SHADER_OBJECT_PARAM_DESC>& getSamplerParams() const { return mDesc.samplerParams; }
-
-		/** 
-		 * @brief	Returns a map of all parameter blocks.
-		 */
-		const Map<String, SHADER_PARAM_BLOCK_DESC>& getParamBlocks() const { return mDesc.paramBlocks; }
-
-		/**
-		 * @brief	Returns a default texture for a parameter that has the specified
-		 *			default value index (retrieved from the parameters descriptor).
-		 */
-		TextureType getDefaultTexture(UINT32 index) const;
-
-		/**
-		 * @brief	Returns a default sampler state for a parameter that has the specified
-		 *			default value index (retrieved from the parameters descriptor).
-		 */
-		SamplerStateType getDefaultSampler(UINT32 index) const;
-
-		/**
-		 * @brief	Returns a pointer to the internal buffer containing the default 
-		 *			value for a data parameter that has the specified default value index 
-		 *			(retrieved from the parameters descriptor).
-		 */
-		UINT8* getDefaultValue(UINT32 index) const;
-
-		/**
-		 * @brief	Returns the unique shader ID.
-		 */
-		UINT32 getId() const { return mId; }
-
-	protected:
-		String mName;
-		TSHADER_DESC<Core> mDesc;
-		Vector<SPtr<TechniqueType>> mTechniques;
-		UINT32 mId;
-	};
-
-	/**
-	 * @copydoc	ShaderBase
-	 */
-	class BS_CORE_EXPORT ShaderCore : public CoreObjectCore, public TShader<true>
-	{
-	public:
-		/**
-		 * @copydoc	Shader::create
-		 */
-		static SPtr<ShaderCore> create(const String& name, const SHADER_DESC_CORE& desc, const Vector<SPtr<TechniqueCore>>& techniques);
-
-	protected:
-		friend class Shader;
-
-		ShaderCore(const String& name, const SHADER_DESC_CORE& desc, const Vector<SPtr<TechniqueCore>>& techniques, UINT32 id);
-
-		static std::atomic<UINT32> mNextShaderId;
-	};
-
-	/**
-	 * @copydoc	ShaderBase
-	 */
-	class BS_CORE_EXPORT Shader : public Resource, public TShader<false>
-	{
-	public:
-		/**
-		 * @brief	Retrieves an implementation of a shader usable only from the
-		 *			core thread.
-		 */
-		SPtr<ShaderCore> getCore() const;
-
-		/**
-		 * @brief	Sets a list include file paths that are referenced by this shader.
-		 *
-		 * @note	This is not used directly by the shader as includes are expected to be
-		 *			processed during GPU program and state creation, but it may be referenced 
-		 *			by higher layers for various purposes.
-		 */
-		void setIncludeFiles(const Vector<String>& includes);
-
-		/**
-		 * @brief	Checks is the provided object type a sampler.
-		 */
-		static bool isSampler(GpuParamObjectType type);
-
-		/**
-		 * @brief	Checks is the provided object type a texture.
-		 */
-		static bool isTexture(GpuParamObjectType type);
-
-		/**
-		 * @brief	Checks is the provided object type a buffer.
-		 */
-		static bool isBuffer(GpuParamObjectType type);
-
-		/**
-		 * @brief	Returns the size in bytes for a specific data type.
-		 *
-		 * @note	Returns 0 for variable size types like structures.
-		 */
-		static UINT32 getDataParamSize(GpuParamDataType type);
-
-		/**
-		 * @brief	Creates a new shader resource using the provided descriptor and techniques.
-		 */
-		static HShader create(const String& name, const SHADER_DESC& desc, const Vector<SPtr<Technique>>& techniques);
-
-		/**
-		 * @brief	Creates a new shader object using the provided descriptor and techniques.
-		 *
-		 * @note	Internal method.
-		 */
-		static ShaderPtr _createPtr(const String& name, const SHADER_DESC& desc, const Vector<SPtr<Technique>>& techniques);
-
-		/**
-		 * @brief	Returns a shader object but doesn't initialize it.
-		 */
-		static ShaderPtr createEmpty();
-
-	private:
-		Shader(const String& name, const SHADER_DESC& desc, const Vector<SPtr<Technique>>& techniques, UINT32 id);
-
-		/**
-		 * @copydoc	CoreObject::getCoreDependencies
-		 */
-		void getCoreDependencies(Vector<CoreObject*>& dependencies) override;
-
-		/**
-		 * @copydoc	CoreObject::createCore
-		 */
-		SPtr<CoreObjectCore> createCore() const override;
-
-		/**
-		 * @brief	Converts a sim thread version of the shader descriptor to
-		 *			a core thread version.
-		 */
-		SHADER_DESC_CORE convertDesc(const SHADER_DESC& desc) const;
-
-	private:
-		/************************************************************************/
-		/* 								RTTI		                     		*/
-		/************************************************************************/
-		Shader() { }
-
-	public:
-		friend class ShaderRTTI;
-		static RTTITypeBase* getRTTIStatic();
-		virtual RTTITypeBase* getRTTI() const override;
-	};
-
-	/**
-	 * @brief	Shader specific resource meta-data containing information
-	 *			about referenced include files.
-	 */
-	class BS_CORE_EXPORT ShaderMetaData : public ResourceMetaData
-	{
-	public:
-		Vector<String> includes;
-
-		/************************************************************************/
-		/* 								SERIALIZATION                      		*/
-		/************************************************************************/
-	public:
-		friend class ShaderMetaDataRTTI;
-		static RTTITypeBase* getRTTIStatic();
-		virtual RTTITypeBase* getRTTI() const override;
-	};
+#pragma once
+
+#include "BsCorePrerequisites.h"
+#include "BsResource.h"
+#include "BsStringID.h"
+#include "BsResourceMetaData.h"
+
+namespace BansheeEngine
+{
+	/** @addtogroup Material
+	 *  @{
+	 */
+
+	/**
+	 * Describes a single data (int, Vector2, etc.) shader parameter.
+	 *
+	 * @see	Shader::addParameter().
+	 */
+	struct SHADER_DATA_PARAM_DESC
+	{
+		String name;
+		String gpuVariableName;
+		GpuParamDataType type;
+		StringID rendererSemantic;
+		UINT32 arraySize;
+		UINT32 elementSize;
+		UINT32 defaultValueIdx;
+	};
+
+	/**
+	 * Describes a single object (texture, sampler state, etc.) shader parameter.
+	 *
+	 * @see	Shader::addParameter().
+	 */
+	struct SHADER_OBJECT_PARAM_DESC
+	{
+		String name;
+		Vector<String> gpuVariableNames;
+		StringID rendererSemantic;
+		GpuParamObjectType type;
+		UINT32 defaultValueIdx;
+	};
+
+	/** Describes a shader parameter block. */
+	struct SHADER_PARAM_BLOCK_DESC
+	{
+		String name;
+		bool shared;
+		StringID rendererSemantic;
+		GpuParamBlockUsage usage;
+	};
+
+	/** Structure used for initializing a shader. */
+	template<bool Core>
+	struct BS_CORE_EXPORT TSHADER_DESC
+	{
+		template<bool Core> struct TTextureType {};
+		template<> struct TTextureType < false > { typedef HTexture Type; };
+		template<> struct TTextureType < true > { typedef SPtr<TextureCore> Type; };
+
+		template<bool Core> struct TSamplerStateType {};
+		template<> struct TSamplerStateType < false > { typedef SamplerStatePtr Type; };
+		template<> struct TSamplerStateType < true > { typedef SPtr<SamplerStateCore> Type; };
+
+		typedef typename TTextureType<Core>::Type TextureType;
+		typedef typename TSamplerStateType<Core>::Type SamplerStateType;
+
+		TSHADER_DESC();
+
+		/**
+		 * Registers a new data (int, Vector2, etc.) parameter you that you may then use via Material by providing the 
+		 * parameter name. All parameters internally map to variables defined in GPU programs.
+		 *
+		 * @param[in]	name		   		The name of the parameter. Name must be unique between all data and object parameters.
+		 * @param[in]	gpuVariableName		Name of the GPU variable in the GpuProgram that the parameter corresponds with.
+		 * @param[in]	type		   		The type of the parameter, must be the same as the type in GpuProgram.
+		 * @param[in]	rendererSemantic	(optional) Semantic that allows you to specify the use of this parameter in the 
+		 *									renderer. The actual value of the semantic depends on the current Renderer and
+		 *									its supported list of semantics. Elements with renderer semantics should not be
+		 *									updated by the user, and will be updated by the renderer. These semantics will 
+		 *									also be used to determine if a shader is compatible with a specific renderer 
+		 *									or not. Value of 0 signifies the parameter is not used by the renderer.
+		 * @param[in]	arraySize	   		(optional) If the parameter is an array, the number of elements in the array. 
+		 *									Size of 1 means its not an array.
+		 * @param[in]	elementSize	   		(optional) Size of an individual element in the array, in bytes. You only need 
+		 *									to set this if you are setting variable length parameters, like structs.
+		 * @param[in]	defaultValue		(optional) Pointer to the buffer containing the default value for this parameter
+		 *									(initial value that will be set when a material is initialized with this shader). 
+		 *									The provided buffer must be of the correct size (depending on the element type 
+		 *									and array size).
+		 *
+		 * @note	If multiple parameters are given with the same name but different types behavior is undefined.
+		 */
+		void addParameter(const String& name, const String& gpuVariableName, GpuParamDataType type, StringID rendererSemantic = StringID::NONE,
+			UINT32 arraySize = 1, UINT32 elementSize = 0, UINT8* defaultValue = nullptr);
+
+		/**
+		 * Registers a new object (texture, sampler state, etc.) parameter you that you may then use via Material by 
+		 * providing the parameter name. All parameters internally map to variables defined in GPU programs. Multiple GPU 
+		 * variables may be mapped to a single parameter in which case the first variable actually found in the program will
+		 * be used while others will be ignored.
+		 *
+		 * @param[in]	name				The name of the parameter. Name must be unique between all data and object parameters.
+		 * @param[in]	gpuVariableName		Name of the GPU variable in the GpuProgram that the parameter corresponds with.
+		 * @param[in]	type		   		The type of the parameter, must be the same as the type in GpuProgram.
+		 * @param[in]	rendererSemantic	(optional) Semantic that allows you to specify the use of this parameter in the 
+		 *									renderer. The actual value of the semantic depends on the current Renderer and 
+		 *									its supported list of semantics. Elements with renderer semantics should not be 
+		 *									updated by the user, and will be updated by the renderer. These semantics will 
+		 *									also be used to determine if a shader is compatible with a specific renderer or 
+		 *									not. Value of 0 signifies the parameter is not used by the renderer.
+		 *
+		 * @note	
+		 * If multiple parameters are given with the same name but different types behavior is undefined. You are allowed 
+		 * to call this method multiple times in order to map multiple GPU variable names to a single parameter, but the 
+		 * default value (if any) will only be recognized on the first call. Mapping multiple GPU variables to a single 
+		 * parameter is useful when you are defining a shader that supports techniques across different render systems 
+		 * where GPU variable names for the same parameters might differ.
+		 */
+		void addParameter(const String& name, const String& gpuVariableName, GpuParamObjectType type, StringID rendererSemantic = StringID::NONE);
+
+		/**
+		 * @see	SHADER_DESC::addParameter(const String&, const String&, GpuParamObjectType, StringID)
+		 *
+		 * @note	
+		 * Specialized version of addParameter that accepts a default sampler value that will be used for initializing the 
+		 * object parameter upon Material creation. Default sampler value is only valid if the object type is one of the 
+		 * sampler types.
+		 */
+		void addParameter(const String& name, const String& gpuVariableName, GpuParamObjectType type, 
+			const SamplerStateType& defaultValue, StringID rendererSemantic = StringID::NONE);
+
+		/**
+		 * @see	SHADER_DESC::addParameter(const String&, const String&, GpuParamObjectType, StringID)
+		 *
+		 * @note	
+		 * Specialized version of addParameter that accepts a default texture value that will be used for initializing the 
+		 * object parameter upon Material creation. Default texture value is only valid if the object type is one of the 
+		 * texture types.
+		 */
+		void addParameter(const String& name, const String& gpuVariableName, GpuParamObjectType type, 
+			const TextureType& defaultValue, StringID rendererSemantic = StringID::NONE);
+
+		/**
+		 * Changes parameters of a parameter block with the specified name.
+		 *
+		 * @param[in]	name				Name of the parameter block. This should correspond with the name specified in 
+		 *									the GPU program code.
+		 * @param[in]	shared				If parameter block is marked as shared it will not be automatically created by 
+		 *									the Material. You will need to create it elsewhere and then assign it manually.
+		 * @param[in]	usage				Specified how often do we plan on modifying the buffer, which determines how is 
+		 *									the buffer internally stored for best performance.
+		 * @param[in]	rendererSemantic	(optional) Semantic that allows you to specify the use of this parameter block 
+		 *									in the renderer. The actual value of the semantic depends on the current 
+		 *									Renderer and its supported list of semantics. Elements with a renderer semantic
+		 *									will not have their parameter block automatically created (similar to "shared" 
+		 *									argument), but instead a Renderer will create an assign it instead. Be aware 
+		 *									that renderers have strict policies on what and how are parameters stored in the 
+		 *									buffer and you will need to respect them. If you don't respect them your shader 
+		 *									will be deemed incompatible and won't be used. Value of 0 signifies the parameter
+		 *									block is not used by the renderer.
+		 */
+		void setParamBlockAttribs(const String& name, bool shared, GpuParamBlockUsage usage, StringID rendererSemantic = StringID::NONE);
+
+		/**
+		 * Sorting type to use when performing sort in the render queue. Default value is sort front to back which causes
+		 * least overdraw and is preferable. Transparent objects need to be sorted back to front. You may also specify no 
+		 * sorting and the elements will be rendered in the order they were added to the render queue.
+		 */
+		QueueSortType queueSortType;
+
+		/**
+		 * Priority that allows you to control in what order are your shaders rendered. See QueuePriority for a list of 
+		 * initial values. Shaders with higher priority will be rendered before shaders with lower priority, and 
+		 * additionally render queue will only sort elements within the same priority group.
+		 *
+		 * @note	
+		 * This is useful when you want all your opaque objects to be rendered before you start drawing your transparent 
+		 * ones. Or to render your overlays after everything else. Values provided in QueuePriority are just for general 
+		 * guidance and feel free to increase them or decrease them for finer tuning. (e.g. QueuePriority::Opaque + 1).
+		 */
+		INT32 queuePriority;
+
+		/**
+		 * Enables or disables separable passes. When separable passes are disabled all shader passes will be executed in a
+		 * sequence one after another. If it is disabled the renderer is free to mix and match passes from different 
+		 * objects to achieve best performance. (They will still be executed in sequence, but some other object may be 
+		 * rendered in-between passes)
+		 *
+		 * @note	Shaders with transparency generally can't be separable, while opaque can.
+		 */
+		bool separablePasses;
+
+		/** Flags that let the renderer know how should it interpret the shader. */
+		UINT32 flags;
+
+		Map<String, SHADER_DATA_PARAM_DESC> dataParams;
+		Map<String, SHADER_OBJECT_PARAM_DESC> textureParams;
+		Map<String, SHADER_OBJECT_PARAM_DESC> bufferParams;
+		Map<String, SHADER_OBJECT_PARAM_DESC> samplerParams;
+		Map<String, SHADER_PARAM_BLOCK_DESC> paramBlocks;
+
+		Vector<UINT8> dataDefaultValues;
+		Vector<SamplerStateType> samplerDefaultValues;
+		Vector<TextureType> textureDefaultValues;
+
+	private:
+		/**
+		 * @copydoc	addParameter(const String&, const String&, GpuParamObjectType, StringID)
+		 *
+		 * @note	Common method shared by different addParameter overloads.
+		 */
+		void addParameterInternal(const String& name, const String& gpuVariableName, GpuParamObjectType type, StringID rendererSemantic, UINT32 defaultValueIdx);
+	};
+
+	typedef TSHADER_DESC<true> SHADER_DESC_CORE;
+	typedef TSHADER_DESC<false> SHADER_DESC;
+
+	/**
+	 * Shader represents a collection of techniques. They are used in Materials, which can be considered as instances of a 
+	 * Shader. Multiple materials may share the same shader but provide different parameters to it.
+	 *
+	 * Shader will always choose the first supported technique based on the current render system, render manager and other
+	 * properties. So make sure to add most important techniques first so you make sure they are used if they are supported.
+	 *
+	 * @note	Templated version of Shader used for implementing both sim and core thread variants.
+	 */
+	template<bool Core>
+	class BS_CORE_EXPORT TShader
+	{
+	public:
+		template<bool Core> struct TTechniqueType {};
+		template<> struct TTechniqueType < false > { typedef Technique Type; };
+		template<> struct TTechniqueType < true > { typedef TechniqueCore Type; };
+
+		typedef typename TTechniqueType<Core>::Type TechniqueType;
+		typedef typename TSHADER_DESC<Core>::TextureType TextureType;
+		typedef typename TSHADER_DESC<Core>::SamplerStateType SamplerStateType;
+
+		TShader() { }
+		TShader(const String& name, const TSHADER_DESC<Core>& desc, const Vector<SPtr<TechniqueType>>& techniques, UINT32 id);
+		virtual ~TShader();
+	
+		/** Returns the total number of techniques in this shader. */
+		UINT32 getNumTechniques() const { return (UINT32)mTechniques.size(); }
+
+		/**
+		 * Gets the best supported technique based on current render and other systems. Returns null if not a single 
+		 * technique is supported.
+		 */
+		SPtr<TechniqueType> getBestTechnique() const;
+
+		/**
+		 * Returns currently active queue sort type.
+		 *
+		 * @see		SHADER_DESC::queueSortType
+		 */
+		QueueSortType getQueueSortType() const { return mDesc.queueSortType; }
+
+		/**
+		 * Returns currently active queue priority.
+		 *
+		 * @see		SHADER_DESC::queuePriority
+		 */
+		INT32 getQueuePriority() const { return mDesc.queuePriority; }
+
+		/**
+		 * Returns if separable passes are allowed.
+		 *
+		 * @see		SHADER_DESC::separablePasses
+		 */
+		bool getAllowSeparablePasses() const { return mDesc.separablePasses; }
+
+		/**
+		 * Returns flags that control how the renderer interprets the shader. Actual interpretation of the flags depends on 
+		 * the active renderer.
+		 */
+		UINT32 getFlags() const { return mDesc.flags; }
+
+		/** Returns type of the parameter with the specified name. Throws exception if the parameter doesn't exist. */
+		GpuParamType getParamType(const String& name) const;
+
+		/**
+		 * Returns description for a data parameter with the specified name. Throws exception if the parameter doesn't exist.
+		 */
+		const SHADER_DATA_PARAM_DESC& getDataParamDesc(const String& name) const;
+
+		/**
+		 * Returns description for a texture parameter with the specified name. Throws exception if the parameter doesn't 
+		 * exist.
+		 */
+		const SHADER_OBJECT_PARAM_DESC& getTextureParamDesc(const String& name) const;
+
+		/**
+		 * Returns description for a sampler parameter with the specified name. Throws exception if the parameter doesn't 
+		 * exist.
+		 */
+		const SHADER_OBJECT_PARAM_DESC& getSamplerParamDesc(const String& name) const;
+
+		/**
+		 * Returns description for a buffer parameter with the specified name. Throws exception if the parameter doesn't 
+		 * exist.
+		 */
+		const SHADER_OBJECT_PARAM_DESC& getBufferParamDesc(const String& name) const;
+
+		/** Checks if the parameter with the specified name exists, and is a data parameter. */
+		bool hasDataParam(const String& name) const;
+
+		/**	Checks if the parameter with the specified name exists, and is a texture parameter. */
+		bool hasTextureParam(const String& name) const;
+
+		/** Checks if the parameter with the specified name exists, and is a sampler parameter. */
+		bool hasSamplerParam(const String& name) const;
+
+		/** Checks if the parameter with the specified name exists, and is a buffer parameter. */
+		bool hasBufferParam(const String& name) const;
+
+		/**	Returns a map of all data parameters in the shader. */
+		const Map<String, SHADER_DATA_PARAM_DESC>& getDataParams() const { return mDesc.dataParams; }
+
+		/**	Returns a map of all texture parameters in the shader. */
+		const Map<String, SHADER_OBJECT_PARAM_DESC>& getTextureParams() const { return mDesc.textureParams; }
+
+		/**	Returns a map of all buffer parameters in the shader. */
+		const Map<String, SHADER_OBJECT_PARAM_DESC>& getBufferParams() const { return mDesc.bufferParams; }
+
+		/** Returns a map of all sampler parameters in the shader. */
+		const Map<String, SHADER_OBJECT_PARAM_DESC>& getSamplerParams() const { return mDesc.samplerParams; }
+
+		/** Returns a map of all parameter blocks. */
+		const Map<String, SHADER_PARAM_BLOCK_DESC>& getParamBlocks() const { return mDesc.paramBlocks; }
+
+		/**
+		 * Returns a default texture for a parameter that has the specified default value index (retrieved from the 
+		 * parameters descriptor).
+		 */
+		TextureType getDefaultTexture(UINT32 index) const;
+
+		/**
+		 * Returns a default sampler state for a parameter that has the specified default value index (retrieved from the 
+		 * parameters descriptor).
+		 */
+		SamplerStateType getDefaultSampler(UINT32 index) const;
+
+		/**
+		 * Returns a pointer to the internal buffer containing the default value for a data parameter that has the
+		 * specified default value index (retrieved from the parameters descriptor).
+		 */
+		UINT8* getDefaultValue(UINT32 index) const;
+
+		/** Returns the unique shader ID. */
+		UINT32 getId() const { return mId; }
+
+	protected:
+		String mName;
+		TSHADER_DESC<Core> mDesc;
+		Vector<SPtr<TechniqueType>> mTechniques;
+		UINT32 mId;
+	};
+
+	/** @copydoc ShaderBase */
+	class BS_CORE_EXPORT ShaderCore : public CoreObjectCore, public TShader<true>
+	{
+	public:
+		/** @copydoc Shader::create */
+		static SPtr<ShaderCore> create(const String& name, const SHADER_DESC_CORE& desc, const Vector<SPtr<TechniqueCore>>& techniques);
+
+	protected:
+		friend class Shader;
+
+		ShaderCore(const String& name, const SHADER_DESC_CORE& desc, const Vector<SPtr<TechniqueCore>>& techniques, UINT32 id);
+
+		static std::atomic<UINT32> mNextShaderId;
+	};
+
+	/** @copydoc ShaderBase */
+	class BS_CORE_EXPORT Shader : public Resource, public TShader<false>
+	{
+	public:
+		/** Retrieves an implementation of a shader usable only from the core thread. */
+		SPtr<ShaderCore> getCore() const;
+
+		/**
+		 * Sets a list include file paths that are referenced by this shader.
+		 *
+		 * @note	
+		 * This is not used directly by the shader as includes are expected to be processed during GPU program and state 
+		 * creation, but it may be referenced by higher layers for various purposes.
+		 */
+		void setIncludeFiles(const Vector<String>& includes);
+
+		/**	Checks is the provided object type a sampler. */
+		static bool isSampler(GpuParamObjectType type);
+
+		/**	Checks is the provided object type a texture. */
+		static bool isTexture(GpuParamObjectType type);
+
+		/** Checks is the provided object type a buffer. */
+		static bool isBuffer(GpuParamObjectType type);
+
+		/**
+		 * Returns the size in bytes for a specific data type.
+		 *
+		 * @note	Returns 0 for variable size types like structures.
+		 */
+		static UINT32 getDataParamSize(GpuParamDataType type);
+
+		/**	Creates a new shader resource using the provided descriptor and techniques. */
+		static HShader create(const String& name, const SHADER_DESC& desc, const Vector<SPtr<Technique>>& techniques);
+
+		/**	Returns a shader object but doesn't initialize it. */
+		static ShaderPtr createEmpty();
+
+		/** @cond INTERNAL */
+
+		/**
+		 * Creates a new shader object using the provided descriptor and techniques.
+		 *
+		 * @note	Internal method.
+		 */
+		static ShaderPtr _createPtr(const String& name, const SHADER_DESC& desc, const Vector<SPtr<Technique>>& techniques);
+
+		/** @endcond */
+
+	private:
+		Shader(const String& name, const SHADER_DESC& desc, const Vector<SPtr<Technique>>& techniques, UINT32 id);
+
+		/** @copydoc CoreObject::getCoreDependencies */
+		void getCoreDependencies(Vector<CoreObject*>& dependencies) override;
+
+		/** @copydoc CoreObject::createCore */
+		SPtr<CoreObjectCore> createCore() const override;
+
+		/** Converts a sim thread version of the shader descriptor to a core thread version. */
+		SHADER_DESC_CORE convertDesc(const SHADER_DESC& desc) const;
+
+	private:
+		/************************************************************************/
+		/* 								RTTI		                     		*/
+		/************************************************************************/
+		Shader() { }
+
+	public:
+		friend class ShaderRTTI;
+		static RTTITypeBase* getRTTIStatic();
+		virtual RTTITypeBase* getRTTI() const override;
+	};
+
+	/** @cond INTERNAL */
+
+	/** Shader specific resource meta-data containing information about referenced include files. */
+	class BS_CORE_EXPORT ShaderMetaData : public ResourceMetaData
+	{
+	public:
+		Vector<String> includes;
+
+		/************************************************************************/
+		/* 								SERIALIZATION                      		*/
+		/************************************************************************/
+	public:
+		friend class ShaderMetaDataRTTI;
+		static RTTITypeBase* getRTTIStatic();
+		virtual RTTITypeBase* getRTTI() const override;
+	};
+
+	/** @endcond */
+	/** @} */
 }

+ 60 - 60
BansheeCore/Include/BsShaderManager.h

@@ -1,61 +1,61 @@
-#pragma once
-
-#include "BsCorePrerequisites.h"
-#include "BsModule.h"
-
-namespace BansheeEngine
-{
-	/**
-	 * @brief	Interface that provides a method for finding a shader include resource
-	 *			based on the name of the include that was provided in a shader file.
-	 */
-	class BS_CORE_EXPORT IShaderIncludeHandler
-	{
-	public:
-		virtual ~IShaderIncludeHandler() { }
-
-		/**
-		 * @brief	Attempts to find a shader include resource based on its name.
-		 */
-		virtual HShaderInclude findInclude(const String& name) const = 0;
-	};
-
-	/**
-	 * @brief	Implements shader include finding by converting the shader 
-	 *			include name into a path that the resource will be loaded from.
-	 */
-	class BS_CORE_EXPORT DefaultShaderIncludeHandler : public IShaderIncludeHandler
-	{
-	public:
-		/**
-		 * @copydoc	IShaderIncludeHandler::findInclude
-		 */
-		virtual HShaderInclude findInclude(const String& name) const override;
-	};
-
-	/**
-	 * @brief	A global manager that handles various shader specific operations.
-	 */
-	class BS_CORE_EXPORT ShaderManager : public Module <ShaderManager>
-	{
-	public:
-		ShaderManager(const ShaderIncludeHandlerPtr& handler) { mIncludeHandler = handler; }
-
-		/**
-		 * @brief	Attempts to find a shader include based on the include name.
-		 *
-		 * @note	The name is usually a path to the resource relative to the working folder,
-		 *			but can be other things depending on active handler.
-		 */
-		HShaderInclude findInclude(const String& name) const;
-
-		/**
-		 * @brief	Changes the active include handler that determines how is
-		 *			a shader include name mapped to the actual resource.
-		 */
-		void setIncludeHandler(const ShaderIncludeHandlerPtr& handler) { mIncludeHandler = handler; }
-
-	private:
-		ShaderIncludeHandlerPtr mIncludeHandler;
-	};
+#pragma once
+
+#include "BsCorePrerequisites.h"
+#include "BsModule.h"
+
+namespace BansheeEngine
+{
+	/** @cond INTERNAL */
+	/** @addtogroup Material
+	 *  @{
+	 */
+
+	/**
+	 * Interface that provides a method for finding a shader include resource based on the name of the include that was 
+	 * provided in a shader file.
+	 */
+	class BS_CORE_EXPORT IShaderIncludeHandler
+	{
+	public:
+		virtual ~IShaderIncludeHandler() { }
+
+		/** Attempts to find a shader include resource based on its name. */
+		virtual HShaderInclude findInclude(const String& name) const = 0;
+	};
+
+	/**
+	 * Implements shader include finding by converting the shader include name into a path that the resource will be loaded 
+	 * from.
+	 */
+	class BS_CORE_EXPORT DefaultShaderIncludeHandler : public IShaderIncludeHandler
+	{
+	public:
+		/** @copydoc IShaderIncludeHandler::findInclude */
+		virtual HShaderInclude findInclude(const String& name) const override;
+	};
+
+	/**	A global manager that handles various shader specific operations. */
+	class BS_CORE_EXPORT ShaderManager : public Module <ShaderManager>
+	{
+	public:
+		ShaderManager(const ShaderIncludeHandlerPtr& handler) { mIncludeHandler = handler; }
+
+		/**
+		 * Attempts to find a shader include based on the include name.
+		 *
+		 * @note	
+		 * The name is usually a path to the resource relative to the working folder, but can be other things depending on 
+		 * active handler.
+		 */
+		HShaderInclude findInclude(const String& name) const;
+
+		/** Changes the active include handler that determines how is a shader include name mapped to the actual resource. */
+		void setIncludeHandler(const ShaderIncludeHandlerPtr& handler) { mIncludeHandler = handler; }
+
+	private:
+		ShaderIncludeHandlerPtr mIncludeHandler;
+	};
+
+	/** @} */
+	/** @endcond */
 }

+ 330 - 341
BansheeCore/Include/BsStringTable.h

@@ -1,342 +1,331 @@
-#pragma once
-
-#include "BsCorePrerequisites.h"
-#include "BsResource.h"
-
-namespace BansheeEngine
-{
-	/**
-	 * @brief	Loosely based on ISO 639-1 two letter language codes
-	 */
-	enum class Language
-	{
-		Afar, 
-		Abkhazian, 
-		Avestan, 
-		Afrikaans, 
-		Akan, 
-		Amharic, 
-		Aragonese, 
-		Arabic, 
-		Assamese, 
-		Avaric, 
-		Aymara, 
-		Azerbaijani, 
-		Bashkir, 
-		Belarusian, 
-		Bulgarian, 
-		Bihari, 
-		Bislama, 
-		Bambara, 
-		Bengali, 
-		Tibetan, 
-		Breton, 
-		Bosnian, 
-		Catalan, 
-		Chechen, 
-		Chamorro, 
-		Corsican, 
-		Cree, 
-		Czech, 
-		ChurchSlavic,
-		Chuvash, 
-		Welsh, 
-		Danish, 
-		German, 
-		Maldivian, 
-		Bhutani, 
-		Ewe, 		
-		Greek, 
-		EnglishUK, 
-		EnglishUS,
-		Esperanto, 
-		Spanish, 
-		Estonian, 
-		Basque, 
-		Persian, 
-		Fulah, 
-		Finnish, 
-		Fijian, 
-		Faroese, 
-		French, 
-		WesternFrisian, 
-		Irish, 
-		ScottishGaelic, 
-		Galician, 
-		Guarani, 
-		Gujarati, 
-		Manx, 
-		Hausa, 
-		Hebrew, 
-		Hindi, 
-		HiriMotu, 
-		Croatian, 
-		Haitian, 
-		Hungarian, 
-		Armenian, 
-		Herero, 
-		Interlingua, 
-		Indonesian, 
-		Interlingue, 
-		Igbo, 
-		SichuanYi, 
-		Inupiak, 
-		Ido, 
-		Icelandic, 
-		Italian, 
-		Inuktitut, 
-		Japanese, 
-		Javanese, 
-		Georgian, 
-		Kongo, 
-		Kikuyu, 
-		Kuanyama, 
-		Kazakh, 
-		Kalaallisut, 
-		Cambodian, 
-		Kannada, 
-		Korean, 
-		Kanuri, 
-		Kashmiri, 
-		Kurdish, 
-		Komi, 
-		Cornish, 
-		Kirghiz, 
-		Latin, 
-		Luxembourgish, 
-		Ganda, 
-		Limburgish,
-		Lingala, 
-		Laotian, 
-		Lithuanian, 
-		LubaKatanga, 
-		Latvian,
-		Malagasy, 
-		Marshallese, 
-		Maori, 
-		Macedonian, 
-		Malayalam, 
-		Mongolian, 
-		Moldavian, 
-		Marathi, 
-		Malay, 
-		Maltese, 
-		Burmese, 
-		Nauru, 
-		NorwegianBokmal, 
-		Ndebele, 
-		Nepali, 
-		Ndonga, 
-		Dutch, 
-		NorwegianNynorsk, 
-		Norwegian, 
-		Navaho, 
-		Nyanja, 
-		Provençal, 
-		Ojibwa, 
-		Oromo, 
-		Oriya, 
-		Ossetic, 
-		Punjabi, 
-		Pali, 
-		Polish, 
-		Pushto, 
-		Portuguese, 
-		Quechua, 
-		Romansh, 
-		Kirundi, 
-		Romanian, 
-		Russian, 
-		Kinyarwanda, 
-		Sanskrit, 
-		Sardinian, 
-		Sindhi, 
-		NorthernSami, 
-		Sangro, 
-		Sinhalese, 
-		Slovak, 
-		Slovenian, 
-		Samoan, 
-		Shona, 
-		Somali, 
-		Albanian, 
-		Serbian, 
-		Swati,
-		Sesotho,
-		Sundanese, 
-		Swedish, 
-		Swahili, 
-		Tamil, 
-		Telugu, 
-		Tajik, 
-		Thai, 
-		Tigrinya, 
-		Turkmen, 
-		Tagalog, 
-		Setswana, 
-		Tonga, 
-		Turkish, 
-		Tsonga, 
-		Tatar,
-		Twi, 
-		Tahitian, 
-		Uighur, 
-		Ukrainian, 
-		Urdu, 
-		Uzbek, 
-		Venda, 
-		Vietnamese, 
-		Volapuk, 
-		Walloon, 
-		Wolof, 
-		Xhosa, 
-		Yiddish, 
-		Yoruba, 
-		Zhuang,
-		Chinese,
-		Zulu,
-		Count // Number of entries
-	};
-
-	/**
-	 * @brief	Internal data used for representing a localized string instance.
-	 * 			e.g. a specific instance of a localized string using specific parameters.
-	 */
-	struct LocalizedStringData
-	{
-		struct ParamOffset
-		{
-			ParamOffset()
-				:paramIdx(0), location(0)
-			{ }
-
-			ParamOffset(UINT32 _paramIdx, UINT32 _location)
-				:paramIdx(_paramIdx), location(_location)
-			{ }
-
-			UINT32 paramIdx;
-			UINT32 location;
-		};
-
-		LocalizedStringData();
-		~LocalizedStringData();
-
-		WString string;
-		UINT32 numParameters;
-		ParamOffset* parameterOffsets; 
-
-		void concatenateString(WString& outputString, WString* parameters, UINT32 numParameterValues) const;
-		void updateString(const WString& string);
-	};
-
-	/**
-	 * @brief	Data for a single language in the string table.
-	 */
-	struct LanguageData
-	{
-		UnorderedMap<WString, SPtr<LocalizedStringData>> strings;
-	};
-
-	/**
-	 * @brief	Used for string localization. Stores strings and their translations in various languages.
-	 */
-	class BS_CORE_EXPORT StringTable : public Resource
-	{
-		// TODO - When editing string table I will need to ensure that all languages of the same string have the same number of parameters
-
-
-	public:
-		StringTable();
-		~StringTable();
-
-		/**
-		 * @brief	Returns all identifiers in the table.
-		 */
-		const UnorderedSet<WString>& getIdentifiers() const { return mIdentifiers; }
-
-		/**
-		 * @brief	Adds or modifies string translation for the specified language.
-		 */
-		void setString(const WString& identifier, Language language, const WString& string);
-
-		/**
-		 * @brief	Returns a string translation for the specified language. Returns
-		 *			the identifier itself if one doesn't exist.
-		 */
-		WString getString(const WString& identifier, Language language);
-
-		/**
-		 * @brief	Removes the string described by identifier, from all languages.
-		 */
-		void removeString(const WString& identifier);
-
-		/**
-		 * @brief	Gets a string data for the specified string identifier and currently active language.
-		 *
-		 * @param	identifier		   	Unique string identifier.
-		 * @param	insertIfNonExisting	If true, a new string data for the specified identifier and language will be
-		 * 								added to the table if data doesn't already exist. The data will use the identifier as
-		 * 								the translation string.
-		 *
-		 * @return	The string data. Don't store reference to this data as it may get deleted.
-		 */
-		SPtr<LocalizedStringData> getStringData(const WString& identifier, bool insertIfNonExisting = true);
-
-		/**
-		 * @brief	Gets a string data for the specified string identifier and language.
-		 *
-		 * @param	identifier		   	Unique string identifier.
-		 * @param	language		   	Language.
-		 * @param	insertIfNonExisting	If true, a new string data for the specified identifier and language will be
-		 * 								added to the table if data doesn't already exist. The data will use the identifier as
-		 * 								the translation string.
-		 *
-		 * @return	The string data. Don't store reference to this data as it may get deleted.
-		 */
-		SPtr<LocalizedStringData> getStringData(const WString& identifier, Language language, bool insertIfNonExisting = true);
-
-		/**
-		 * @brief	Creates a new empty string table resource.
-		 */
-		static HStringTable create();
-
-		/**
-		 * @brief	Creates a new empty string table resource.
-		 *
-		 * @note	Internal method. Use "create" for normal use.
-		 */
-		static SPtr<StringTable> _createPtr();
-
-		static const Language DEFAULT_LANGUAGE;
-	private:
-		friend class HString;
-		friend class StringTableManager;
-
-		/**
-		 * @brief	Gets the currently active language.
-		 */
-		Language getActiveLanguage() const { return mActiveLanguage; }
-
-		/**
-		 * @brief	Changes the currently active language.
-		 * 			Any newly created strings will use this value.
-		 */
-		void setActiveLanguage(Language language);
-
-		Language mActiveLanguage;
-		LanguageData* mActiveLanguageData;
-		LanguageData* mDefaultLanguageData;
-
-		LanguageData* mAllLanguages;
-
-		UnorderedSet<WString> mIdentifiers;
-
-		/************************************************************************/
-		/* 								SERIALIZATION                      		*/
-		/************************************************************************/
-	public:
-		friend class StringTableRTTI;
-		static RTTITypeBase* getRTTIStatic();
-		virtual RTTITypeBase* getRTTI() const override;
-	};
+#pragma once
+
+#include "BsCorePrerequisites.h"
+#include "BsResource.h"
+
+namespace BansheeEngine
+{
+	/** @addtogroup Localization
+	 *  @{
+	 */
+
+	/** Loosely based on ISO 639-1 two letter language codes */
+	enum class Language
+	{
+		Afar, 
+		Abkhazian, 
+		Avestan, 
+		Afrikaans, 
+		Akan, 
+		Amharic, 
+		Aragonese, 
+		Arabic, 
+		Assamese, 
+		Avaric, 
+		Aymara, 
+		Azerbaijani, 
+		Bashkir, 
+		Belarusian, 
+		Bulgarian, 
+		Bihari, 
+		Bislama, 
+		Bambara, 
+		Bengali, 
+		Tibetan, 
+		Breton, 
+		Bosnian, 
+		Catalan, 
+		Chechen, 
+		Chamorro, 
+		Corsican, 
+		Cree, 
+		Czech, 
+		ChurchSlavic,
+		Chuvash, 
+		Welsh, 
+		Danish, 
+		German, 
+		Maldivian, 
+		Bhutani, 
+		Ewe, 		
+		Greek, 
+		EnglishUK, 
+		EnglishUS,
+		Esperanto, 
+		Spanish, 
+		Estonian, 
+		Basque, 
+		Persian, 
+		Fulah, 
+		Finnish, 
+		Fijian, 
+		Faroese, 
+		French, 
+		WesternFrisian, 
+		Irish, 
+		ScottishGaelic, 
+		Galician, 
+		Guarani, 
+		Gujarati, 
+		Manx, 
+		Hausa, 
+		Hebrew, 
+		Hindi, 
+		HiriMotu, 
+		Croatian, 
+		Haitian, 
+		Hungarian, 
+		Armenian, 
+		Herero, 
+		Interlingua, 
+		Indonesian, 
+		Interlingue, 
+		Igbo, 
+		SichuanYi, 
+		Inupiak, 
+		Ido, 
+		Icelandic, 
+		Italian, 
+		Inuktitut, 
+		Japanese, 
+		Javanese, 
+		Georgian, 
+		Kongo, 
+		Kikuyu, 
+		Kuanyama, 
+		Kazakh, 
+		Kalaallisut, 
+		Cambodian, 
+		Kannada, 
+		Korean, 
+		Kanuri, 
+		Kashmiri, 
+		Kurdish, 
+		Komi, 
+		Cornish, 
+		Kirghiz, 
+		Latin, 
+		Luxembourgish, 
+		Ganda, 
+		Limburgish,
+		Lingala, 
+		Laotian, 
+		Lithuanian, 
+		LubaKatanga, 
+		Latvian,
+		Malagasy, 
+		Marshallese, 
+		Maori, 
+		Macedonian, 
+		Malayalam, 
+		Mongolian, 
+		Moldavian, 
+		Marathi, 
+		Malay, 
+		Maltese, 
+		Burmese, 
+		Nauru, 
+		NorwegianBokmal, 
+		Ndebele, 
+		Nepali, 
+		Ndonga, 
+		Dutch, 
+		NorwegianNynorsk, 
+		Norwegian, 
+		Navaho, 
+		Nyanja, 
+		Provençal, 
+		Ojibwa, 
+		Oromo, 
+		Oriya, 
+		Ossetic, 
+		Punjabi, 
+		Pali, 
+		Polish, 
+		Pushto, 
+		Portuguese, 
+		Quechua, 
+		Romansh, 
+		Kirundi, 
+		Romanian, 
+		Russian, 
+		Kinyarwanda, 
+		Sanskrit, 
+		Sardinian, 
+		Sindhi, 
+		NorthernSami, 
+		Sangro, 
+		Sinhalese, 
+		Slovak, 
+		Slovenian, 
+		Samoan, 
+		Shona, 
+		Somali, 
+		Albanian, 
+		Serbian, 
+		Swati,
+		Sesotho,
+		Sundanese, 
+		Swedish, 
+		Swahili, 
+		Tamil, 
+		Telugu, 
+		Tajik, 
+		Thai, 
+		Tigrinya, 
+		Turkmen, 
+		Tagalog, 
+		Setswana, 
+		Tonga, 
+		Turkish, 
+		Tsonga, 
+		Tatar,
+		Twi, 
+		Tahitian, 
+		Uighur, 
+		Ukrainian, 
+		Urdu, 
+		Uzbek, 
+		Venda, 
+		Vietnamese, 
+		Volapuk, 
+		Walloon, 
+		Wolof, 
+		Xhosa, 
+		Yiddish, 
+		Yoruba, 
+		Zhuang,
+		Chinese,
+		Zulu,
+		Count // Number of entries
+	};
+
+	/** @cond INTERNAL */
+
+	/**
+	 * Internal data used for representing a localized string instance. e.g. a specific instance of a localized string 
+	 * using specific parameters.
+	 */
+	struct LocalizedStringData
+	{
+		struct ParamOffset
+		{
+			ParamOffset()
+				:paramIdx(0), location(0)
+			{ }
+
+			ParamOffset(UINT32 _paramIdx, UINT32 _location)
+				:paramIdx(_paramIdx), location(_location)
+			{ }
+
+			UINT32 paramIdx;
+			UINT32 location;
+		};
+
+		LocalizedStringData();
+		~LocalizedStringData();
+
+		WString string;
+		UINT32 numParameters;
+		ParamOffset* parameterOffsets; 
+
+		void concatenateString(WString& outputString, WString* parameters, UINT32 numParameterValues) const;
+		void updateString(const WString& string);
+	};
+
+	/** Data for a single language in the string table. */
+	struct LanguageData
+	{
+		UnorderedMap<WString, SPtr<LocalizedStringData>> strings;
+	};
+
+	/** @endcond */
+
+	/** Used for string localization. Stores strings and their translations in various languages. */
+	class BS_CORE_EXPORT StringTable : public Resource
+	{
+		// TODO - When editing string table I will need to ensure that all languages of the same string have the same number of parameters
+
+	public:
+		StringTable();
+		~StringTable();
+
+		/** Returns all identifiers in the table. */
+		const UnorderedSet<WString>& getIdentifiers() const { return mIdentifiers; }
+
+		/**	Adds or modifies string translation for the specified language. */
+		void setString(const WString& identifier, Language language, const WString& string);
+
+		/**	Returns a string translation for the specified language. Returns the identifier itself if one doesn't exist. */
+		WString getString(const WString& identifier, Language language);
+
+		/** Removes the string described by identifier, from all languages. */
+		void removeString(const WString& identifier);
+
+		/**
+		 * Gets a string data for the specified string identifier and currently active language.
+		 *
+		 * @param[in]	identifier		   	Unique string identifier.
+		 * @param[in]	insertIfNonExisting	If true, a new string data for the specified identifier and language will be 
+		 *									added to the table if data doesn't already exist. The data will use the 
+		 *									identifier as the translation string.
+		 * @return							The string data. Don't store reference to this data as it may get deleted.
+		 */
+		SPtr<LocalizedStringData> getStringData(const WString& identifier, bool insertIfNonExisting = true);
+
+		/**
+		 * Gets a string data for the specified string identifier and language.
+		 *
+		 * @param[in]	identifier		   	Unique string identifier.
+		 * @param[in]	language		   	Language.
+		 * @param[in]	insertIfNonExisting	If true, a new string data for the specified identifier and language will be 
+		 *									added to the table if data doesn't already exist. The data will use the 
+		 *									identifier as the translation string.
+		 * @return							The string data. Don't store reference to this data as it may get deleted.
+		 */
+		SPtr<LocalizedStringData> getStringData(const WString& identifier, Language language, bool insertIfNonExisting = true);
+
+		/** Creates a new empty string table resource. */
+		static HStringTable create();
+
+		/** @cond INTERNAL */
+
+		/**
+		 * Creates a new empty string table resource.
+		 *
+		 * @note	Internal method. Use create() for normal use.
+		 */
+		static SPtr<StringTable> _createPtr();
+
+		/** @endcond */
+
+		static const Language DEFAULT_LANGUAGE;
+	private:
+		friend class HString;
+		friend class StringTableManager;
+
+		/** Gets the currently active language. */
+		Language getActiveLanguage() const { return mActiveLanguage; }
+
+		/** Changes the currently active language. Any newly created strings will use this value. */
+		void setActiveLanguage(Language language);
+
+		Language mActiveLanguage;
+		LanguageData* mActiveLanguageData;
+		LanguageData* mDefaultLanguageData;
+
+		LanguageData* mAllLanguages;
+
+		UnorderedSet<WString> mIdentifiers;
+
+		/************************************************************************/
+		/* 								SERIALIZATION                      		*/
+		/************************************************************************/
+	public:
+		friend class StringTableRTTI;
+		static RTTITypeBase* getRTTIStatic();
+		virtual RTTITypeBase* getRTTI() const override;
+	};
+
+	/** @} */
 }

+ 42 - 48
BansheeCore/Include/BsStringTableManager.h

@@ -1,49 +1,43 @@
-#pragma once
-
-#include "BsCorePrerequisites.h"
-#include "BsModule.h"
-#include "BsStringTable.h"
-
-namespace BansheeEngine
-{
-	/**
-	 * @brief	Manages string tables used for localizing text. Allows you to add 
-	 *			and remove different tables and change the active language.
-	 */
-	class BS_CORE_EXPORT StringTableManager : public Module<StringTableManager>
-	{
-	public:
-		StringTableManager();
-
-		/**
-		 * @brief	Gets the currently active language.
-		 */
-		Language getActiveLanguage() const { return mActiveLanguage; }
-
-		/**
-		 * @brief	Changes the currently active language.
-		 *			Any newly created strings will use this value.
-		 */
-		void setActiveLanguage(Language language);
-
-		/**
-		 * @brief	Returns the string table with the specified id.
-		 *			If the table doesn't exist new one is created.
-		 */
-		HStringTable getTable(UINT32 id);
-
-		/**
-		 * @brief	Removes the string table with the specified id.
-		 */
-		void removeTable(UINT32 id);
-
-		/**
-		 * @brief	Registers a new string table or replaces an old one at the specified id.
-		 */
-		void setTable(UINT32 id, HStringTable table);
-
-	private:
-		Language mActiveLanguage;
-		UnorderedMap<UINT32, HStringTable> mTables;
-	};
+#pragma once
+
+#include "BsCorePrerequisites.h"
+#include "BsModule.h"
+#include "BsStringTable.h"
+
+namespace BansheeEngine
+{
+	/** @addtogroup Localization
+	 *  @{
+	 */
+
+	/**
+	 * Manages string tables used for localizing text. Allows you to add and remove different tables and change the active 
+	 * language.
+	 */
+	class BS_CORE_EXPORT StringTableManager : public Module<StringTableManager>
+	{
+	public:
+		StringTableManager();
+
+		/** Gets the currently active language. */
+		Language getActiveLanguage() const { return mActiveLanguage; }
+
+		/** Changes the currently active language. Any newly created strings will use this value. */
+		void setActiveLanguage(Language language);
+
+		/** Returns the string table with the specified id. If the table doesn't exist new one is created. */
+		HStringTable getTable(UINT32 id);
+
+		/** Removes the string table with the specified id. */
+		void removeTable(UINT32 id);
+
+		/** Registers a new string table or replaces an old one at the specified id. */
+		void setTable(UINT32 id, HStringTable table);
+
+	private:
+		Language mActiveLanguage;
+		UnorderedMap<UINT32, HStringTable> mTables;
+	};
+
+	/** @} */
 }

+ 123 - 136
BansheeCore/Include/BsTechnique.h

@@ -1,137 +1,124 @@
-#pragma once
-
-#include "BsCorePrerequisites.h"
-#include "BsIReflectable.h"
-#include "BsCoreObject.h"
-
-namespace BansheeEngine
-{
-	/**
-	 * @brief	Technique represents a specific implementation of a shader. Contains
-	 *			a number of passes that will be executed when rendering objects using this technique.
-	 *
-	 * @note	Normally you want to have a separate technique for every render system and renderer your 
-	 *			application supports. For example, if you are supporting DirectX11 and OpenGL you will
-	 *			want to have two techniques, one using HLSL based GPU programs, other using GLSL. Those
-	 *			techniques should try to mirror each others end results.
-	 */
-	class BS_CORE_EXPORT TechniqueBase
-	{
-	public:
-		TechniqueBase(const StringID& renderAPI, const StringID& renderer);
-		virtual ~TechniqueBase() { }
-
-		/**
-		 * @brief	Checks if this technique is supported based on current
-		 *			render and other systems.
-		 */
-		bool isSupported() const;
-
-	protected:
-		StringID mRenderAPI;
-		StringID mRenderer;
-	};
-
-	/**
-	 * @copydoc	TechniqueBase
-	 *
-	 * @note	Templated version that is used for implementing 
-	 *			both sim and core versions of Technique.
-	 */
-	template<bool Core>
-	class BS_CORE_EXPORT TTechnique : public TechniqueBase
-	{
-	public:
-		template<bool Core> struct TPassType { };
-		template<> struct TPassType < false > { typedef Pass Type; };
-		template<> struct TPassType < true > { typedef PassCore Type; };
-
-		typedef typename TPassType<Core>::Type PassType;
-		
-		TTechnique();
-		TTechnique(const StringID& renderAPI, const StringID& renderer, const Vector<SPtr<PassType>>& passes);
-		virtual ~TTechnique() { }
-
-		/**
-		 * @brief	Returns a pass with the specified index.
-		 */
-		SPtr<PassType> getPass(UINT32 idx) const;
-
-		/**
-		 * @brief	Returns total number of passes.
-		 */
-		UINT32 getNumPasses() const { return (UINT32)mPasses.size(); }
-
-	protected:
-		Vector<SPtr<PassType>> mPasses;
-	};
-
-	/**
-	 * @copydoc	TechniqueBase
-	 *
-	 * @note	Core thread.
-	 */
-	class BS_CORE_EXPORT TechniqueCore : public CoreObjectCore, public TTechnique<true>
-	{
-	public:
-		TechniqueCore(const StringID& renderAPI, const StringID& renderer, const Vector<SPtr<PassCore>>& passes);
-
-		/**
-		 * @brief	Creates a new technique.
-		 */
-		static SPtr<TechniqueCore> create(const StringID& renderAPI, const StringID& renderer, const Vector<SPtr<PassCore>>& passes);
-	};
-
-	/**
-	 * @copydoc	TechniqueBase
-	 *
-	 * @note	Sim thread.
-	 */
-	class BS_CORE_EXPORT Technique : public IReflectable, public CoreObject, public TTechnique<false>
-	{
-	public:
-		Technique(const StringID& renderAPI, const StringID& renderer, const Vector<SPtr<Pass>>& passes);
-
-		/**
-		 * @brief	Retrieves an implementation of a technique usable only from the
-		 *			core thread.
-		 */
-		SPtr<TechniqueCore> getCore() const;
-
-		/**
-		 * @brief	Creates a new technique.
-		 */
-		static TechniquePtr create(const StringID& renderAPI, const StringID& renderer, const Vector<SPtr<Pass>>& passes);
-
-	protected:
-		/**
-		 * @copydoc	CoreObject::createCore
-		 */
-		SPtr<CoreObjectCore> createCore() const override;
-
-		/**
-		 * @copydoc	CoreObject::getCoreDependencies
-		 */
-		void getCoreDependencies(Vector<CoreObject*>& dependencies) override;
-
-		/**
-		 * @brief	Creates a new technique but doesn't initialize it.
-		 */
-		static TechniquePtr createEmpty();
-
-	private:
-		/************************************************************************/
-		/* 								RTTI		                     		*/
-		/************************************************************************/
-		
-		/**
-		 * @brief	Serialization only constructor.
-		 */
-		Technique();
-
-	public:
-		friend class TechniqueRTTI;
-		static RTTITypeBase* getRTTIStatic();
-		virtual RTTITypeBase* getRTTI() const;	
-	};
+#pragma once
+
+#include "BsCorePrerequisites.h"
+#include "BsIReflectable.h"
+#include "BsCoreObject.h"
+
+namespace BansheeEngine
+{
+	/** @addtogroup Material
+	 *  @{
+	 */
+
+	/**
+	 * Technique represents a specific implementation of a shader. Contains a number of passes that will be executed when 
+	 * rendering objects using this technique.
+	 *
+	 * @note	
+	 * Normally you want to have a separate technique for every render system and renderer your application supports. 
+	 * For example, if you are supporting DirectX11 and OpenGL you will want to have two techniques, one using HLSL based 
+	 * GPU programs, other using GLSL. Those techniques should try to mirror each others end results.
+	 */
+	class BS_CORE_EXPORT TechniqueBase
+	{
+	public:
+		TechniqueBase(const StringID& renderAPI, const StringID& renderer);
+		virtual ~TechniqueBase() { }
+
+		/**
+		 * @brief	Checks if this technique is supported based on current
+		 *			render and other systems.
+		 */
+		bool isSupported() const;
+
+	protected:
+		StringID mRenderAPI;
+		StringID mRenderer;
+	};
+
+	/**
+	 * @copydoc	TechniqueBase
+	 *
+	 * @note	Templated version that is used for implementing 
+	 *			both sim and core versions of Technique.
+	 */
+	template<bool Core>
+	class BS_CORE_EXPORT TTechnique : public TechniqueBase
+	{
+	public:
+		template<bool Core> struct TPassType { };
+		template<> struct TPassType < false > { typedef Pass Type; };
+		template<> struct TPassType < true > { typedef PassCore Type; };
+
+		typedef typename TPassType<Core>::Type PassType;
+		
+		TTechnique();
+		TTechnique(const StringID& renderAPI, const StringID& renderer, const Vector<SPtr<PassType>>& passes);
+		virtual ~TTechnique() { }
+
+		/**	Returns a pass with the specified index. */
+		SPtr<PassType> getPass(UINT32 idx) const;
+
+		/**	Returns total number of passes. */
+		UINT32 getNumPasses() const { return (UINT32)mPasses.size(); }
+
+	protected:
+		Vector<SPtr<PassType>> mPasses;
+	};
+
+	/**
+	 * @copydoc	TechniqueBase
+	 *
+	 * @note	Core thread.
+	 */
+	class BS_CORE_EXPORT TechniqueCore : public CoreObjectCore, public TTechnique<true>
+	{
+	public:
+		TechniqueCore(const StringID& renderAPI, const StringID& renderer, const Vector<SPtr<PassCore>>& passes);
+
+		/** Creates a new technique. */
+		static SPtr<TechniqueCore> create(const StringID& renderAPI, const StringID& renderer, const Vector<SPtr<PassCore>>& passes);
+	};
+
+	/**
+	 * @copydoc	TechniqueBase
+	 *
+	 * @note	Sim thread.
+	 */
+	class BS_CORE_EXPORT Technique : public IReflectable, public CoreObject, public TTechnique<false>
+	{
+	public:
+		Technique(const StringID& renderAPI, const StringID& renderer, const Vector<SPtr<Pass>>& passes);
+
+		/** Retrieves an implementation of a technique usable only from the core thread. */
+		SPtr<TechniqueCore> getCore() const;
+
+		/** Creates a new technique. */
+		static TechniquePtr create(const StringID& renderAPI, const StringID& renderer, const Vector<SPtr<Pass>>& passes);
+
+	protected:
+		/** @copydoc CoreObject::createCore */
+		SPtr<CoreObjectCore> createCore() const override;
+
+		/** @copydoc CoreObject::getCoreDependencies */
+		void getCoreDependencies(Vector<CoreObject*>& dependencies) override;
+
+		/**	Creates a new technique but doesn't initialize it. */
+		static TechniquePtr createEmpty();
+
+	private:
+		/************************************************************************/
+		/* 								RTTI		                     		*/
+		/************************************************************************/
+		
+		/** Serialization only constructor. */
+		Technique();
+
+	public:
+		friend class TechniqueRTTI;
+		static RTTITypeBase* getRTTIStatic();
+		virtual RTTITypeBase* getRTTI() const override;	
+	};
+
+	/** @} */
 }