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

GUI and debug draw now use parameter handles for faster way of setting material parameters

Marko Pintera 12 лет назад
Родитель
Сommit
564bb9b499
42 измененных файлов с 283 добавлено и 139 удалено
  1. 2 0
      BansheeEngine/BansheeEngine.vcxproj
  2. 6 0
      BansheeEngine/BansheeEngine.vcxproj.filters
  3. 7 5
      BansheeEngine/Include/BsBuiltinMaterialManager.h
  4. 25 0
      BansheeEngine/Include/BsDebugDrawMaterialInfo.h
  5. 1 1
      BansheeEngine/Include/BsDrawHelper2D.h
  6. 6 1
      BansheeEngine/Include/BsDrawHelperTemplate.h
  7. 1 1
      BansheeEngine/Include/BsGUIButtonBase.h
  8. 1 1
      BansheeEngine/Include/BsGUIElement.h
  9. 1 0
      BansheeEngine/Include/BsGUIElementBase.h
  10. 1 1
      BansheeEngine/Include/BsGUIInputBox.h
  11. 1 1
      BansheeEngine/Include/BsGUILabel.h
  12. 2 1
      BansheeEngine/Include/BsGUIManager.h
  13. 16 0
      BansheeEngine/Include/BsGUIMaterialInfo.h
  14. 5 4
      BansheeEngine/Include/BsGUIMaterialManager.h
  15. 1 1
      BansheeEngine/Include/BsGUIScrollArea.h
  16. 1 1
      BansheeEngine/Include/BsGUIScrollBar.h
  17. 1 1
      BansheeEngine/Include/BsGUIScrollBarHandle.h
  18. 1 1
      BansheeEngine/Include/BsGUITexture.h
  19. 1 1
      BansheeEngine/Include/BsGUIViewport.h
  20. 4 1
      BansheeEngine/Include/BsRenderable.h
  21. 3 2
      BansheeEngine/Include/BsSprite.h
  22. 37 10
      BansheeEngine/Source/BsBuiltinMaterialManager.cpp
  23. 10 10
      BansheeEngine/Source/BsDrawHelper2D.cpp
  24. 5 5
      BansheeEngine/Source/BsDrawHelper3D.cpp
  25. 21 9
      BansheeEngine/Source/BsDrawHelperTemplate.cpp
  26. 1 1
      BansheeEngine/Source/BsGUIButtonBase.cpp
  27. 1 1
      BansheeEngine/Source/BsGUIInputBox.cpp
  28. 1 1
      BansheeEngine/Source/BsGUILabel.cpp
  29. 11 11
      BansheeEngine/Source/BsGUIManager.cpp
  30. 21 21
      BansheeEngine/Source/BsGUIMaterialManager.cpp
  31. 1 1
      BansheeEngine/Source/BsGUIScrollArea.cpp
  32. 1 1
      BansheeEngine/Source/BsGUIScrollBar.cpp
  33. 1 1
      BansheeEngine/Source/BsGUIScrollBarHandle.cpp
  34. 1 1
      BansheeEngine/Source/BsGUITexture.cpp
  35. 1 1
      BansheeEngine/Source/BsGUIViewport.cpp
  36. 15 4
      BansheeEngine/Source/BsImageSprite.cpp
  37. 15 1
      BansheeEngine/Source/BsRenderable.cpp
  38. 4 4
      BansheeEngine/Source/BsSprite.cpp
  39. 17 6
      BansheeEngine/Source/BsTextSprite.cpp
  40. 1 14
      BansheeForwardRenderer/Source/BsForwardRenderer.cpp
  41. 10 3
      CamelotCore/Include/CmGpuParam.h
  42. 21 9
      CamelotCore/Source/CmGpuParam.cpp

+ 2 - 0
BansheeEngine/BansheeEngine.vcxproj

@@ -238,6 +238,7 @@
     <ClInclude Include="Include\BsGUICommandEvent.h" />
     <ClInclude Include="Include\BsGUICommandEvent.h" />
     <ClInclude Include="Include\BsGUIContent.h" />
     <ClInclude Include="Include\BsGUIContent.h" />
     <ClInclude Include="Include\BsGUIContextMenu.h" />
     <ClInclude Include="Include\BsGUIContextMenu.h" />
+    <ClInclude Include="Include\BsDebugDrawMaterialInfo.h" />
     <ClInclude Include="Include\BsGUIDropDownBox.h" />
     <ClInclude Include="Include\BsGUIDropDownBox.h" />
     <ClInclude Include="Include\BsGUIDropDownBoxManager.h" />
     <ClInclude Include="Include\BsGUIDropDownBoxManager.h" />
     <ClInclude Include="Include\BsGUIHelper.h" />
     <ClInclude Include="Include\BsGUIHelper.h" />
@@ -245,6 +246,7 @@
     <ClInclude Include="Include\BsGUIElementBase.h" />
     <ClInclude Include="Include\BsGUIElementBase.h" />
     <ClInclude Include="Include\BsGUIInputTool.h" />
     <ClInclude Include="Include\BsGUIInputTool.h" />
     <ClInclude Include="Include\BsGUIInputBox.h" />
     <ClInclude Include="Include\BsGUIInputBox.h" />
+    <ClInclude Include="Include\BsGUIMaterialInfo.h" />
     <ClInclude Include="Include\BsGUIOptions.h" />
     <ClInclude Include="Include\BsGUIOptions.h" />
     <ClInclude Include="Include\BsGUIRenderTexture.h" />
     <ClInclude Include="Include\BsGUIRenderTexture.h" />
     <ClInclude Include="Include\BsGUITextInputEvent.h" />
     <ClInclude Include="Include\BsGUITextInputEvent.h" />

+ 6 - 0
BansheeEngine/BansheeEngine.vcxproj.filters

@@ -231,6 +231,12 @@
     <ClInclude Include="Include\BsGUIRenderTexture.h">
     <ClInclude Include="Include\BsGUIRenderTexture.h">
       <Filter>Header Files\GUI</Filter>
       <Filter>Header Files\GUI</Filter>
     </ClInclude>
     </ClInclude>
+    <ClInclude Include="Include\BsGUIMaterialInfo.h">
+      <Filter>Header Files\GUI</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsDebugDrawMaterialInfo.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
   </ItemGroup>
   </ItemGroup>
   <ItemGroup>
   <ItemGroup>
     <ClCompile Include="Source\BsGUIElement.cpp">
     <ClCompile Include="Source\BsGUIElement.cpp">

+ 7 - 5
BansheeEngine/Include/BsBuiltinMaterialManager.h

@@ -1,6 +1,8 @@
 #pragma once
 #pragma once
 
 
 #include "BsPrerequisites.h"
 #include "BsPrerequisites.h"
+#include "BsGUIMaterialInfo.h"
+#include "BsDebugDrawMaterialInfo.h"
 #include "CmModule.h"
 #include "CmModule.h"
 
 
 namespace BansheeEngine
 namespace BansheeEngine
@@ -34,11 +36,11 @@ namespace BansheeEngine
 		BuiltinMaterialManager();
 		BuiltinMaterialManager();
 		~BuiltinMaterialManager();
 		~BuiltinMaterialManager();
 
 
-		CM::HMaterial createSpriteTextMaterial() const;
-		CM::HMaterial createSpriteImageMaterial() const;
-		CM::HMaterial createDebugDraw2DClipSpaceMaterial() const;
-		CM::HMaterial createDebugDraw2DScreenSpaceMaterial() const;
-		CM::HMaterial createDebugDraw3DMaterial() const;
+		GUIMaterialInfo createSpriteTextMaterial() const;
+		GUIMaterialInfo createSpriteImageMaterial() const;
+		DebugDraw2DClipSpaceMatInfo createDebugDraw2DClipSpaceMaterial() const;
+		DebugDraw2DScreenSpaceMatInfo createDebugDraw2DScreenSpaceMaterial() const;
+		DebugDraw3DMatInfo createDebugDraw3DMaterial() const;
 		CM::HMaterial createDockDropOverlayMaterial() const;
 		CM::HMaterial createDockDropOverlayMaterial() const;
 
 
 		void addFactory(BuiltinMaterialFactory* factory);
 		void addFactory(BuiltinMaterialFactory* factory);

+ 25 - 0
BansheeEngine/Include/BsDebugDrawMaterialInfo.h

@@ -0,0 +1,25 @@
+#pragma once
+
+#include "BsPrerequisites.h"
+#include "CmGpuParam.h"
+
+namespace BansheeEngine
+{
+	struct DebugDraw2DClipSpaceMatInfo
+	{
+		CM::HMaterial material;
+	};
+
+	struct DebugDraw2DScreenSpaceMatInfo
+	{
+		CM::HMaterial material;
+		CM::GpuParamFloat invViewportWidth;
+		CM::GpuParamFloat invViewportHeight;
+	};
+
+	struct DebugDraw3DMatInfo
+	{
+		CM::HMaterial material;
+		CM::GpuParamMat4 matViewProj;
+	};
+}

+ 1 - 1
BansheeEngine/Include/BsDrawHelper2D.h

