소스 검색

Refactored GUI so it generates all of it's GPU param buffers before rendering, instead of updating them before every draw call
Fixed OpenGL GPU param unit binding assigments

BearishSun 9 년 전
부모
커밋
23561ee03b

+ 47 - 38
Data/Raw/Engine/Includes/SpriteImage.bslinc

@@ -1,13 +1,17 @@
 Parameters =
 Parameters =
 {
 {
-	mat4x4 	worldTransform;
-	float	invViewportWidth;
-	float	invViewportHeight;
+	mat4x4 	gWorldTransform;
+	float	gInvViewportWidth;
+	float	gInvViewportHeight;
+	color	gTint;
 	
 	
-	Sampler2D	mainTexSamp : alias("mainTexture");
-	Texture2D	mainTexture;
-	
-	color		tint;
+	Sampler2D	gMainTexSamp : alias("gMainTexture");
+	Texture2D	gMainTexture;
+};
+
+Blocks = 
+{
+	Block GUIParams : auto("GUIParams");
 };
 };
 
 
 Technique : base("SpriteImage") =
 Technique : base("SpriteImage") =
@@ -19,22 +23,29 @@ Technique : base("SpriteImage") =
 		DepthRead = false;
 		DepthRead = false;
 		DepthWrite = false;
 		DepthWrite = false;
 		
 		
