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

Better way of updating GUI elements

Marko Pintera 12 лет назад
Родитель
Сommit
06f19ace97

+ 22 - 6
BansheeEngine/Include/BsGUIElement.h

@@ -65,16 +65,17 @@ namespace BansheeEngine
 		virtual void fillBuffer(UINT8* vertices, UINT8* uv, UINT32* indices, UINT32 startingQuad, 
 			UINT32 maxNumQuads, UINT32 vertexStride, UINT32 indexStride, UINT32 renderElementIdx) const = 0;
 
+		/**
+		 * @brief	Recreates the internal render elements. Must be called before fillBuffer if element is dirty. 
+		 * 			Marks the element as non dirty.
+		 */
+		void updateRenderElements();
+
 		virtual bool mouseEvent(const GUIMouseEvent& ev);
 
 		const CM::Rect& getBounds() const { return mBounds; }
-
-		void setDepth(INT32 depth) { mDepth = depth; }
 		INT32 getDepth() const { return mDepth; }
-
 		bool isDirty() const { return mIsDirty; }
-		void markAsClean() { mIsDirty = false; }
-		void markAsDirty() { mIsDirty = true; }
 
 		static void destroy(GUIElement* element);
 
@@ -89,18 +90,33 @@ namespace BansheeEngine
 
 		virtual ~GUIElement();
 
+		virtual void updateRenderElementsInternal() = 0;
+
 		GUILayout* getParentLayout() const { return mParentLayout; }
 		void setParentLayout(GUILayout* layout) { mParentLayout = layout; }
 
+		void setDepth(INT32 depth) { mDepth = depth; }
+		void setOffset(const CM::Int2& offset) { mOffset = offset; }
+		void setWidth(UINT32 width) { mWidth = width; }
+		void setHeight(UINT32 height) { mHeight = height; }
+		void setClipRect(const CM::Rect& clipRect) { mClipRect = clipRect; }
+
 		void setLayoutOptions(const GUI_LAYOUT_OPTIONS& layoutOptions) { mLayoutOptions = layoutOptions; }
 		const GUI_LAYOUT_OPTIONS& getLayoutOptions() const { return mLayoutOptions; }
 
+		void markAsClean() { mIsDirty = false; }
+		void markAsDirty() { mIsDirty = true; }
+
 		GUIWidget& mParent;
 		GUILayout* mParentLayout;
 		GUI_LAYOUT_OPTIONS mLayoutOptions;
 		CM::Rect mBounds;
-		INT32 mDepth;
+
 		bool mIsDirty;
+		INT32 mDepth;
+		CM::Int2 mOffset;
+		UINT32 mWidth, mHeight;
+		CM::Rect mClipRect;
 		const GUIElementStyle* mStyle;
 
 		static void destroyInternal(GUIElement* element);

+ 5 - 0
BansheeEngine/Include/BsGUILabel.h

@@ -45,6 +45,11 @@ namespace BansheeEngine
 		virtual void fillBuffer(UINT8* vertices, UINT8* uv, UINT32* indices, UINT32 startingQuad, 
 			UINT32 maxNumQuads, UINT32 vertexStride, UINT32 indexStride, UINT32 renderElementIdx) const;
 
+		/**
+		 * @copydoc GUIElement::updateRenderElementsInternal()
+		 */
+		virtual void updateRenderElementsInternal();
+
 		static const GUI_LAYOUT_OPTIONS& getDefaultLayoutOptions();
 	private:
 		TextSprite* mTextSprite;

+ 7 - 1
BansheeEngine/Include/BsGUIWindowFrame.h

@@ -2,7 +2,7 @@
 
 #include "BsPrerequisites.h"
 #include "BsGUIElement.h"
-#include "BsTextSprite.h"
+#include "BsImageSprite.h"
 
 namespace BansheeEngine
 {
@@ -37,9 +37,15 @@ namespace BansheeEngine
 		virtual void fillBuffer(UINT8* vertices, UINT8* uv, UINT32* indices, UINT32 startingQuad, 
 			UINT32 maxNumQuads, UINT32 vertexStride, UINT32 indexStride, UINT32 renderElementIdx) const;
 
+		/**
+		 * @copydoc GUIElement::updateRenderElementsInternal()
+		 */
+		virtual void updateRenderElementsInternal();
+
 		static const GUI_LAYOUT_OPTIONS& getDefaultLayoutOptions();
 	private:
 		ImageSprite* mImageSprite;
+		IMAGE_SPRITE_DESC mDesc;
 
 		GUIWindowFrame(GUIWidget& parent, const GUI_LAYOUT_OPTIONS& layoutOptions);
 	};

+ 7 - 1
BansheeEngine/Source/BsGUIElement.cpp