@@ -113,7 +113,7 @@ namespace BansheeEngine
 			const CM::Color& color = CM::Color::White, DebugDrawCoordType coordType = DebugDrawCoordType::Pixel, float timeout = 0.0f);
 			const CM::Color& color = CM::Color::White, DebugDrawCoordType coordType = DebugDrawCoordType::Pixel, float timeout = 0.0f);
 
 
 	private:
 	private:
-		CM::HMaterial mMaterial2DClipSpace;
+		DebugDraw2DClipSpaceMatInfo mMaterial2DClipSpace;
 
 
 		CM::FRect normalizedCoordToClipSpace(const CM::FRect& area) const;
 		CM::FRect normalizedCoordToClipSpace(const CM::FRect& area) const;
 		CM::Vector2 normalizedCoordToClipSpace(const CM::Vector2& pos) const;
 		CM::Vector2 normalizedCoordToClipSpace(const CM::Vector2& pos) const;

+ 6 - 1
BansheeEngine/Include/BsDrawHelperTemplate.h

@@ -1,6 +1,7 @@
 #pragma once
 #pragma once
 
 
 #include "BsPrerequisites.h"
 #include "BsPrerequisites.h"
+#include "BsDebugDrawMaterialInfo.h"
 #include "CmColor.h"
 #include "CmColor.h"
 #include "CmAABox.h"
 #include "CmAABox.h"
 
 
@@ -29,7 +30,11 @@ namespace BansheeEngine
 	struct DebugDrawCommand
 	struct DebugDrawCommand
 	{
 	{
 		CM::HMesh mesh;
 		CM::HMesh mesh;
-		CM::HMaterial material;
+
+		DebugDraw2DClipSpaceMatInfo matInfo2DClipSpace;
+		DebugDraw2DScreenSpaceMatInfo matInfo2DScreenSpace;
+		DebugDraw3DMatInfo matInfo3D;
+
 		DebugDrawType type;
 		DebugDrawType type;
 		CM::Vector3 worldCenter;
 		CM::Vector3 worldCenter;
 		float endTime;
 		float endTime;

+ 1 - 1
BansheeEngine/Include/BsGUIButtonBase.h

@@ -44,7 +44,7 @@ namespace BansheeEngine
 		/**
 		/**
 		 * @copydoc GUIElement::getMaterial()
 		 * @copydoc GUIElement::getMaterial()
 		 */
 		 */
-		virtual const CM::HMaterial& getMaterial(CM::UINT32 renderElementIdx) const;
+		virtual const GUIMaterialInfo& getMaterial(CM::UINT32 renderElementIdx) const;
 
 
 		/**
 		/**
 		 * @copydoc GUIElement::getNumQuads()
 		 * @copydoc GUIElement::getNumQuads()

+ 1 - 1
BansheeEngine/Include/BsGUIElement.h

@@ -32,7 +32,7 @@ namespace BansheeEngine
 		 * 		
 		 * 		
 		 * @return	Handle to the material.
 		 * @return	Handle to the material.
 		 */
 		 */
-		virtual const CM::HMaterial& getMaterial(CM::UINT32 renderElementIdx) const = 0;
+		virtual const GUIMaterialInfo& getMaterial(CM::UINT32 renderElementIdx) const = 0;
 
 
 		/**
 		/**
 		 * @brief	Returns the number of quads that the specified render element will use. You will need this
 		 * @brief	Returns the number of quads that the specified render element will use. You will need this

+ 1 - 0
BansheeEngine/Include/BsGUIElementBase.h

@@ -1,6 +1,7 @@
 #pragma once
 #pragma once
 
 
 #include "BsPrerequisites.h"
 #include "BsPrerequisites.h"
+#include "BsGUIMaterialInfo.h"
 #include "BsGUILayoutOptions.h"
 #include "BsGUILayoutOptions.h"
 #include "CmRect.h"
 #include "CmRect.h"
 #include "CmInt2.h"
 #include "CmInt2.h"

+ 1 - 1
BansheeEngine/Include/BsGUIInputBox.h

@@ -25,7 +25,7 @@ namespace BansheeEngine
 		/**
 		/**
 		 * @copydoc GUIElement::getMaterial()
 		 * @copydoc GUIElement::getMaterial()
 		 */
 		 */
-		virtual const CM::HMaterial& getMaterial(CM::UINT32 renderElementIdx) const;
+		virtual const GUIMaterialInfo& getMaterial(CM::UINT32 renderElementIdx) const;
 
 
 		/**
 		/**
 		 * @copydoc GUIElement::getNumQuads()
 		 * @copydoc GUIElement::getNumQuads()

+ 1 - 1
BansheeEngine/Include/BsGUILabel.h

@@ -31,7 +31,7 @@ namespace BansheeEngine
 		/**
 		/**
 		 * @copydoc GUIElement::getMaterial()
 		 * @copydoc GUIElement::getMaterial()
 		 */
 		 */
-		virtual const CM::HMaterial& getMaterial(CM::UINT32 renderElementIdx) const;
+		virtual const GUIMaterialInfo& getMaterial(CM::UINT32 renderElementIdx) const;
 
 
 		/**
 		/**
 		 * @copydoc GUIElement::getNumQuads()
 		 * @copydoc GUIElement::getNumQuads()

+ 2 - 1
BansheeEngine/Include/BsGUIManager.h

@@ -4,6 +4,7 @@
 #include "BsGUIMouseEvent.h"
 #include "BsGUIMouseEvent.h"
 #include "BsGUITextInputEvent.h"
 #include "BsGUITextInputEvent.h"
 #include "BsGUICommandEvent.h"
 #include "BsGUICommandEvent.h"
+#include "BsGUIMaterialInfo.h"
 #include "CmModule.h"
 #include "CmModule.h"
 #include "CmColor.h"
 #include "CmColor.h"
 #include "CmInput.h"
 #include "CmInput.h"
@@ -30,7 +31,7 @@ namespace BansheeEngine
 			{ }
 			{ }
 
 
 			CM::Vector<CM::HMesh>::type cachedMeshes;
 			CM::Vector<CM::HMesh>::type cachedMeshes;
-			CM::Vector<CM::HMaterial>::type cachedMaterials;
+			CM::Vector<GUIMaterialInfo>::type cachedMaterials;
 			CM::Vector<GUIWidget*>::type cachedWidgetsPerMesh;
 			CM::Vector<GUIWidget*>::type cachedWidgetsPerMesh;
 			CM::Vector<GUIWidget*>::type widgets;
 			CM::Vector<GUIWidget*>::type widgets;
 			bool isDirty;
 			bool isDirty;

+ 16 - 0
BansheeEngine/Include/BsGUIMaterialInfo.h

@@ -0,0 +1,16 @@
+#pragma once
+
+#include "BsPrerequisites.h"
+#include "CmGpuParam.h"
+
+namespace BansheeEngine
+{
+	struct GUIMaterialInfo
+	{
+		CM::HMaterial material;
+		CM::GpuParamMat4 worldTransform;
+		CM::GpuParamFloat invViewportWidth;
+		CM::GpuParamFloat invViewportHeight;
+		CM::GpuParamTexture mainTexture;
+	};
+}

+ 5 - 4
BansheeEngine/Include/BsGUIMaterialManager.h

@@ -1,6 +1,7 @@
 #pragma once
 #pragma once
 
 
 #include "BsPrerequisites.h"
 #include "BsPrerequisites.h"
+#include "BsGUIMaterialInfo.h"
 #include "CmModule.h"
 #include "CmModule.h"
 
 
 namespace BansheeEngine
 namespace BansheeEngine
@@ -20,7 +21,7 @@ namespace BansheeEngine
 		 *			
 		 *			
 		 *			Make sure to release all materials with a call to "releaseMaterial()".
 		 *			Make sure to release all materials with a call to "releaseMaterial()".
 		 */
 		 */
-		const CM::HMaterial& requestTextMaterial(const CM::HTexture& texture) const;
+		const GUIMaterialInfo& requestTextMaterial(const CM::HTexture& texture) const;
 
 
 		/**
 		/**
 		 * @brief	Creates a new material, or returns a reference to an existing one based on
 		 * @brief	Creates a new material, or returns a reference to an existing one based on
@@ -30,13 +31,13 @@ namespace BansheeEngine
 		 *			
 		 *			
 		 *			Make sure to release all materials with a call to "releaseMaterial()".
 		 *			Make sure to release all materials with a call to "releaseMaterial()".
 		 */
 		 */
-		const CM::HMaterial& requestImageMaterial(const CM::HTexture& texture) const;
+		const GUIMaterialInfo& requestImageMaterial(const CM::HTexture& texture) const;
 
 
 		/**
 		/**
 		 * @brief	Releases the held reference to the material. This allows us to fully unload a material
 		 * @brief	Releases the held reference to the material. This allows us to fully unload a material
 		 * 			and their textures when they are no longer being used.
 		 * 			and their textures when they are no longer being used.
 		 */
 		 */
-		void releaseMaterial(const CM::HMaterial& material) const;
+		void releaseMaterial(const GUIMaterialInfo& material) const;
 
 
 		void forceReleaseAllMaterials();
 		void forceReleaseAllMaterials();
 	private:
 	private:
@@ -46,7 +47,7 @@ namespace BansheeEngine
 				:refCount(0)
 				:refCount(0)
 			{ }
 			{ }
 
 
-			CM::HMaterial handle;
+			GUIMaterialInfo handle;
 			CM::UINT32 refCount;
 			CM::UINT32 refCount;
 		};
 		};
 
 