+		Common =
+		{
+			cbuffer GUIParams
+			{
+				float4x4 gWorldTransform;
+				float gInvViewportWidth;
+				float gInvViewportHeight;
+				float4 gTint;
+			}	
+		};
+		
 		Vertex =
 		Vertex =
 		{
 		{
-			float invViewportWidth;
-			float invViewportHeight;
-			float4x4 worldTransform;
-
 			void main(
 			void main(
 				in float3 inPos : POSITION,
 				in float3 inPos : POSITION,
 				in float2 uv : TEXCOORD0,
 				in float2 uv : TEXCOORD0,
 				out float4 oPosition : SV_Position,
 				out float4 oPosition : SV_Position,
 				out float2 oUv : TEXCOORD0)
 				out float2 oUv : TEXCOORD0)
 			{
 			{
-				float4 tfrmdPos = mul(worldTransform, float4(inPos.xy, 0, 1));
+				float4 tfrmdPos = mul(gWorldTransform, float4(inPos.xy, 0, 1));
 
 
-				float tfrmdX = -1.0f + (tfrmdPos.x * invViewportWidth);
-				float tfrmdY = 1.0f - (tfrmdPos.y * invViewportHeight);
+				float tfrmdX = -1.0f + (tfrmdPos.x * gInvViewportWidth);
+				float tfrmdY = 1.0f - (tfrmdPos.y * gInvViewportHeight);
 
 
 				oPosition = float4(tfrmdX, tfrmdY, 0, 1);
 				oPosition = float4(tfrmdX, tfrmdY, 0, 1);
 				oUv = uv;
 				oUv = uv;
@@ -43,14 +54,13 @@ Technique : base("SpriteImage") =
 		
 		
 		Fragment =
 		Fragment =
 		{
 		{
-			SamplerState mainTexSamp : register(s0);
-			Texture2D mainTexture : register(t0);
-			float4 tint;
-
+			SamplerState gMainTexSamp : register(s0);
+			Texture2D gMainTexture : register(t0);
+			
 			float4 main(in float4 inPos : SV_Position, float2 uv : TEXCOORD0) : SV_Target
 			float4 main(in float4 inPos : SV_Position, float2 uv : TEXCOORD0) : SV_Target
 			{
 			{
-				float4 color = mainTexture.Sample(mainTexSamp, uv);
-				return color * tint;
+				float4 color = gMainTexture.Sample(gMainTexSamp, uv);
+				return color * gTint;
 			}
 			}
 		};
 		};
 	};
 	};
@@ -65,15 +75,19 @@ Technique : base("SpriteImage") =
 		DepthRead = false;
 		DepthRead = false;
 		DepthWrite = false;
 		DepthWrite = false;
 		
 		
-		Vertex =
+		Common =
 		{
 		{
-			layout (binding = 0) uniform VertUBO
+			layout (binding = 0, std140) uniform GUIParams
 			{
 			{
-				float invViewportWidth;
-				float invViewportHeight;
-				mat4 worldTransform;
-			};
-			
+				mat4 gWorldTransform;
+				float gInvViewportWidth;
+				float gInvViewportHeight;
+				vec4 gTint;
+			};			
+		};		
+		
+		Vertex =
+		{
 			layout (location = 0) in vec3 bs_position;
 			layout (location = 0) in vec3 bs_position;
 			layout (location = 1) in vec2 bs_texcoord0;
 			layout (location = 1) in vec2 bs_texcoord0;
 			
 			
@@ -86,10 +100,10 @@ Technique : base("SpriteImage") =
 			
 			
 			void main()
 			void main()
 			{
 			{
-				vec4 tfrmdPos = worldTransform * vec4(bs_position.xy, 0, 1);
+				vec4 tfrmdPos = gWorldTransform * vec4(bs_position.xy, 0, 1);
 
 
-				float tfrmdX = -1.0f + (tfrmdPos.x * invViewportWidth);
-				float tfrmdY = 1.0f - (tfrmdPos.y * invViewportHeight);	
+				float tfrmdX = -1.0f + (tfrmdPos.x * gInvViewportWidth);
+				float tfrmdY = 1.0f - (tfrmdPos.y * gInvViewportHeight);	
 
 
 				gl_Position = vec4(tfrmdX, tfrmdY, 0, 1);
 				gl_Position = vec4(tfrmdX, tfrmdY, 0, 1);
 				texcoord0 = bs_texcoord0;
 				texcoord0 = bs_texcoord0;
@@ -98,20 +112,15 @@ Technique : base("SpriteImage") =
 		
 		
 		Fragment =
 		Fragment =
 		{
 		{
-			layout (binding = 1) uniform FragUBO
-			{
-				vec4 tint;
-			};
-			
-			layout (binding = 2) uniform sampler2D mainTexture;
+			layout (binding = 1) uniform sampler2D gMainTexture;
 			
 			
 			layout (location = 0) in vec2 texcoord0;
 			layout (location = 0) in vec2 texcoord0;
 			layout (location = 0) out vec4 fragColor;
 			layout (location = 0) out vec4 fragColor;
 
 
 			void main()
 			void main()
 			{
 			{
-				vec4 color = texture2D(mainTexture, texcoord0.st);
-				fragColor = color * tint;
+				vec4 color = texture2D(gMainTexture, texcoord0.st);
+				fragColor = color * gTint;
 			}
 			}
 		};
 		};
 	};
 	};

+ 44 - 35
Data/Raw/Engine/Shaders/SpriteText.bsl

@@ -1,13 +1,17 @@
 Parameters =
 Parameters =
 {
 {
-	mat4x4 	worldTransform;
-	float	invViewportWidth;
-	float	invViewportHeight;
+	mat4x4 	gWorldTransform;
+	float	gInvViewportWidth;
+	float	gInvViewportHeight;
+	color	gTint;
 	
 	
-	Sampler2D	mainTexSamp : alias("mainTexture");
-	Texture2D	mainTexture;
-	
-	color		tint;
+	Sampler2D	gMainTexSamp : alias("gMainTexture");
+	Texture2D	gMainTexture;
+};
+
+Blocks = 
+{
+	Block GUIParams : auto("GUIParams");
 };
 };
 
 
 Technique =
 Technique =
@@ -26,22 +30,29 @@ Technique =
 		DepthRead = false;
 		DepthRead = false;
 		DepthWrite = false;
 		DepthWrite = false;
 		
 		
+		Common =
+		{
+			cbuffer GUIParams
+			{
+				float4x4 gWorldTransform;
+				float gInvViewportWidth;
+				float gInvViewportHeight;
+				float4 gTint;
+			}	
+		};
+		
 		Vertex =
 		Vertex =
 		{
 		{
-			float invViewportWidth;
-			float invViewportHeight;
-			float4x4 worldTransform;
-
 			void main(
 			void main(
 				in float3 inPos : POSITION,
 				in float3 inPos : POSITION,
 				in float2 uv : TEXCOORD0,
 				in float2 uv : TEXCOORD0,
 				out float4 oPosition : SV_Position,
 				out float4 oPosition : SV_Position,
 				out float2 oUv : TEXCOORD0)
 				out float2 oUv : TEXCOORD0)
 			{
 			{
-				float4 tfrmdPos = mul(worldTransform, float4(inPos.xy, 0, 1));
+				float4 tfrmdPos = mul(gWorldTransform, float4(inPos.xy, 0, 1));
 
 
-				float tfrmdX = -1.0f + (tfrmdPos.x * invViewportWidth);
-				float tfrmdY = 1.0f - (tfrmdPos.y * invViewportHeight);
+				float tfrmdX = -1.0f + (tfrmdPos.x * gInvViewportWidth);
+				float tfrmdY = 1.0f - (tfrmdPos.y * gInvViewportHeight);
 
 
 				oPosition = float4(tfrmdX, tfrmdY, 0, 1);
 				oPosition = float4(tfrmdX, tfrmdY, 0, 1);
 				oUv = uv;
 				oUv = uv;
@@ -50,13 +61,12 @@ Technique =
 		
 		
 		Fragment =
 		Fragment =
 		{
 		{
-			SamplerState mainTexSamp : register(s0);
-			Texture2D mainTexture : register(t0);
-			float4 tint;
+			SamplerState gMainTexSamp : register(s0);
+			Texture2D gMainTexture : register(t0);
 
 
 			float4 main(in float4 inPos : SV_Position, float2 uv : TEXCOORD0) : SV_Target
 			float4 main(in float4 inPos : SV_Position, float2 uv : TEXCOORD0) : SV_Target
 			{
 			{
-				float4 color = float4(tint.rgb, mainTexture.Sample(mainTexSamp, uv).r * tint.a);
+				float4 color = float4(gTint.rgb, gMainTexture.Sample(gMainTexSamp, uv).r * gTint.a);
 				return color;
 				return color;
 			}
 			}
 		};
 		};
@@ -79,15 +89,19 @@ Technique =
 		DepthRead = false;
 		DepthRead = false;
 		DepthWrite = false;
 		DepthWrite = false;
 		
 		
-		Vertex =
+		Common =
 		{
 		{
-			layout (binding = 0) uniform VertUBO
+			layout (binding = 0, std140) uniform GUIParams
 			{
 			{
-				float invViewportWidth;
-				float invViewportHeight;
-				mat4 worldTransform;
-			};
-
+				mat4 gWorldTransform;
+				float gInvViewportWidth;
+				float gInvViewportHeight;
+				vec4 gTint;
+			};			
+		};			
+		
+		Vertex =
+		{
 			layout (location = 0) in vec3 bs_position;
 			layout (location = 0) in vec3 bs_position;
 			layout (location = 1) in vec2 bs_texcoord0;
 			layout (location = 1) in vec2 bs_texcoord0;
 			
 			
@@ -100,10 +114,10 @@ Technique =
 			
 			
 			void main()
 			void main()
 			{
 			{
-				vec4 tfrmdPos = worldTransform * vec4(bs_position.xy, 0, 1);
+				vec4 tfrmdPos = gWorldTransform * vec4(bs_position.xy, 0, 1);
 
 
-				float tfrmdX = -1.0f + (tfrmdPos.x * invViewportWidth);
-				float tfrmdY = 1.0f - (tfrmdPos.y * invViewportHeight);
+				float tfrmdX = -1.0f + (tfrmdPos.x * gInvViewportWidth);
+				float tfrmdY = 1.0f - (tfrmdPos.y * gInvViewportHeight);
 
 
 				gl_Position = vec4(tfrmdX, tfrmdY, 0, 1);
 				gl_Position = vec4(tfrmdX, tfrmdY, 0, 1);
 				texcoord0 = bs_texcoord0;
 				texcoord0 = bs_texcoord0;
@@ -112,19 +126,14 @@ Technique =
 		
 		
 		Fragment =
 		Fragment =
 		{
 		{
-			layout (binding = 1) uniform FragUBO
-			{
-				vec4 tint;
-			};		
-		
-			layout (binding = 2) uniform sampler2D mainTexture;
+			layout (binding = 1) uniform sampler2D gMainTexture;
 			
 			
 			layout (location = 0) in vec2 texcoord0;
 			layout (location = 0) in vec2 texcoord0;
 			layout (location = 0) out vec4 fragColor;
 			layout (location = 0) out vec4 fragColor;
 
 
 			void main()
 			void main()
 			{
 			{
-				vec4 color = vec4(tint.rgb, texture2D(mainTexture, texcoord0.st).r * tint.a);
+				vec4 color = vec4(gTint.rgb, texture2D(gMainTexture, texcoord0.st).r * gTint.a);
 				fragColor = color;
 				fragColor = color;
 			}
 			}
 		};
 		};

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

@@ -15,6 +15,9 @@ namespace bs
 	 *  @{
 	 *  @{
 	 */
 	 */
 
 
+// Note: Every time one of these param blocks is instantiated we generate its descriptor. It would be better to generate
+// it once, and then just quickly instantiate for subsequent creations.
+
 /**
 /**
  * Starts a new custom parameter block. Custom parameter blocks allow you to create C++ structures that map directly
  * Starts a new custom parameter block. Custom parameter blocks allow you to create C++ structures that map directly
  * to GPU program buffers (for example uniform buffer in OpenGL or constant buffer in DX). Must be followed by
  * to GPU program buffers (for example uniform buffer in OpenGL or constant buffer in DX). Must be followed by
@@ -46,6 +49,11 @@ namespace bs
 		}																													\
 		}																													\
 																															\
 																															\
 		const SPtr<GpuParamBlockBufferCore>& getBuffer() const { return mBuffer; }											\
 		const SPtr<GpuParamBlockBufferCore>& getBuffer() const { return mBuffer; }											\
+		void setBuffer(const SPtr<GpuParamBlockBufferCore>& buffer)															\
+		{																													\
+				mBuffer = buffer;																							\
+				mParams->setParamBlockBuffer(GPT_VERTEX_PROGRAM, #Name, mBuffer);											\
+		}																													\
 		const GpuParamBlockDesc& getDesc() const { return mBlockDesc; }														\
 		const GpuParamBlockDesc& getDesc() const { return mBlockDesc; }														\
 		void flushToGPU(UINT32 queueIdx = 0) { mBuffer->flushToGPU(queueIdx); }												\
 		void flushToGPU(UINT32 queueIdx = 0) { mBuffer->flushToGPU(queueIdx); }												\
 																															\
 																															\

+ 12 - 2
Source/BansheeEngine/Include/BsGUIManager.h

@@ -13,6 +13,7 @@
 #include "BsMatrix4.h"
 #include "BsMatrix4.h"
 #include "BsEvent.h"
 #include "BsEvent.h"
 #include "BsMaterialParam.h"
 #include "BsMaterialParam.h"
+#include "BsParamBlocks.h"
 
 
 namespace bs
 namespace bs
 {
 {
@@ -77,6 +78,7 @@ namespace bs
 			Color tint;
 			Color tint;
 			Matrix4 worldTransform;
 			Matrix4 worldTransform;
 			SPtr<SpriteMaterialExtraInfo> additionalData;
 			SPtr<SpriteMaterialExtraInfo> additionalData;
+			UINT32 bufferIdx;
 		};
 		};
 
 
 		/**	Container for a GUI widget. */
 		/**	Container for a GUI widget. */
@@ -419,6 +421,13 @@ namespace bs
 		HEvent mMouseLeftWindowConn;
 		HEvent mMouseLeftWindowConn;
 	};
 	};
 
 
+	BS_PARAM_BLOCK_BEGIN(GUISpriteParamBuffer)
+		BS_PARAM_BLOCK_ENTRY(Matrix4, gWorldTransform)
+		BS_PARAM_BLOCK_ENTRY(float, gInvViewportWidth)
+		BS_PARAM_BLOCK_ENTRY(float, gInvViewportHeight)
+		BS_PARAM_BLOCK_ENTRY(Color, gTint)
+	BS_PARAM_BLOCK_END
+
 	/**	Handles GUI rendering on the core thread. */
 	/**	Handles GUI rendering on the core thread. */
 	class BS_EXPORT GUIManagerCore
 	class BS_EXPORT GUIManagerCore
 	{
 	{
@@ -434,7 +443,7 @@ namespace bs
 		/**
 		/**
 		 * Updates the internal data that determines what will be rendered on the next render() call.
 		 * Updates the internal data that determines what will be rendered on the next render() call.
 		 *
 		 *
-		 * @param[in]	data	GUI mesh/material per viewport.
+		 * @param[in]	perCameraData	GUI mesh/material per viewport.
 		 */
 		 */
 		void updateData(const UnorderedMap<SPtr<CameraCore>, Vector<GUIManager::GUICoreRenderData>>& perCameraData);
 		void updateData(const UnorderedMap<SPtr<CameraCore>, Vector<GUIManager::GUICoreRenderData>>& perCameraData);
 
 
@@ -442,6 +451,7 @@ namespace bs
 		void render(const SPtr<CameraCore>& camera);
 		void render(const SPtr<CameraCore>& camera);
 
 
 		UnorderedMap<SPtr<CameraCore>, Vector<GUIManager::GUICoreRenderData>> mPerCameraData;
 		UnorderedMap<SPtr<CameraCore>, Vector<GUIManager::GUICoreRenderData>> mPerCameraData;
+		Vector<GUISpriteParamBuffer*> mParamBlocks;
 		SPtr<SamplerStateCore> mSamplerState;
 		SPtr<SamplerStateCore> mSamplerState;
 	};
 	};
 
 
@@ -449,4 +459,4 @@ namespace bs
 	BS_EXPORT GUIManager& gGUIManager();
 	BS_EXPORT GUIManager& gGUIManager();
 
 
 	/** @} */
 	/** @} */
-}
+}

+ 4 - 9
Source/BansheeEngine/Include/BsSpriteMaterial.h

@@ -89,14 +89,12 @@ namespace bs
 		 * @param[in]	mesh			Mesh to render, containing vertices in screen space.
 		 * @param[in]	mesh			Mesh to render, containing vertices in screen space.
 		 * @param[in]	texture			Optional texture to render the mesh with.
 		 * @param[in]	texture			Optional texture to render the mesh with.
 		 * @param[in]	sampler			Optional sampler to render the texture with.
 		 * @param[in]	sampler			Optional sampler to render the texture with.
-		 * @param[in]	tint			Color tint to apply to the rendered mesh.
-		 * @param[in]	worldTransform	World transform to apply to the rendered mesh.
-		 * @param[in]	invViewportSize	Inverse size of the viewport the mesh will be rendered to.
+		 * @param[in]	paramBuffer		Buffer containing data GPU parameters.
 		 * @param[in]	additionalData	Optional additional data that might be required by the renderer.
 		 * @param[in]	additionalData	Optional additional data that might be required by the renderer.
 		 */
 		 */
 		virtual void render(const SPtr<MeshCoreBase>& mesh, const SPtr<TextureCore>& texture,
 		virtual void render(const SPtr<MeshCoreBase>& mesh, const SPtr<TextureCore>& texture,
-			const SPtr<SamplerStateCore>& sampler, const Color& tint, const Matrix4& worldTransform, 
-			const Vector2& invViewportSize, const SPtr<SpriteMaterialExtraInfo>& additionalData) const;
+			const SPtr<SamplerStateCore>& sampler, const SPtr<GpuParamBlockBufferCore>& paramBuffer, 
+			const SPtr<SpriteMaterialExtraInfo>& additionalData) const;
 
 
 	protected:
 	protected:
 		/** Perform initialization of core-thread specific objects. */
 		/** Perform initialization of core-thread specific objects. */
@@ -112,10 +110,7 @@ namespace bs
 		std::atomic<bool> mMaterialStored;
 		std::atomic<bool> mMaterialStored;
 
 
 		SPtr<GpuParamsSetCore> mParams;
 		SPtr<GpuParamsSetCore> mParams;
-		mutable MaterialParamMat4Core mWorldTransformParam;
-		mutable MaterialParamFloatCore mInvViewportWidthParam;
-		mutable MaterialParamFloatCore mInvViewportHeightParam;
-		mutable MaterialParamColorCore mTintParam;
+		UINT32 mParamBufferIdx;
 		mutable MaterialParamTextureCore mTextureParam;
 		mutable MaterialParamTextureCore mTextureParam;
 		mutable MaterialParamSampStateCore mSamplerParam;
 		mutable MaterialParamSampStateCore mSamplerParam;
 	};
 	};

+ 46 - 3
Source/BansheeEngine/Source/BsGUIManager.cpp

@@ -1743,6 +1743,9 @@ namespace bs
 		SPtr<CoreRenderer> activeRenderer = RendererManager::instance().getActive();
 		SPtr<CoreRenderer> activeRenderer = RendererManager::instance().getActive();
 		for (auto& cameraData : mPerCameraData)
 		for (auto& cameraData : mPerCameraData)
 			activeRenderer->unregisterRenderCallback(cameraData.first.get(), 30);
 			activeRenderer->unregisterRenderCallback(cameraData.first.get(), 30);
+
+		for(auto& entry : mParamBlocks)
+			bs_delete(entry);
 	}
 	}
 
 
 	void GUIManagerCore::initialize()
 	void GUIManagerCore::initialize()
@@ -1760,6 +1763,7 @@ namespace bs
 		bs_frame_mark();
 		bs_frame_mark();
 
 
 		{
 		{
+			// Assign new per camera data, and find if any cameras were added or removed
 			FrameSet<SPtr<CameraCore>> validCameras;
 			FrameSet<SPtr<CameraCore>> validCameras;
 
 
 			SPtr<CoreRenderer> activeRenderer = RendererManager::instance().getActive();
 			SPtr<CoreRenderer> activeRenderer = RendererManager::instance().getActive();
@@ -1806,6 +1810,35 @@ namespace bs
 				activeRenderer->unregisterRenderCallback(camera.get(), 30);
 				activeRenderer->unregisterRenderCallback(camera.get(), 30);
 				mPerCameraData.erase(camera);
 				mPerCameraData.erase(camera);
 			}
 			}
+
+			// Allocate GPU buffers containing the material parameters
+			UINT32 numBuffers = 0;
+			for (auto& cameraData : mPerCameraData)
+				numBuffers += (UINT32)cameraData.second.size();
+
+			UINT32 numAllocatedBuffers = (UINT32)mParamBlocks.size();
+			if (numBuffers > numAllocatedBuffers)
+			{
+				mParamBlocks.resize(numBuffers);
+
+				for (UINT32 i = numAllocatedBuffers; i < numBuffers; i++)
+					mParamBlocks[i] = bs_new<GUISpriteParamBuffer>();
+			}
+
+			UINT32 curBufferIdx = 0;
+			for (auto& cameraData : mPerCameraData)
+			{
+				for(auto& entry : cameraData.second)
+				{
+					GUISpriteParamBuffer* buffer = mParamBlocks[curBufferIdx];
+
+					buffer->gTint.set(entry.tint);
+					buffer->gWorldTransform.set(entry.worldTransform);
+
+					entry.bufferIdx = curBufferIdx;
+					curBufferIdx++;
+				}
+			}
 		}
 		}
 
 
 		bs_frame_clear();
 		bs_frame_clear();
@@ -1818,14 +1851,24 @@ namespace bs
 		float invViewportWidth = 1.0f / (camera->getViewport()->getWidth() * 0.5f);
 		float invViewportWidth = 1.0f / (camera->getViewport()->getWidth() * 0.5f);
 		float invViewportHeight = 1.0f / (camera->getViewport()->getHeight() * 0.5f);
 		float invViewportHeight = 1.0f / (camera->getViewport()->getHeight() * 0.5f);
 
 
-		Vector2 invViewportSize(invViewportWidth, invViewportHeight);
+		for (auto& entry : renderData)
+		{
+			GUISpriteParamBuffer* buffer = mParamBlocks[entry.bufferIdx];
+
+			buffer->gInvViewportWidth.set(invViewportWidth);
+			buffer->gInvViewportHeight.set(invViewportHeight);
+
+			buffer->getBuffer()->flushToGPU();
+		}
+
 		for (auto& entry : renderData)
 		for (auto& entry : renderData)
 		{
 		{
 			// TODO - I shouldn't be re-applying the entire material for each entry, instead just check which programs
 			// TODO - I shouldn't be re-applying the entire material for each entry, instead just check which programs
 			// changed, and apply only those + the modified constant buffers and/or texture.
 			// changed, and apply only those + the modified constant buffers and/or texture.
 
 
-			entry.material->render(entry.mesh, entry.texture, mSamplerState, entry.tint, entry.worldTransform, 
-				invViewportSize, entry.additionalData);
+			GUISpriteParamBuffer* buffer = mParamBlocks[entry.bufferIdx];
+
+			entry.material->render(entry.mesh, entry.texture, mSamplerState, buffer->getBuffer(), entry.additionalData);
 		}
 		}
 	}
 	}
 }
 }