@@ -9,7 +9,7 @@ using namespace CamelotFramework;
 namespace BansheeEngine
 {
 	GUIElement::GUIElement(GUIWidget& parent, const GUI_LAYOUT_OPTIONS& layoutOptions)
-		:mParent(parent), mIsDirty(true), mParentLayout(nullptr), mLayoutOptions(layoutOptions)
+		:mParent(parent), mIsDirty(true), mParentLayout(nullptr), mLayoutOptions(layoutOptions), mWidth(0), mHeight(0), mDepth(0)
 	{
 		mParent.registerElement(this);
 	}
@@ -20,6 +20,12 @@ namespace BansheeEngine
 			mParentLayout->removeElement(this);
 	}
 
+	void GUIElement::updateRenderElements()
+	{
+		updateRenderElementsInternal();
+		markAsClean();
+	}
+
 	bool GUIElement::mouseEvent(const GUIMouseEvent& ev)
 	{
 		return false;

+ 6 - 3
BansheeEngine/Source/BsGUILabel.cpp

@@ -25,9 +25,6 @@ namespace BansheeEngine
 		mDesc.wordWrap = wordWrap;
 		mDesc.horzAlign = horzAlign;
 		mDesc.vertAlign = vertAlign;
-		mTextSprite->update(mDesc); // TODO - I probably don't need to call this until I have GUILayout set up
-
-		mBounds = mTextSprite->getBounds();
 	}
 
 	GUILabel::~GUILabel()
@@ -50,6 +47,12 @@ namespace BansheeEngine
 		return mTextSprite->getNumQuads(renderElementIdx);
 	}
 
+	void GUILabel::updateRenderElementsInternal()
+	{		
+		mTextSprite->update(mDesc);
+		mBounds = mTextSprite->getBounds();
+	}
+
 	void GUILabel::fillBuffer(UINT8* vertices, UINT8* uv, UINT32* indices, UINT32 startingQuad, UINT32 maxNumQuads, 
 		UINT32 vertexStride, UINT32 indexStride, UINT32 renderElementIdx) const
 	{

+ 3 - 1
BansheeEngine/Source/BsGUIWidget.cpp

@@ -154,6 +154,9 @@ namespace BansheeEngine
 		// Determine mesh sizes per group
 		for(auto& elem : mElements)
 		{
+			if(elem->isDirty())
+				elem->updateRenderElements();
+
 			UINT32 numRenderElems = elem->getNumRenderElements();
 
 			for(UINT32 i = 0; i < numRenderElems; i++)
@@ -216,7 +219,6 @@ namespace BansheeEngine
 				UINT32 indexStride = meshData->getIndexElementSize();
 				
 				elem->fillBuffer(vertices, uvs, indices, startingQuad, maxNumQuads, vertexStride, indexStride, i);
-				elem->markAsClean();
 
 				UINT32 numQuads = elem->getNumQuads(i);
 				meshDataPerRenderElement[meshGroup].quadOffset += numQuads;

+ 14 - 13
BansheeEngine/Source/BsGUIWindowFrame.cpp

@@ -24,23 +24,18 @@ namespace BansheeEngine
 		mStyle = skin->getStyle(getGUITypeName());
 		mImageSprite = CM_NEW(ImageSprite, PoolAlloc) ImageSprite();
 
-		IMAGE_SPRITE_DESC desc;
-		desc.texture = mStyle->normal.texture;
+		mDesc.texture = mStyle->normal.texture;
 
-		if(desc.texture != nullptr)
+		if(mDesc.texture != nullptr)
 		{
-			desc.width = desc.texture->getTexture()->getWidth();
-			desc.height = desc.texture->getTexture()->getHeight();
+			mDesc.width = mDesc.texture->getTexture()->getWidth();
+			mDesc.height = mDesc.texture->getTexture()->getHeight();
 		}
 
-		desc.borderLeft = mStyle->border.left;
-		desc.borderRight = mStyle->border.right;
-		desc.borderTop = mStyle->border.top;
-		desc.borderBottom = mStyle->border.bottom;
-
-		mImageSprite->update(desc);
-
-		mBounds = mImageSprite->getBounds();
+		mDesc.borderLeft = mStyle->border.left;
+		mDesc.borderRight = mStyle->border.right;
+		mDesc.borderTop = mStyle->border.top;
+		mDesc.borderBottom = mStyle->border.bottom;
 	}
 
 	GUIWindowFrame::~GUIWindowFrame()
@@ -73,6 +68,12 @@ namespace BansheeEngine
 		return mImageSprite->getNumQuads(renderElementIdx);
 	}
 
+	void GUIWindowFrame::updateRenderElementsInternal()
+	{		
+		mImageSprite->update(mDesc);
+		mBounds = mImageSprite->getBounds();
+	}
+
 	void GUIWindowFrame::fillBuffer(UINT8* vertices, UINT8* uv, UINT32* indices, UINT32 startingQuad, UINT32 maxNumQuads, 
 		UINT32 vertexStride, UINT32 indexStride, UINT32 renderElementIdx) const
 	{