+ 1 - 1
BansheeEngine/Include/BsGUIScrollArea.h

@@ -26,7 +26,7 @@ namespace BansheeEngine
 		/**
 		/**
 		 * @copydoc GUIElement::getMaterial()
 		 * @copydoc GUIElement::getMaterial()
 		 */
 		 */
-		virtual const CM::HMaterial& getMaterial(CM::UINT32 renderElementIdx) const;
+		virtual const GUIMaterialInfo& getMaterial(CM::UINT32 renderElementIdx) const;
 
 
 		/**
 		/**
 		 * @copydoc GUIElement::getNumQuads()
 		 * @copydoc GUIElement::getNumQuads()

+ 1 - 1
BansheeEngine/Include/BsGUIScrollBar.h

@@ -35,7 +35,7 @@ namespace BansheeEngine
 		/**
 		/**
 		 * @copydoc GUIElement::getMaterial()
 		 * @copydoc GUIElement::getMaterial()
 		 */
 		 */
-		virtual const CM::HMaterial& getMaterial(CM::UINT32 renderElementIdx) const;
+		virtual const GUIMaterialInfo& getMaterial(CM::UINT32 renderElementIdx) const;
 
 
 		/**
 		/**
 		 * @copydoc GUIElement::getNumQuads()
 		 * @copydoc GUIElement::getNumQuads()

+ 1 - 1
BansheeEngine/Include/BsGUIScrollBarHandle.h

@@ -36,7 +36,7 @@ namespace BansheeEngine
 		/**
 		/**
 		 * @copydoc GUIElement::getMaterial()
 		 * @copydoc GUIElement::getMaterial()
 		 */
 		 */
-		virtual const CM::HMaterial& getMaterial(CM::UINT32 renderElementIdx) const;
+		virtual const GUIMaterialInfo& getMaterial(CM::UINT32 renderElementIdx) const;
 
 
 		/**
 		/**
 		 * @copydoc GUIElement::getNumQuads()
 		 * @copydoc GUIElement::getNumQuads()

+ 1 - 1
BansheeEngine/Include/BsGUITexture.h

@@ -43,7 +43,7 @@ namespace BansheeEngine
 		/**
 		/**
 		 * @copydoc GUIElement::getMaterial()
 		 * @copydoc GUIElement::getMaterial()
 		 */
 		 */
-		virtual const CM::HMaterial& getMaterial(CM::UINT32 renderElementIdx) const;
+		virtual const GUIMaterialInfo& getMaterial(CM::UINT32 renderElementIdx) const;
 
 
 		/**
 		/**
 		 * @copydoc GUIElement::getNumQuads()
 		 * @copydoc GUIElement::getNumQuads()

+ 1 - 1
BansheeEngine/Include/BsGUIViewport.h

@@ -35,7 +35,7 @@ namespace BansheeEngine
 		/**
 		/**
 		 * @copydoc GUIElement::getMaterial()
 		 * @copydoc GUIElement::getMaterial()
 		 */
 		 */
-		virtual const CM::HMaterial& getMaterial(CM::UINT32 renderElementIdx) const;
+		virtual const GUIMaterialInfo& getMaterial(CM::UINT32 renderElementIdx) const;
 
 
 		/**
 		/**
 		 * @copydoc GUIElement::getNumQuads()
 		 * @copydoc GUIElement::getNumQuads()

+ 4 - 1
BansheeEngine/Include/BsRenderable.h

@@ -3,6 +3,7 @@
 #include "BsPrerequisites.h"
 #include "BsPrerequisites.h"
 #include "CmComponent.h"
 #include "CmComponent.h"
 #include "CmAABox.h"
 #include "CmAABox.h"
+#include "CmGpuParam.h"
 
 
 namespace BansheeEngine
 namespace BansheeEngine
 {
 {
@@ -18,7 +19,7 @@ namespace BansheeEngine
 		CM::UINT32 getNumMaterials() const { return (CM::UINT32)mMaterials.size(); }
 		CM::UINT32 getNumMaterials() const { return (CM::UINT32)mMaterials.size(); }
 		CM::HMaterial& getMaterial(CM::UINT32 idx) { return mMaterials[idx]; }
 		CM::HMaterial& getMaterial(CM::UINT32 idx) { return mMaterials[idx]; }
 
 
-		void render(CM::RenderQueue& renderQueue);
+		void render(CM::RenderQueue& renderQueue, const CM::Matrix4& viewProjMatrix);
 		void updateWorldBounds();
 		void updateWorldBounds();
 	private:
 	private:
 		CM::HMesh mMesh;
 		CM::HMesh mMesh;
@@ -26,6 +27,8 @@ namespace BansheeEngine
 		CM::UINT64 mLayer;
 		CM::UINT64 mLayer;
 		CM::Vector<CM::AABox>::type mWorldBounds;
 		CM::Vector<CM::AABox>::type mWorldBounds;
 
 
+		CM::Vector<CM::GpuParamMat4>::type mMatViewProjParam;
+
 		/************************************************************************/
 		/************************************************************************/
 		/* 							COMPONENT OVERRIDES                    		*/
 		/* 							COMPONENT OVERRIDES                    		*/
 		/************************************************************************/
 		/************************************************************************/

+ 3 - 2
BansheeEngine/Include/BsSprite.h

@@ -1,6 +1,7 @@
 #pragma once
 #pragma once
 
 
 #include "BsPrerequisites.h"
 #include "BsPrerequisites.h"
+#include "BsGUIMaterialInfo.h"
 #include "CmInt2.h"
 #include "CmInt2.h"
 #include "CmRect.h"
 #include "CmRect.h"
 
 
@@ -29,7 +30,7 @@ namespace BansheeEngine
 		CM::Vector2* uvs;
 		CM::Vector2* uvs;
 		CM::UINT32* indexes;
 		CM::UINT32* indexes;
 		CM::UINT32 numQuads;
 		CM::UINT32 numQuads;
-		CM::HMaterial material;
+		GUIMaterialInfo matInfo;
 	};
 	};
 
 
 	class BS_EXPORT Sprite
 	class BS_EXPORT Sprite
@@ -55,7 +56,7 @@ namespace BansheeEngine
 		 * 		
 		 * 		
 		 * @return	Handle to the material.
 		 * @return	Handle to the material.
 		 */
 		 */