+ 20 - 13
Source/BansheeEngine/Source/BsSpriteMaterial.cpp

@@ -6,6 +6,7 @@
 #include "BsMesh.h"
 #include "BsMesh.h"
 #include "BsShader.h"
 #include "BsShader.h"
 #include "BsRendererUtility.h"
 #include "BsRendererUtility.h"
+#include "BsGpuParamsSet.h"
 #include "BsCoreThread.h"
 #include "BsCoreThread.h"
 
 
 namespace bs
 namespace bs
@@ -31,18 +32,25 @@ namespace bs
 		assert(materialStored == true);
 		assert(materialStored == true);
 
 
 		mParams = mMaterial->createParamsSet();
 		mParams = mMaterial->createParamsSet();
+
 		SPtr<ShaderCore> shader = mMaterial->getShader();
 		SPtr<ShaderCore> shader = mMaterial->getShader();
+		if(shader->hasTextureParam("gMainTexture"))
+		{
+			mTextureParam = mMaterial->getParamTexture("gMainTexture");
+			mSamplerParam = mMaterial->getParamSamplerState("gMainTexSamp");
+		}
 
 
-		if(shader->hasTextureParam("mainTexture"))
+		static StringID GUIParamsSemantic = "GUIParams";
+		const Map<String, SHADER_PARAM_BLOCK_DESC>& paramBlockDescs = shader->getParamBlocks();
+
+		for (auto& paramBlockDesc : paramBlockDescs)
 		{
 		{
-			mTextureParam = mMaterial->getParamTexture("mainTexture");
-			mSamplerParam = mMaterial->getParamSamplerState("mainTexSamp");
+			if (paramBlockDesc.second.rendererSemantic == GUIParamsSemantic)
+				mParamBufferIdx = mParams->getParamBlockBufferIndex(paramBlockDesc.second.name);
 		}
 		}
 
 
