Ver código fonte

Refactored text vertex generation into a separate method

Marko Pintera 12 anos atrás
pai
commit
6b2ccea5b3
3 arquivos alterados com 108 adições e 24 exclusões
  1. 29 0
      BansheeEngine/Include/BsTextSprite.h
  2. 70 22
      BansheeEngine/Source/BsTextSprite.cpp
  3. 9 2
      TODO.txt

+ 29 - 0
BansheeEngine/Include/BsTextSprite.h

@@ -72,6 +72,35 @@ namespace BansheeEngine
 
 
 		static CM::Vector<CM::Int2>::type getAlignmentOffsets(const CM::Vector<CM::TextUtility::TextLine>::type& lines, 
 		static CM::Vector<CM::Int2>::type getAlignmentOffsets(const CM::Vector<CM::TextUtility::TextLine>::type& lines, 
 			CM::UINT32 width, CM::UINT32 height, TextHorzAlign horzAlign, TextVertAlign vertAlign);
 			CM::UINT32 width, CM::UINT32 height, TextHorzAlign horzAlign, TextVertAlign vertAlign);
+
+		/**
+		 * @brief	Calculates text quads you may use for text rendering, based on the specified text
+		 * 			data. Only generates quads for the specified page.
+		 * 			
+		 * 			You must provide pre-allocated vertex/uv/index buffers of adequate size to hold all
+		 * 			quads for the specified page.
+		 * 			
+		 * @note	uv and/or index array may be null.
+		 *
+		 * @return	Number of generated quads.
+		 */
+		static CM::UINT32 genTextQuads(CM::UINT32 page, const CM::TextUtility::TextData& textData, CM::UINT32 width, CM::UINT32 height, 
+			TextHorzAlign horzAlign, TextVertAlign vertAlign, SpriteAnchor anchor, CM::Vector2* vertices, CM::Vector2* uv, CM::UINT32* indices, 
+			CM::UINT32 bufferSizeQuads);
+
+		/**
+		 * @brief	Calculates text quads you may use for text rendering, based on the specified text data. Generates quads for all pages.
+		 * 			
+		 *			You must provide pre-allocated vertex/uv/index buffers of adequate size to hold all quads for all characters
+		 *			on all pages.
+		 *			
+		 * @note	uv and/or index array may be null.
+		 *
+		 * @return	Number of generated quads.
+		 */
+		static CM::UINT32 genTextQuads(const CM::TextUtility::TextData& textData, CM::UINT32 width, CM::UINT32 height, 
+			TextHorzAlign horzAlign, TextVertAlign vertAlign, SpriteAnchor anchor, CM::Vector2* vertices, CM::Vector2* uv, CM::UINT32* indices, 
+			CM::UINT32 bufferSizeQuads);
 	private:
 	private:
 		CM::Vector<SpriteLineDesc>::type mLineDescs;
 		CM::Vector<SpriteLineDesc>::type mLineDescs;
 	};
 	};

+ 70 - 22
BansheeEngine/Source/BsTextSprite.cpp

@@ -85,31 +85,14 @@ namespace BansheeEngine
 		}
 		}
 
 
 		// Calc alignment and anchor offsets and set final line positions
 		// Calc alignment and anchor offsets and set final line positions
-		Vector<Int2>::type alignmentOffsets = getAlignmentOffsets(lines, desc.width, desc.height, desc.horzAlign, desc.vertAlign);
-		Int2 offset = getAnchorOffset(desc.anchor, desc.width, desc.height);
-
 		UINT32 numPages = (UINT32)quadsPerPage.size();
 		UINT32 numPages = (UINT32)quadsPerPage.size();
-		Vector<UINT32>::type faceOffsets(mCachedRenderElements.size(), 0);
-		for(size_t i = 0; i < lines.size(); i++)
+		
+		for(UINT32 j = 0; j < numPages; j++)
 		{
 		{
-			Int2 position = offset + alignmentOffsets[i];
-
-			for(size_t j = 0; j < numPages; j++)
-			{
-				SpriteRenderElement& renderElem = mCachedRenderElements[j];
-				UINT32 offset = faceOffsets[j];
-
-				UINT32 writtenQuads = lines[i].fillBuffer((UINT32)j, renderElem.vertices, renderElem.uvs, renderElem.indexes, offset, renderElem.numQuads);
-				
-				UINT32 numVertices = writtenQuads * 4;
-				for(size_t i = 0; i < numVertices; i++)
-				{
-					renderElem.vertices[offset * 4 + i].x += (float)position.x;
-					renderElem.vertices[offset * 4 + i].y += (float)position.y;
-				}
+			SpriteRenderElement& renderElem = mCachedRenderElements[j];
 
 
-				faceOffsets[j] += writtenQuads;
-			}
+			genTextQuads(j, *textData, desc.width, desc.height, desc.horzAlign, desc.vertAlign, desc.anchor, 
+				renderElem.vertices, renderElem.uvs, renderElem.indexes, renderElem.numQuads);
 		}
 		}
 
 
 		if(desc.clipRect.width > 0 && desc.clipRect.height > 0)
 		if(desc.clipRect.width > 0 && desc.clipRect.height > 0)
@@ -133,6 +116,7 @@ namespace BansheeEngine
 		UINT32 curCharIdx = 0;
 		UINT32 curCharIdx = 0;
 		UINT32 cachedLineY = 0;
 		UINT32 cachedLineY = 0;
 		UINT32 curLineIdx = 0;
 		UINT32 curLineIdx = 0;