-		const CM::HMaterial& getMaterial(CM::UINT32 renderElementIdx) const;
+		const GUIMaterialInfo& getMaterial(CM::UINT32 renderElementIdx) const;
 
 
 		/**
 		/**
 		 * @brief	Returns the number of quads that the specified render element will use. You will need this
 		 * @brief	Returns the number of quads that the specified render element will use. You will need this

+ 37 - 10
BansheeEngine/Source/BsBuiltinMaterialManager.cpp

@@ -1,4 +1,5 @@
 #include "BsBuiltinMaterialManager.h"
 #include "BsBuiltinMaterialManager.h"
+#include "CmMaterial.h"
 
 
 using namespace CamelotFramework;
 using namespace CamelotFramework;
 
 
@@ -19,39 +20,65 @@ namespace BansheeEngine
 		}
 		}
 	}
 	}
 
 
-	HMaterial BuiltinMaterialManager::createSpriteTextMaterial() const
+	GUIMaterialInfo BuiltinMaterialManager::createSpriteTextMaterial() const
 	{
 	{
 		assert(mActiveFactory != nullptr);
 		assert(mActiveFactory != nullptr);
 
 
-		return mActiveFactory->createSpriteTextMaterial();
+		GUIMaterialInfo info;
+		info.material = mActiveFactory->createSpriteTextMaterial();
+		info.invViewportWidth = info.material->getParamFloat("invViewportWidth");
+		info.invViewportHeight = info.material->getParamFloat("invViewportHeight");
+		info.worldTransform = info.material->getParamMat4("worldTransform");
+		info.mainTexture = info.material->getParamTexture("mainTexture");
+
+		return info;
 	}
 	}
 
 
-	HMaterial BuiltinMaterialManager::createSpriteImageMaterial() const
+	GUIMaterialInfo BuiltinMaterialManager::createSpriteImageMaterial() const
 	{
 	{
 		assert(mActiveFactory != nullptr);
 		assert(mActiveFactory != nullptr);
 
 
-		return mActiveFactory->createSpriteImageMaterial();
+		GUIMaterialInfo info;
+		info.material = mActiveFactory->createSpriteImageMaterial();
+		info.invViewportWidth = info.material->getParamFloat("invViewportWidth");
+		info.invViewportHeight = info.material->getParamFloat("invViewportHeight");
+		info.worldTransform = info.material->getParamMat4("worldTransform");
+		info.mainTexture = info.material->getParamTexture("mainTexture");
+
+		return info;
 	}
 	}
 
 
-	HMaterial BuiltinMaterialManager::createDebugDraw2DClipSpaceMaterial() const
+	DebugDraw2DClipSpaceMatInfo BuiltinMaterialManager::createDebugDraw2DClipSpaceMaterial() const
 	{
 	{
 		assert(mActiveFactory != nullptr);
 		assert(mActiveFactory != nullptr);
 
 
-		return mActiveFactory->createDebugDraw2DClipSpaceMaterial();
+		DebugDraw2DClipSpaceMatInfo info;
+		info.material = mActiveFactory->createDebugDraw2DClipSpaceMaterial();
+
+		return info;
 	}
 	}
 
 
-	HMaterial BuiltinMaterialManager::createDebugDraw2DScreenSpaceMaterial() const
+	DebugDraw2DScreenSpaceMatInfo BuiltinMaterialManager::createDebugDraw2DScreenSpaceMaterial() const
 	{
 	{
 		assert(mActiveFactory != nullptr);
 		assert(mActiveFactory != nullptr);
 
 
-		return mActiveFactory->createDebugDraw2DScreenSpaceMaterial();
+		DebugDraw2DScreenSpaceMatInfo info;
+		info.material = mActiveFactory->createDebugDraw2DScreenSpaceMaterial();
+		info.invViewportWidth = info.material->getParamFloat("invViewportWidth");
+		info.invViewportHeight = info.material->getParamFloat("invViewportHeight");
+
+		return info;
 	}
 	}
 
 
-	HMaterial BuiltinMaterialManager::createDebugDraw3DMaterial() const
+	DebugDraw3DMatInfo BuiltinMaterialManager::createDebugDraw3DMaterial() const
 	{
 	{
 		assert(mActiveFactory != nullptr);
 		assert(mActiveFactory != nullptr);
 
 
-		return mActiveFactory->createDebugDraw3DMaterial();
+		DebugDraw3DMatInfo info;
+		info.material = mActiveFactory->createDebugDraw3DMaterial();
+		info.matViewProj = info.material->getParamMat4("matViewProj");
+
+		return info;
 	}
 	}
 
 
 	CM::HMaterial BuiltinMaterialManager::createDockDropOverlayMaterial() const
 	CM::HMaterial BuiltinMaterialManager::createDockDropOverlayMaterial() const

+ 10 - 10
BansheeEngine/Source/BsDrawHelper2D.cpp

@@ -111,12 +111,12 @@ namespace BansheeEngine
 		if(coordType == DebugDrawCoordType::Normalized)
 		if(coordType == DebugDrawCoordType::Normalized)
 		{
 		{
 			dbgCmd.type = DebugDrawType::ClipSpace;
 			dbgCmd.type = DebugDrawType::ClipSpace;
-			dbgCmd.material = mMaterial2DClipSpace;
+			dbgCmd.matInfo2DClipSpace = mMaterial2DClipSpace;
 		}
 		}
 		else
 		else
 		{
 		{
 			dbgCmd.type = DebugDrawType::ScreenSpace;
 			dbgCmd.type = DebugDrawType::ScreenSpace;
-			dbgCmd.material = BuiltinMaterialManager::instance().createDebugDraw2DScreenSpaceMaterial();
+			dbgCmd.matInfo2DScreenSpace = BuiltinMaterialManager::instance().createDebugDraw2DScreenSpaceMaterial();
 		}
 		}
 	}
 	}
 
 
@@ -160,12 +160,12 @@ namespace BansheeEngine
 		if(coordType == DebugDrawCoordType::Normalized)
 		if(coordType == DebugDrawCoordType::Normalized)
 		{
 		{
 			dbgCmd.type = DebugDrawType::ClipSpace;
 			dbgCmd.type = DebugDrawType::ClipSpace;
-			dbgCmd.material = mMaterial2DClipSpace;
+			dbgCmd.matInfo2DClipSpace = mMaterial2DClipSpace;
 		}
 		}
 		else
 		else
 		{
 		{
 			dbgCmd.type = DebugDrawType::ScreenSpace;
 			dbgCmd.type = DebugDrawType::ScreenSpace;
-			dbgCmd.material = BuiltinMaterialManager::instance().createDebugDraw2DScreenSpaceMaterial();
+			dbgCmd.matInfo2DScreenSpace = BuiltinMaterialManager::instance().createDebugDraw2DScreenSpaceMaterial();
 		}
 		}
 	}
 	}
 
 
@@ -209,12 +209,12 @@ namespace BansheeEngine
 		if(coordType == DebugDrawCoordType::Normalized)
 		if(coordType == DebugDrawCoordType::Normalized)
 		{
 		{
 			dbgCmd.type = DebugDrawType::ClipSpace;
 			dbgCmd.type = DebugDrawType::ClipSpace;
-			dbgCmd.material = mMaterial2DClipSpace;
+			dbgCmd.matInfo2DClipSpace = mMaterial2DClipSpace;
 		}
 		}
 		else
 		else
 		{
 		{
 			dbgCmd.type = DebugDrawType::ScreenSpace;
 			dbgCmd.type = DebugDrawType::ScreenSpace;
-			dbgCmd.material = BuiltinMaterialManager::instance().createDebugDraw2DScreenSpaceMaterial();
+			dbgCmd.matInfo2DScreenSpace = BuiltinMaterialManager::instance().createDebugDraw2DScreenSpaceMaterial();
 		}
 		}
 	}
 	}
 
 
@@ -263,12 +263,12 @@ namespace BansheeEngine
 		if(coordType == DebugDrawCoordType::Normalized)
 		if(coordType == DebugDrawCoordType::Normalized)
 		{
 		{
 			dbgCmd.type = DebugDrawType::ClipSpace;
 			dbgCmd.type = DebugDrawType::ClipSpace;
-			dbgCmd.material = mMaterial2DClipSpace;
+			dbgCmd.matInfo2DClipSpace = mMaterial2DClipSpace;
 		}
 		}
 		else
 		else
 		{
 		{
 			dbgCmd.type = DebugDrawType::ScreenSpace;
 			dbgCmd.type = DebugDrawType::ScreenSpace;
-			dbgCmd.material = BuiltinMaterialManager::instance().createDebugDraw2DScreenSpaceMaterial();
+			dbgCmd.matInfo2DScreenSpace = BuiltinMaterialManager::instance().createDebugDraw2DScreenSpaceMaterial();
 		}
 		}
 	}
 	}
 
 
@@ -317,12 +317,12 @@ namespace BansheeEngine
 		if(coordType == DebugDrawCoordType::Normalized)
 		if(coordType == DebugDrawCoordType::Normalized)
 		{
 		{
 			dbgCmd.type = DebugDrawType::ClipSpace;
 			dbgCmd.type = DebugDrawType::ClipSpace;
-			dbgCmd.material = mMaterial2DClipSpace;
+			dbgCmd.matInfo2DClipSpace = mMaterial2DClipSpace;
 		}
 		}
 		else
 		else
 		{
 		{
 			dbgCmd.type = DebugDrawType::ScreenSpace;
 			dbgCmd.type = DebugDrawType::ScreenSpace;
-			dbgCmd.material = BuiltinMaterialManager::instance().createDebugDraw2DScreenSpaceMaterial();
+			dbgCmd.matInfo2DScreenSpace = BuiltinMaterialManager::instance().createDebugDraw2DScreenSpaceMaterial();
 		}
 		}
 	}
 	}
 
 

+ 5 - 5
BansheeEngine/Source/BsDrawHelper3D.cpp

@@ -81,7 +81,7 @@ namespace BansheeEngine
 
 
 		dbgCmd.mesh = mesh;
 		dbgCmd.mesh = mesh;
 		dbgCmd.type = DebugDrawType::WorldSpace;
 		dbgCmd.type = DebugDrawType::WorldSpace;
-		dbgCmd.material = BuiltinMaterialManager::instance().createDebugDraw3DMaterial();
+		dbgCmd.matInfo3D = BuiltinMaterialManager::instance().createDebugDraw3DMaterial();
 	}
 	}
 
 
 	void DrawHelper3D::drawLine_AA(const HCamera& camera, const Vector3& a, const Vector3& b, float width, float borderWidth, const Color& color, float timeout)
 	void DrawHelper3D::drawLine_AA(const HCamera& camera, const Vector3& a, const Vector3& b, float width, float borderWidth, const Color& color, float timeout)
@@ -115,7 +115,7 @@ namespace BansheeEngine
 
 
 		dbgCmd.mesh = mesh;
 		dbgCmd.mesh = mesh;
 		dbgCmd.type = DebugDrawType::WorldSpace;
 		dbgCmd.type = DebugDrawType::WorldSpace;
-		dbgCmd.material = BuiltinMaterialManager::instance().createDebugDraw3DMaterial();
+		dbgCmd.matInfo3D = BuiltinMaterialManager::instance().createDebugDraw3DMaterial();
 	}
 	}
 
 
 	void DrawHelper3D::drawLineList_Pixel(const HCamera& camera, const Vector<Vector3>::type& linePoints, const Color& color, float timeout)
 	void DrawHelper3D::drawLineList_Pixel(const HCamera& camera, const Vector<Vector3>::type& linePoints, const Color& color, float timeout)
@@ -149,7 +149,7 @@ namespace BansheeEngine
 
 
 		dbgCmd.mesh = mesh;
 		dbgCmd.mesh = mesh;
 		dbgCmd.type = DebugDrawType::WorldSpace;
 		dbgCmd.type = DebugDrawType::WorldSpace;
-		dbgCmd.material = BuiltinMaterialManager::instance().createDebugDraw3DMaterial();
+		dbgCmd.matInfo3D = BuiltinMaterialManager::instance().createDebugDraw3DMaterial();
 	}
 	}
 
 
 	void DrawHelper3D::drawLineList_AA(const HCamera& camera, const CM::Vector<CM::Vector3>::type& linePoints, float width, float borderWidth, 
 	void DrawHelper3D::drawLineList_AA(const HCamera& camera, const CM::Vector<CM::Vector3>::type& linePoints, float width, float borderWidth, 
@@ -184,7 +184,7 @@ namespace BansheeEngine
 
 
 		dbgCmd.mesh = mesh;
 		dbgCmd.mesh = mesh;
 		dbgCmd.type = DebugDrawType::WorldSpace;
 		dbgCmd.type = DebugDrawType::WorldSpace;
-		dbgCmd.material = BuiltinMaterialManager::instance().createDebugDraw3DMaterial();
+		dbgCmd.matInfo3D = BuiltinMaterialManager::instance().createDebugDraw3DMaterial();
 	}
 	}
 
 
 	void DrawHelper3D::drawAABox(const HCamera& camera, const CM::AABox& box, const CM::Color& color, float timeout)
 	void DrawHelper3D::drawAABox(const HCamera& camera, const CM::AABox& box, const CM::Color& color, float timeout)
@@ -229,7 +229,7 @@ namespace BansheeEngine
 
 
 		dbgCmd.mesh = mesh;
 		dbgCmd.mesh = mesh;
 		dbgCmd.type = DebugDrawType::WorldSpace;
 		dbgCmd.type = DebugDrawType::WorldSpace;
-		dbgCmd.material = BuiltinMaterialManager::instance().createDebugDraw3DMaterial();
+		dbgCmd.matInfo3D = BuiltinMaterialManager::instance().createDebugDraw3DMaterial();
 	}
 	}
 
 
 	void DrawHelper3D::aabox(const AABox& box, UINT8* outVertices, UINT32 vertexOffset, UINT32 vertexStride, UINT32* outIndices, UINT32 indexOffset)
 	void DrawHelper3D::aabox(const AABox& box, UINT8* outVertices, UINT32 vertexOffset, UINT32 vertexStride, UINT32* outIndices, UINT32 indexOffset)

+ 21 - 9
BansheeEngine/Source/BsDrawHelperTemplate.cpp

@@ -31,25 +31,37 @@ namespace BansheeEngine
 			if(cmd.mesh == nullptr || !cmd.mesh.isLoaded() || !cmd.mesh->isInitialized())
 			if(cmd.mesh == nullptr || !cmd.mesh.isLoaded() || !cmd.mesh->isInitialized())
 				continue;
 				continue;
 
 
-			if(cmd.material == nullptr || !cmd.material.isLoaded() || !cmd.material->isInitialized())
-				continue;
-
 			if(cmd.type == DebugDrawType::ClipSpace)
 			if(cmd.type == DebugDrawType::ClipSpace)
 			{
 			{
-				renderQueue.add(cmd.material, cmd.mesh, 0, cmd.worldCenter);
+				HMaterial mat = cmd.matInfo2DClipSpace.material;
+
+				if(mat == nullptr || !mat.isLoaded() || !mat->isInitialized())
+					continue;
+
+				renderQueue.add(mat, cmd.mesh, 0, cmd.worldCenter);
 			}
 			}
 			else if(cmd.type == DebugDrawType::ScreenSpace)
 			else if(cmd.type == DebugDrawType::ScreenSpace)
 			{
 			{
-				cmd.material->setFloat("invViewportWidth", invViewportWidth);
-				cmd.material->setFloat("invViewportHeight", invViewportHeight);
+				HMaterial mat = cmd.matInfo2DScreenSpace.material;
 
 
-				renderQueue.add(cmd.material, cmd.mesh, 0, cmd.worldCenter);
+				if(mat == nullptr || !mat.isLoaded() || !mat->isInitialized())
+					continue;
+
+				cmd.matInfo2DScreenSpace.invViewportWidth.set(invViewportWidth);
+				cmd.matInfo2DScreenSpace.invViewportHeight.set(invViewportHeight);
+
+				renderQueue.add(mat, cmd.mesh, 0, cmd.worldCenter);
 			}
 			}
 			else if(cmd.type == DebugDrawType::WorldSpace)
 			else if(cmd.type == DebugDrawType::WorldSpace)
 			{
 			{
-				cmd.material->setMat4("matViewProj", viewProjMatrix);
+				HMaterial mat = cmd.matInfo3D.material;
+
+				if(mat == nullptr || !mat.isLoaded() || !mat->isInitialized())
+					continue;
+
+				cmd.matInfo3D.matViewProj.set(viewProjMatrix);
 
 
-				renderQueue.add(cmd.material, cmd.mesh, 0, cmd.worldCenter);
+				renderQueue.add(mat, cmd.mesh, 0, cmd.worldCenter);
 			}
 			}
 		}
 		}
 
 

+ 1 - 1
BansheeEngine/Source/BsGUIButtonBase.cpp

@@ -84,7 +84,7 @@ namespace BansheeEngine
 		return numElements;
 		return numElements;
 	}
 	}
 
 
-	const HMaterial& GUIButtonBase::getMaterial(UINT32 renderElementIdx) const
+	const GUIMaterialInfo& GUIButtonBase::getMaterial(UINT32 renderElementIdx) const
 	{
 	{
 		UINT32 textSpriteIdx = mImageSprite->getNumRenderElements();
 		UINT32 textSpriteIdx = mImageSprite->getNumRenderElements();
 		UINT32 contentImgSpriteIdx = textSpriteIdx + mTextSprite->getNumRenderElements();
 		UINT32 contentImgSpriteIdx = textSpriteIdx + mTextSprite->getNumRenderElements();

+ 1 - 1
BansheeEngine/Source/BsGUIInputBox.cpp

@@ -98,7 +98,7 @@ namespace BansheeEngine
 		return numElements;
 		return numElements;
 	}
 	}
 
 
-	const HMaterial& GUIInputBox::getMaterial(UINT32 renderElementIdx) const
+	const GUIMaterialInfo& GUIInputBox::getMaterial(UINT32 renderElementIdx) const
 	{
 	{
 		UINT32 localRenderElementIdx;
 		UINT32 localRenderElementIdx;
 		Sprite* sprite = renderElemToSprite(renderElementIdx, localRenderElementIdx);
 		Sprite* sprite = renderElemToSprite(renderElementIdx, localRenderElementIdx);

+ 1 - 1
BansheeEngine/Source/BsGUILabel.cpp

@@ -36,7 +36,7 @@ namespace BansheeEngine
 		return mTextSprite->getNumRenderElements();
 		return mTextSprite->getNumRenderElements();
 	}
 	}
 
 
-	const HMaterial& GUILabel::getMaterial(UINT32 renderElementIdx) const
+	const GUIMaterialInfo& GUILabel::getMaterial(UINT32 renderElementIdx) const
 	{
 	{
 		return mTextSprite->getMaterial(renderElementIdx);
 		return mTextSprite->getMaterial(renderElementIdx);
 	}
 	}

+ 11 - 11
BansheeEngine/Source/BsGUIManager.cpp

@@ -47,7 +47,7 @@ namespace BansheeEngine
 
 
 	struct GUIMaterialGroup
 	struct GUIMaterialGroup
 	{
 	{
-		HMaterial material;
+		GUIMaterialInfo matInfo;
 		UINT32 numQuads;
 		UINT32 numQuads;
 		UINT32 depth;
 		UINT32 depth;
 		Rect bounds;
 		Rect bounds;
@@ -244,10 +244,10 @@ namespace BansheeEngine
 			UINT32 meshIdx = 0;
 			UINT32 meshIdx = 0;
 			for(auto& mesh : renderData.cachedMeshes)
 			for(auto& mesh : renderData.cachedMeshes)
 			{
 			{
-				HMaterial material = renderData.cachedMaterials[meshIdx];
+				GUIMaterialInfo materialInfo = renderData.cachedMaterials[meshIdx];
 				GUIWidget* widget = renderData.cachedWidgetsPerMesh[meshIdx];
 				GUIWidget* widget = renderData.cachedWidgetsPerMesh[meshIdx];
 
 
-				if(material == nullptr || !material.isLoaded())
+				if(materialInfo.material == nullptr || !materialInfo.material.isLoaded())
 				{
 				{
 					meshIdx++;
 					meshIdx++;
 					continue;
 					continue;
@@ -259,11 +259,11 @@ namespace BansheeEngine
 					continue;
 					continue;
 				}
 				}
 
 
-				material->setFloat("invViewportWidth", invViewportWidth);
-				material->setFloat("invViewportHeight", invViewportHeight);
-				material->setMat4("worldTransform", widget->SO()->getWorldTfrm());
+				materialInfo.invViewportWidth.set(invViewportWidth);
+				materialInfo.invViewportHeight.set(invViewportHeight);
+				materialInfo.worldTransform.set(widget->SO()->getWorldTfrm());
 
 
-				renderQueue.add(material, mesh, 0, Vector3::ZERO);
+				renderQueue.add(materialInfo.material, mesh, 0, Vector3::ZERO);
 
 
 				meshIdx++;
 				meshIdx++;
 			}
 			}
@@ -348,9 +348,9 @@ namespace BansheeEngine
 				Rect tfrmedBounds = guiElem->_getClippedBounds();
 				Rect tfrmedBounds = guiElem->_getClippedBounds();
 				tfrmedBounds.transform(guiElem->_getParentWidget().SO()->getWorldTfrm());
 				tfrmedBounds.transform(guiElem->_getParentWidget().SO()->getWorldTfrm());
 
 
-				const HMaterial& mat = guiElem->getMaterial(renderElemIdx);
+				const GUIMaterialInfo& matInfo = guiElem->getMaterial(renderElemIdx);
 
 
-				UINT64 materialId = mat->getInternalID(); // TODO - I group based on material ID. So if two widgets used exact copies of the same material
+				UINT64 materialId = matInfo.material->getInternalID(); // TODO - I group based on material ID. So if two widgets used exact copies of the same material
 				// this system won't detect it. Find a better way of determining material similarity?
 				// this system won't detect it. Find a better way of determining material similarity?
 
 
 				// If this is a new material, add a new list of groups
 				// If this is a new material, add a new list of groups
@@ -421,7 +421,7 @@ namespace BansheeEngine
 					foundGroup->depth = elemDepth;
 					foundGroup->depth = elemDepth;
 					foundGroup->bounds = tfrmedBounds;
 					foundGroup->bounds = tfrmedBounds;
 					foundGroup->elements.push_back(GUIGroupElement(guiElem, renderElemIdx));
 					foundGroup->elements.push_back(GUIGroupElement(guiElem, renderElemIdx));
-					foundGroup->material = mat;
+					foundGroup->matInfo = matInfo;
 					foundGroup->numQuads = guiElem->getNumQuads(renderElemIdx);
 					foundGroup->numQuads = guiElem->getNumQuads(renderElemIdx);
 				}
 				}
 				else
 				else
@@ -463,7 +463,7 @@ namespace BansheeEngine
 			UINT32 groupIdx = 0;
 			UINT32 groupIdx = 0;
 			for(auto& group : sortedGroups)
 			for(auto& group : sortedGroups)
 			{
 			{
-				renderData.cachedMaterials[groupIdx] = group->material;
+				renderData.cachedMaterials[groupIdx] = group->matInfo;
 
 
 				if(mSeparateMeshesByWidget)
 				if(mSeparateMeshesByWidget)
 				{
 				{

+ 21 - 21
BansheeEngine/Source/BsGUIMaterialManager.cpp

@@ -7,58 +7,58 @@ using namespace CamelotFramework;
 
 
 namespace BansheeEngine
 namespace BansheeEngine
 {
 {
-	const HMaterial& GUIMaterialManager::requestTextMaterial(const HTexture& texture) const
+	const GUIMaterialInfo& GUIMaterialManager::requestTextMaterial(const HTexture& texture) const
 	{
 	{
 		for(auto& matHandle : mTextMaterials)
 		for(auto& matHandle : mTextMaterials)
 		{
 		{
-			const HMaterial& material = matHandle.handle;
-			if(material->getTexture("mainTexture") == texture)
+			if(matHandle.handle.mainTexture.get() == texture)
 			{
 			{
 				matHandle.refCount++;
 				matHandle.refCount++;
-				return material;
+				return matHandle.handle;
 			}
 			}
 		}
 		}
 
 
 		mTextMaterials.push_back(GUIMaterial());
 		mTextMaterials.push_back(GUIMaterial());
 
 
-		GUIMaterial& material = mTextMaterials[mTextMaterials.size() - 1];
-		material.handle = BuiltinMaterialManager::instance().createSpriteTextMaterial();
-		material.handle->setTexture("mainTexture", texture);
-		material.refCount = 1;		
+		GUIMaterial& guiMat = mTextMaterials[mTextMaterials.size() - 1];
+		guiMat.handle = BuiltinMaterialManager::instance().createSpriteTextMaterial();
 
 
-		return material.handle;
+		guiMat.handle.mainTexture.set(texture);
+		guiMat.refCount = 1;		
+
+		return guiMat.handle;
 	}
 	}
 
 
-	const HMaterial& GUIMaterialManager::requestImageMaterial(const HTexture& texture) const
+	const GUIMaterialInfo& GUIMaterialManager::requestImageMaterial(const HTexture& texture) const
 	{
 	{
 		for(auto& matHandle : mImageMaterials)
 		for(auto& matHandle : mImageMaterials)
 		{
 		{
-			const HMaterial& material = matHandle.handle;
-			if(material->getTexture("mainTexture") == texture)
+			if(matHandle.handle.mainTexture.get() == texture)
 			{
 			{
 				matHandle.refCount++;
 				matHandle.refCount++;
-				return material;
+				return matHandle.handle;
 			}
 			}
 		}
 		}
 
 
 		mImageMaterials.push_back(GUIMaterial());
 		mImageMaterials.push_back(GUIMaterial());
 
 
-		GUIMaterial& material = mImageMaterials[mImageMaterials.size() - 1];
-		material.handle = BuiltinMaterialManager::instance().createSpriteImageMaterial();
-		material.handle->setTexture("mainTexture", texture);
-		material.refCount = 1;		
+		GUIMaterial& guiMat = mImageMaterials[mImageMaterials.size() - 1];
+		guiMat.handle = BuiltinMaterialManager::instance().createSpriteImageMaterial();
+
+		guiMat.handle.mainTexture.set(texture);
+		guiMat.refCount = 1;		
 
 
-		return material.handle;
+		return guiMat.handle;
 	}
 	}
 
 
-	void GUIMaterialManager::releaseMaterial(const HMaterial& material) const
+	void GUIMaterialManager::releaseMaterial(const GUIMaterialInfo& material) const
 	{
 	{
 		bool released = false;
 		bool released = false;
 
 
 		UINT32 i = 0;
 		UINT32 i = 0;
 		for(auto& matHandle : mTextMaterials)
 		for(auto& matHandle : mTextMaterials)
 		{
 		{
-			if(matHandle.handle == material)
+			if(&matHandle.handle == &material)
 			{
 			{
 				if(--matHandle.refCount == 0)
 				if(--matHandle.refCount == 0)
 				{
 				{
@@ -74,7 +74,7 @@ namespace BansheeEngine
 		i = 0;
 		i = 0;
 		for(auto& matHandle : mImageMaterials)
 		for(auto& matHandle : mImageMaterials)
 		{
 		{
-			if(matHandle.handle == material)
+			if(&matHandle.handle == &material)
 			{
 			{
 				if(--matHandle.refCount == 0)
 				if(--matHandle.refCount == 0)
 				{
 				{

+ 1 - 1
BansheeEngine/Source/BsGUIScrollArea.cpp

@@ -35,7 +35,7 @@ namespace BansheeEngine
 		return 0;
 		return 0;
 	}
 	}
 
 
-	const HMaterial& GUIScrollArea::getMaterial(UINT32 renderElementIdx) const
+	const GUIMaterialInfo& GUIScrollArea::getMaterial(UINT32 renderElementIdx) const
 	{
 	{
 		CM_EXCEPT(InternalErrorException, "Trying to retrieve a material from an element with no render elements.");
 		CM_EXCEPT(InternalErrorException, "Trying to retrieve a material from an element with no render elements.");
 	}
 	}

+ 1 - 1
BansheeEngine/Source/BsGUIScrollBar.cpp

@@ -74,7 +74,7 @@ namespace BansheeEngine
 		return mImageSprite->getNumRenderElements();
 		return mImageSprite->getNumRenderElements();
 	}
 	}
 
 
-	const HMaterial& GUIScrollBar::getMaterial(UINT32 renderElementIdx) const
+	const GUIMaterialInfo& GUIScrollBar::getMaterial(UINT32 renderElementIdx) const
 	{
 	{
 		return mImageSprite->getMaterial(renderElementIdx);
 		return mImageSprite->getMaterial(renderElementIdx);
 	}
 	}

+ 1 - 1
BansheeEngine/Source/BsGUIScrollBarHandle.cpp

@@ -90,7 +90,7 @@ namespace BansheeEngine
 		return mImageSprite->getNumRenderElements();
 		return mImageSprite->getNumRenderElements();
 	}
 	}
 
 
-	const HMaterial& GUIScrollBarHandle::getMaterial(UINT32 renderElementIdx) const
+	const GUIMaterialInfo& GUIScrollBarHandle::getMaterial(UINT32 renderElementIdx) const
 	{
 	{
 		return mImageSprite->getMaterial(renderElementIdx);
 		return mImageSprite->getMaterial(renderElementIdx);
 	}
 	}

+ 1 - 1
BansheeEngine/Source/BsGUITexture.cpp

@@ -95,7 +95,7 @@ namespace BansheeEngine
 		return mImageSprite->getNumRenderElements();
 		return mImageSprite->getNumRenderElements();
 	}
 	}
 
 
-	const HMaterial& GUITexture::getMaterial(UINT32 renderElementIdx) const
+	const GUIMaterialInfo& GUITexture::getMaterial(UINT32 renderElementIdx) const
 	{
 	{
 		return mImageSprite->getMaterial(renderElementIdx);
 		return mImageSprite->getMaterial(renderElementIdx);
 	}
 	}

+ 1 - 1
BansheeEngine/Source/BsGUIViewport.cpp

@@ -65,7 +65,7 @@ namespace BansheeEngine
 		return 0;
 		return 0;
 	}
 	}
 
 
-	const HMaterial& GUIViewport::getMaterial(UINT32 renderElementIdx) const
+	const GUIMaterialInfo& GUIViewport::getMaterial(UINT32 renderElementIdx) const
 	{
 	{
 		CM_EXCEPT(InternalErrorException, "This element has no render element so no material can be retrieved.");
 		CM_EXCEPT(InternalErrorException, "This element has no render element so no material can be retrieved.");
 	}
 	}

+ 15 - 4
BansheeEngine/Source/BsImageSprite.cpp

@@ -56,11 +56,22 @@ namespace BansheeEngine
 				renderElem.numQuads = newNumQuads;
 				renderElem.numQuads = newNumQuads;
 			}
 			}
 
 
-			HMaterial newMaterial = GUIMaterialManager::instance().requestImageMaterial(desc.texture->getTexture());
-			if(renderElem.material != nullptr)
-				GUIMaterialManager::instance().releaseMaterial(renderElem.material);
+			const HTexture& tex = desc.texture->getTexture();
 
 
-			renderElem.material = newMaterial;
+			bool getNewMaterial = false;
+			if(renderElem.matInfo.material == nullptr)
+				getNewMaterial = true;
+			else
+			{
+				if(renderElem.matInfo.mainTexture.get() != tex)
+				{
+					GUIMaterialManager::instance().releaseMaterial(renderElem.matInfo);
+					getNewMaterial = true;
+				}
+			}
+
+			if(getNewMaterial)
+				renderElem.matInfo = GUIMaterialManager::instance().requestImageMaterial(tex);
 
 
 			texPage++;
 			texPage++;
 		}
 		}

+ 15 - 1
BansheeEngine/Source/BsRenderable.cpp

@@ -2,6 +2,7 @@
 #include "BsRenderableRTTI.h"
 #include "BsRenderableRTTI.h"
 #include "CmSceneObject.h"
 #include "CmSceneObject.h"
 #include "CmMesh.h"
 #include "CmMesh.h"
+#include "CmMaterial.h"
 #include "CmRenderQueue.h"
 #include "CmRenderQueue.h"
 
 
 using namespace CamelotFramework;
 using namespace CamelotFramework;
@@ -12,24 +13,28 @@ namespace BansheeEngine
 		:Component(parent), mLayer(1)
 		:Component(parent), mLayer(1)
 	{
 	{
 		mMaterials.resize(1);
 		mMaterials.resize(1);
+		mMatViewProjParam.resize(1);
 	}
 	}
 
 
 	void Renderable::setNumMaterials(CM::UINT32 numMaterials)
 	void Renderable::setNumMaterials(CM::UINT32 numMaterials)
 	{
 	{
 		mMaterials.resize(numMaterials);
 		mMaterials.resize(numMaterials);
+		mMatViewProjParam.resize(numMaterials);
 	}
 	}
 
 
 	void Renderable::setMaterial(CM::UINT32 idx, CM::HMaterial material)
 	void Renderable::setMaterial(CM::UINT32 idx, CM::HMaterial material)
 	{
 	{
 		mMaterials[idx] = material;
 		mMaterials[idx] = material;
+		mMatViewProjParam[idx] = material->getParamMat4("matViewProjection");
 	}
 	}
 
 
-	void Renderable::render(CM::RenderQueue& renderQueue)
+	void Renderable::render(CM::RenderQueue& renderQueue, const Matrix4& viewProjMatrix)
 	{
 	{
 		if(mMesh == nullptr || !mMesh.isLoaded())
 		if(mMesh == nullptr || !mMesh.isLoaded())
 			return;
 			return;
 
 
 		bool hasAtLeastOneMaterial = false;
 		bool hasAtLeastOneMaterial = false;
+		UINT32 idx = 0;
 		for(auto& material : mMaterials)
 		for(auto& material : mMaterials)
 		{
 		{
 			if(material != nullptr)
 			if(material != nullptr)
@@ -39,6 +44,15 @@ namespace BansheeEngine
 				if(!material.isLoaded()) // We wait until all materials are loaded
 				if(!material.isLoaded()) // We wait until all materials are loaded
 					return;
 					return;
 			}
 			}
+
+			// TODO - Do different things depending on material and renderable settings
+
+			// TODO - Renderer should ensure shader is compatible with it, and it contains all the needed parameters
+			// (probably at an earlier stage). e.g. I want the user to be warned if the shader doesn't contain matViewProjection param
+			// (or should we just ignore such missing parameters?)
+
+			mMatViewProjParam[idx].set(viewProjMatrix);
+			idx++;
 		}
 		}
 
 
 		if(hasAtLeastOneMaterial)
 		if(hasAtLeastOneMaterial)

+ 4 - 4
BansheeEngine/Source/BsSprite.cpp

@@ -34,9 +34,9 @@ namespace BansheeEngine
 		return (UINT32)mCachedRenderElements.size();
 		return (UINT32)mCachedRenderElements.size();
 	}
 	}
 
 
-	const HMaterial& Sprite::getMaterial(UINT32 renderElementIdx) const
+	const GUIMaterialInfo& Sprite::getMaterial(UINT32 renderElementIdx) const
 	{
 	{
-		return mCachedRenderElements.at(renderElementIdx).material;
+		return mCachedRenderElements.at(renderElementIdx).matInfo;
 	}
 	}
 
 
 	UINT32 Sprite::getNumQuads(UINT32 renderElementIdx) const
 	UINT32 Sprite::getNumQuads(UINT32 renderElementIdx) const
@@ -259,9 +259,9 @@ namespace BansheeEngine
 			if(renderElem.indexes != nullptr)
 			if(renderElem.indexes != nullptr)
 				cm_deleteN<ScratchAlloc>(renderElem.indexes, indexCount);
 				cm_deleteN<ScratchAlloc>(renderElem.indexes, indexCount);
 
 
-			if(renderElem.material != nullptr)
+			if(renderElem.matInfo.material != nullptr)
 			{
 			{
-				GUIMaterialManager::instance().releaseMaterial(renderElem.material);
+				GUIMaterialManager::instance().releaseMaterial(renderElem.matInfo);
 			}
 			}
 		}
 		}
 
 

+ 17 - 6
BansheeEngine/Source/BsTextSprite.cpp

@@ -45,9 +45,9 @@ namespace BansheeEngine
 				if(renderElem.indexes != nullptr)
 				if(renderElem.indexes != nullptr)
 					cm_deleteN<ScratchAlloc>(renderElem.indexes, indexCount);
 					cm_deleteN<ScratchAlloc>(renderElem.indexes, indexCount);
 
 
-				if(renderElem.material != nullptr)
+				if(renderElem.matInfo.material != nullptr)
 				{
 				{
-					GUIMaterialManager::instance().releaseMaterial(renderElem.material);
+					GUIMaterialManager::instance().releaseMaterial(renderElem.matInfo);
 				}
 				}
 			}
 			}
 		}
 		}
@@ -78,11 +78,22 @@ namespace BansheeEngine
 				cachedElem.numQuads = newNumQuads;
 				cachedElem.numQuads = newNumQuads;
 			}
 			}
 
 
-			HMaterial newMaterial = GUIMaterialManager::instance().requestTextMaterial(textData.getTextureForPage(texPage));
-			if(cachedElem.material != nullptr)
-				GUIMaterialManager::instance().releaseMaterial(cachedElem.material);
+			const HTexture& tex = textData.getTextureForPage(texPage);
 
 
-			cachedElem.material = newMaterial;
+			bool getNewMaterial = false;
+			if(cachedElem.matInfo.material == nullptr)
+				getNewMaterial = true;
+			else
+			{
+				if(cachedElem.matInfo.mainTexture.get() != tex)
+				{
+					GUIMaterialManager::instance().releaseMaterial(cachedElem.matInfo);
+					getNewMaterial = true;
+				}
+			}
+
+			if(getNewMaterial)
+				cachedElem.matInfo = GUIMaterialManager::instance().requestTextMaterial(tex);
 
 
 			texPage++;
 			texPage++;
 		}
 		}

+ 1 - 14
BansheeForwardRenderer/Source/BsForwardRenderer.cpp

@@ -148,20 +148,7 @@ namespace BansheeEngine
 		// Get scene render operations
 		// Get scene render operations
 		for(auto iter = allRenderables.begin(); iter != allRenderables.end(); ++iter)
 		for(auto iter = allRenderables.begin(); iter != allRenderables.end(); ++iter)
 		{
 		{
-			UINT32 numMaterials = (*iter)->getNumMaterials();
-
-			for(UINT32 i = 0; i < numMaterials; i++)
-			{
-				// TODO - Do different things depending on material and renderable settings
-				
-				// TODO - Renderer should ensure shader is compatible with it, and it contains all the needed parameters
-				// (probably at an earlier stage). e.g. I want the user to be warned if the shader doesn't contain matViewProjection param
-				// (or should we just ignore such missing parameters?)
-				HMaterial& material = (*iter)->getMaterial(i);
-				material->setMat4("matViewProjection", viewProjMatrix);
-			}
-
-			(*iter)->render(*mRenderQueue);
+			(*iter)->render(*mRenderQueue, viewProjMatrix);
 		}
 		}
 
 
 		gProfiler().endSample("renderD");
 		gProfiler().endSample("renderD");

+ 10 - 3
CamelotCore/Include/CmGpuParam.h

@@ -30,6 +30,10 @@ namespace CamelotFramework
 				:paramDesc(paramDesc), paramBlocks(paramBlocks), transpose(transpose), isDestroyed(false)
 				:paramDesc(paramDesc), paramBlocks(paramBlocks), transpose(transpose), isDestroyed(false)
 			{ }
 			{ }
 
 
+			InternalData()
+				:paramDesc(nullptr), paramBlocks(nullptr), transpose(false), isDestroyed(true)
+			{ }
+
 			~InternalData()
 			~InternalData()
 			{ }
 			{ }
 
 
@@ -62,6 +66,7 @@ namespace CamelotFramework
 
 
 	public:
 	public:
 		GpuDataParamBase()
 		GpuDataParamBase()
+			:mData(cm_shared_ptr<InternalData>())
 		{ }
 		{ }
 
 
 		void set(const T& value, UINT32 arrayIdx = 0)
 		void set(const T& value, UINT32 arrayIdx = 0)
@@ -133,9 +138,8 @@ namespace CamelotFramework
 
 
 	private:
 	private:
 		GpuDataParamBase(GpuParamDataDesc* paramDesc, GpuParamBlock** paramBlocks, bool transpose)
 		GpuDataParamBase(GpuParamDataDesc* paramDesc, GpuParamBlock** paramBlocks, bool transpose)
-		{
-			mData = cm_shared_ptr<InternalData>(paramDesc, paramBlocks, transpose);
-		}
+			:mData(cm_shared_ptr<InternalData>(paramDesc, paramBlocks, transpose))
+		{ }
 
 
 	private:
 	private:
 		std::shared_ptr<InternalData> mData;
 		std::shared_ptr<InternalData> mData;
@@ -159,6 +163,7 @@ namespace CamelotFramework
 		struct InternalData
 		struct InternalData
 		{
 		{
 			InternalData(GpuParamDataDesc* paramDesc, GpuParamBlock** paramBlocks);
 			InternalData(GpuParamDataDesc* paramDesc, GpuParamBlock** paramBlocks);
+			InternalData();
 			~InternalData();
 			~InternalData();
 
 
 			GpuParamDataDesc* paramDesc;
 			GpuParamDataDesc* paramDesc;
@@ -192,6 +197,7 @@ namespace CamelotFramework
 		struct InternalData
 		struct InternalData
 		{
 		{
 			InternalData(GpuParamObjectDesc* paramDesc, HTexture* textures);
 			InternalData(GpuParamObjectDesc* paramDesc, HTexture* textures);
+			InternalData();
 			~InternalData();
 			~InternalData();
 
 
 			GpuParamObjectDesc* paramDesc;
 			GpuParamObjectDesc* paramDesc;
@@ -224,6 +230,7 @@ namespace CamelotFramework
 		struct InternalData
 		struct InternalData
 		{
 		{
 			InternalData(GpuParamObjectDesc* paramDesc, HSamplerState* samplerStates);
 			InternalData(GpuParamObjectDesc* paramDesc, HSamplerState* samplerStates);
+			InternalData();
 			~InternalData();
 			~InternalData();
 
 
 			GpuParamObjectDesc* paramDesc;
 			GpuParamObjectDesc* paramDesc;

+ 21 - 9
CamelotCore/Source/CmGpuParam.cpp

@@ -10,16 +10,20 @@ namespace CamelotFramework
 		:paramDesc(paramDesc), paramBlocks(paramBlocks), isDestroyed(false)
 		:paramDesc(paramDesc), paramBlocks(paramBlocks), isDestroyed(false)
 	{ }
 	{ }
 
 
+	GpuParamStruct::InternalData::InternalData()
+		:paramDesc(nullptr), paramBlocks(nullptr), isDestroyed(true)
+	{ }
+
 	GpuParamStruct::InternalData::~InternalData()
 	GpuParamStruct::InternalData::~InternalData()
 	{ }
 	{ }
 
 
 	GpuParamStruct::GpuParamStruct()
 	GpuParamStruct::GpuParamStruct()
+		:mData(cm_shared_ptr<InternalData>())
 	{ }
 	{ }
 
 
 	GpuParamStruct::GpuParamStruct(GpuParamDataDesc* paramDesc, GpuParamBlock** paramBlocks)
 	GpuParamStruct::GpuParamStruct(GpuParamDataDesc* paramDesc, GpuParamBlock** paramBlocks)
-	{
-		mData = cm_shared_ptr<InternalData>(paramDesc, paramBlocks);
-	}
+		:mData(cm_shared_ptr<InternalData>(paramDesc, paramBlocks))
+	{ }
 
 
 	void GpuParamStruct::set(const void* value, UINT32 sizeBytes, UINT32 arrayIdx)
 	void GpuParamStruct::set(const void* value, UINT32 sizeBytes, UINT32 arrayIdx)
 	{
 	{
@@ -103,16 +107,20 @@ namespace CamelotFramework
 		:paramDesc(paramDesc), textures(textures), isDestroyed(false)
 		:paramDesc(paramDesc), textures(textures), isDestroyed(false)
 	{ }
 	{ }
 
 
+	GpuParamTexture::InternalData::InternalData()
+		:paramDesc(nullptr), textures(nullptr), isDestroyed(true)
+	{ }
+
 	GpuParamTexture::InternalData::~InternalData()
 	GpuParamTexture::InternalData::~InternalData()
 	{ }
 	{ }
 
 
 	GpuParamTexture::GpuParamTexture()
 	GpuParamTexture::GpuParamTexture()
+		:mData(cm_shared_ptr<InternalData>())
 	{ }
 	{ }
 
 
 	GpuParamTexture::GpuParamTexture(GpuParamObjectDesc* paramDesc, HTexture* textures)
 	GpuParamTexture::GpuParamTexture(GpuParamObjectDesc* paramDesc, HTexture* textures)
-	{
-		mData = cm_shared_ptr<InternalData>(paramDesc, textures);
-	}
+		:mData(cm_shared_ptr<InternalData>(paramDesc, textures))
+	{ }
 
 
 	void GpuParamTexture::set(const HTexture& texture)
 	void GpuParamTexture::set(const HTexture& texture)
 	{
 	{
@@ -143,16 +151,20 @@ namespace CamelotFramework
 		:paramDesc(paramDesc), samplerStates(samplerStates), isDestroyed(false)
 		:paramDesc(paramDesc), samplerStates(samplerStates), isDestroyed(false)
 	{ }
 	{ }
 
 
+	GpuParamSampState::InternalData::InternalData()
+		:paramDesc(nullptr), samplerStates(nullptr), isDestroyed(true)
+	{ }
+
 	GpuParamSampState::InternalData::~InternalData()
 	GpuParamSampState::InternalData::~InternalData()
 	{ }
 	{ }
 
 
 	GpuParamSampState::GpuParamSampState()
 	GpuParamSampState::GpuParamSampState()
+		:mData(cm_shared_ptr<InternalData>())
 	{ }
 	{ }
 
 
 	GpuParamSampState::GpuParamSampState(GpuParamObjectDesc* paramDesc, HSamplerState* samplerStates)
 	GpuParamSampState::GpuParamSampState(GpuParamObjectDesc* paramDesc, HSamplerState* samplerStates)
-	{
-		mData = cm_shared_ptr<InternalData>(paramDesc, samplerStates);
-	}
+		:mData(cm_shared_ptr<InternalData>(paramDesc, samplerStates))
+	{ }
 
 
 	void GpuParamSampState::set(const HSamplerState& samplerState)
 	void GpuParamSampState::set(const HSamplerState& samplerState)
 	{
 	{