-		mTintParam = mMaterial->getParamColor("tint");
-		mInvViewportWidthParam = mMaterial->getParamFloat("invViewportWidth");
-		mInvViewportHeightParam = mMaterial->getParamFloat("invViewportHeight");
-		mWorldTransformParam = mMaterial->getParamMat4("worldTransform");
+		if(mParamBufferIdx == -1)
+			LOGERR("Sprite material shader missing \"GUIParams\" block.");
 	}
 	}
 
 
 	void SpriteMaterial::destroy(const SPtr<MaterialCore>& material, const SPtr<GpuParamsSetCore>& params)
 	void SpriteMaterial::destroy(const SPtr<MaterialCore>& material, const SPtr<GpuParamsSetCore>& params)
@@ -66,8 +74,8 @@ namespace bs
 	}
 	}
 
 
 	void SpriteMaterial::render(const SPtr<MeshCoreBase>& mesh, const SPtr<TextureCore>& texture,
 	void SpriteMaterial::render(const SPtr<MeshCoreBase>& mesh, const SPtr<TextureCore>& texture,
-		const SPtr<SamplerStateCore>& sampler, const Color& tint, const Matrix4& worldTransform,
-		const Vector2& invViewportSize, const SPtr<SpriteMaterialExtraInfo>& additionalData) const
+		const SPtr<SamplerStateCore>& sampler, const SPtr<GpuParamBlockBufferCore>& paramBuffer,
+		const SPtr<SpriteMaterialExtraInfo>& additionalData) const
 	{
 	{
 		SPtr<TextureCore> spriteTexture;
 		SPtr<TextureCore> spriteTexture;
 		if (texture != nullptr)
 		if (texture != nullptr)
@@ -77,10 +85,9 @@ namespace bs
 
 
 		mTextureParam.set(spriteTexture);
 		mTextureParam.set(spriteTexture);
 		mSamplerParam.set(sampler);
 		mSamplerParam.set(sampler);
-		mTintParam.set(tint);
-		mInvViewportWidthParam.set(invViewportSize.x);
-		mInvViewportHeightParam.set(invViewportSize.y);
-		mWorldTransformParam.set(worldTransform);
+
+		if(mParamBufferIdx != -1)
+			mParams->setParamBlockBuffer(mParamBufferIdx, paramBuffer, true);
 
 
 		mMaterial->updateParamsSet(mParams);
 		mMaterial->updateParamsSet(mParams);
 
 

+ 19 - 25
Source/BansheeGLRenderAPI/Source/BsGLRenderAPI.cpp

@@ -55,7 +55,7 @@ namespace bs
 		, mActivePipeline(nullptr)
 		, mActivePipeline(nullptr)
 		, mCurrentDrawOperation(DOT_TRIANGLE_LIST)
 		, mCurrentDrawOperation(DOT_TRIANGLE_LIST)
 		, mDrawCallInProgress(false)
 		, mDrawCallInProgress(false)
-		, mActiveTextureUnit(0)
+		, mActiveTextureUnit(-1)
 	{
 	{
 		// Get our GLSupport
 		// Get our GLSupport
 		mGLSupport = bs::getGLSupport();
 		mGLSupport = bs::getGLSupport();
@@ -356,17 +356,15 @@ namespace bs
 				FrameVector<UINT32> textureUnits(12);
 				FrameVector<UINT32> textureUnits(12);
 				auto getTexUnit = [&](UINT32 binding)
 				auto getTexUnit = [&](UINT32 binding)
 				{
 				{
-					UINT32 unit;
-
-					auto iterFind = std::find(textureUnits.begin(), textureUnits.end(), binding);
-					if (iterFind != textureUnits.end())
-						unit = *iterFind;
-					else
+					for(UINT32 i = 0; i < (UINT32)textureUnits.size(); i++)
 					{
 					{
-						unit = textureUnitCount++;
-						textureUnits.push_back(binding);
+						if (textureUnits[i] == binding)
+							return i;
 					}
 					}
 
 
+					UINT32 unit = textureUnitCount++;
+					textureUnits.push_back(binding);
+
 					return unit;
 					return unit;
 				};
 				};
 
 
@@ -374,17 +372,15 @@ namespace bs
 				FrameVector<UINT32> imageUnits(6);
 				FrameVector<UINT32> imageUnits(6);
 				auto getImageUnit = [&](UINT32 binding)
 				auto getImageUnit = [&](UINT32 binding)
 				{
 				{
-					UINT32 unit;
-
-					auto iterFind = std::find(imageUnits.begin(), imageUnits.end(), binding);
-					if (iterFind != imageUnits.end())
-						unit = *iterFind;
-					else
+					for (UINT32 i = 0; i < (UINT32)imageUnits.size(); i++)
 					{
 					{
-						unit = imageUnitCount++;
-						imageUnits.push_back(binding);
+						if (imageUnits[i] == binding)
+							return i;
 					}
 					}
 
 
+					UINT32 unit = imageUnitCount++;
+					imageUnits.push_back(binding);
+
 					return unit;
 					return unit;
 				};
 				};
 
 
@@ -392,17 +388,15 @@ namespace bs
 				FrameVector<UINT32> uniformUnits(6);
 				FrameVector<UINT32> uniformUnits(6);
 				auto getUniformUnit = [&](UINT32 binding)
 				auto getUniformUnit = [&](UINT32 binding)
 				{
 				{
-					UINT32 unit;
-
-					auto iterFind = std::find(uniformUnits.begin(), uniformUnits.end(), binding);
-					if (iterFind != uniformUnits.end())
-						unit = *iterFind;
-					else
+					for (UINT32 i = 0; i < (UINT32)uniformUnits.size(); i++)
 					{
 					{
-						unit = uniformUnitCount++;
-						uniformUnits.push_back(binding);
+						if (uniformUnits[i] == binding)
+							return i;
 					}
 					}
 
 
+					UINT32 unit = uniformUnitCount++;
+					uniformUnits.push_back(binding);
+
 					return unit;
 					return unit;
 				};
 				};