+		Vector<Int2>::type alignmentOffsets = getAlignmentOffsets(lines, desc.width, desc.height, desc.horzAlign, desc.vertAlign);
 		for(auto& line : lines)
 		for(auto& line : lines)
 		{
 		{
 			// Line has a newline char only if it wasn't created by word wrap and it isn't the last line
 			// Line has a newline char only if it wasn't created by word wrap and it isn't the last line
@@ -154,6 +138,70 @@ namespace BansheeEngine
 		updateBounds();
 		updateBounds();
 	}
 	}
 
 
+	UINT32 TextSprite::genTextQuads(UINT32 page, const TextUtility::TextData& textData, UINT32 width, UINT32 height, 
+		TextHorzAlign horzAlign, TextVertAlign vertAlign, SpriteAnchor anchor, Vector2* vertices, Vector2* uv, UINT32* indices, UINT32 bufferSizeQuads)
+	{
+		const CM::Vector<TextUtility::TextLine>::type& lines = textData.getLines();
+		const CM::Vector<UINT32>::type& quadsPerPage = textData.getNumQuadsPerPage();
+
+		UINT32 newNumQuads = quadsPerPage[page];
+
+		Vector<Int2>::type alignmentOffsets = getAlignmentOffsets(lines, width, height, horzAlign, vertAlign);
+		Int2 offset = getAnchorOffset(anchor, width, height);
+
+		UINT32 quadOffset = 0;
+		for(size_t i = 0; i < lines.size(); i++)
+		{
+			UINT32 writtenQuads = lines[i].fillBuffer(page, vertices, uv, indices, quadOffset, bufferSizeQuads);
+
+			Int2 position = offset + alignmentOffsets[i];
+			UINT32 numVertices = writtenQuads * 4;
+			for(UINT32 i = 0; i < numVertices; i++)
+			{
+				vertices[quadOffset * 4 + i].x += (float)position.x;
+				vertices[quadOffset * 4 + i].y += (float)position.y;
+			}
+
+			quadOffset += writtenQuads;
+		}
+
+		return newNumQuads;
+	}
+
+
+	UINT32 TextSprite::genTextQuads(const TextUtility::TextData& textData, UINT32 width, UINT32 height, 
+		TextHorzAlign horzAlign, TextVertAlign vertAlign, SpriteAnchor anchor, Vector2* vertices, Vector2* uv, UINT32* indices, UINT32 bufferSizeQuads)
+	{
+		const CM::Vector<TextUtility::TextLine>::type& lines = textData.getLines();
+		const CM::Vector<UINT32>::type& quadsPerPage = textData.getNumQuadsPerPage();
+
+		Vector<Int2>::type alignmentOffsets = getAlignmentOffsets(lines, width, height, horzAlign, vertAlign);
+		Int2 offset = getAnchorOffset(anchor, width, height);
+
+		UINT32 quadOffset = 0;
+		UINT32 numPages = (UINT32)quadsPerPage.size();
+		for(size_t i = 0; i < lines.size(); i++)
+		{
+			for(UINT32 j = 0; j < numPages; j++)
+			{
+				UINT32 writtenQuads = lines[i].fillBuffer(j, vertices, uv, indices, quadOffset, bufferSizeQuads);
+
+				Int2 position = offset + alignmentOffsets[i];
+
+				UINT32 numVertices = writtenQuads * 4;
+				for(UINT32 i = 0; i < numVertices; i++)
+				{
+					vertices[quadOffset * 4 + i].x += (float)position.x;
+					vertices[quadOffset * 4 + i].y += (float)position.y;
+				}
+
+				quadOffset += writtenQuads;
+			}
+		}
+
+		return quadOffset;
+	}
+
 	CM::Rect TextSprite::getCharRect(UINT32 charIdx) const
 	CM::Rect TextSprite::getCharRect(UINT32 charIdx) const
 	{
 	{
 		UINT32 lineIdx = getLineForChar(charIdx);
 		UINT32 lineIdx = getLineForChar(charIdx);

+ 9 - 2
TODO.txt

@@ -23,14 +23,21 @@ IMMEDIATE:
 	- SpriteTexture keeps a static reference to DUmmyTexture which I need to release before shutdown
 	- SpriteTexture keeps a static reference to DUmmyTexture which I need to release before shutdown
 
 
 TextBox needed elements:
 TextBox needed elements:
- - Clicking on text seems to return slightly offset caret location
  - Key-repeat? Pressing left/right/up/down arrows doesn't repeat the keys (also delete/backspace)
  - Key-repeat? Pressing left/right/up/down arrows doesn't repeat the keys (also delete/backspace)
- - Drag mouse to update selection
+  - Add special text input commands, which will get repeatedly sent as long as their corresponding key is set in GUIManager
  - Get DebugCamera to ignore input if GUI has already processed it
  - Get DebugCamera to ignore input if GUI has already processed it
  - Cut/Copy/Paste
  - Cut/Copy/Paste
  - Make a separate class for InputSelection like I have for InputCaret. 
  - Make a separate class for InputSelection like I have for InputCaret. 
   - Make them use their own text rendering methods instead of relying on TextSprite.
   - Make them use their own text rendering methods instead of relying on TextSprite.
   - Make them a singleton so that any input element can use them, and not every element needs to have its own copy.
   - Make them a singleton so that any input element can use them, and not every element needs to have its own copy.
+  - Since caret and selection are so connected make sure their classes share a common base class.
+
+TextData::getVertexData(vertex, uv, bool splitByPages)
+ - Called by both TextSprite, InputCaret and InputSelection
+ - I move clipping/offset outside of TEXT_SPRITE_DESC and IMAGE_SPRITE_DESC and into fillBuffer()
+   - make sure that I don't call markDirty when clipping and/or offset changes
+ - Move SpriteLineDesc out of TextSprite and into InputCaret (I don't think InputSelection needs it)
+
  - LATER
  - LATER
   - TAB between input elements
   - TAB between input elements
   - Context menu with copy/cut/paste
   - Context menu with copy/cut/paste