From c10e0d92f46e5eaf25a69e1fafe5f4dbd8eaab9d Mon Sep 17 00:00:00 2001 From: chai Date: Wed, 3 Nov 2021 09:52:26 +0800 Subject: *misc --- Data/Resources/Font/simsun.ttc | Bin 0 -> 18214472 bytes Data/Resources/Metatable/Excel/Icons.xlsx | Bin 12425 -> 12447 bytes Data/Resources/Shaders/Editor-Text.glsl | 7 +- Data/Scripts/Editor/AssetBrowser.lua | 6 +- Data/Scripts/EditorApplication.lua | 2 +- Projects/VisualStudio/Editor/Editor.vcxproj | 9 +- .../VisualStudio/Editor/Editor.vcxproj.filters | 27 +++- Runtime/GUI/Font.cpp | 7 +- Runtime/GUI/TextMesh.cpp | 168 -------------------- Runtime/GUI/TextMesh.h | 50 ------ Runtime/GUI/TextMeshGenerator.h | 4 +- Runtime/GUI/UI9Slicing.cpp | 30 ++++ Runtime/GUI/UI9Slicing.h | 25 +++ Runtime/GUI/UIMesh.cpp | 15 ++ Runtime/GUI/UIMesh.h | 32 ++++ Runtime/GUI/UIQuad.h | 4 +- Runtime/GUI/UITextMesh.cpp | 175 +++++++++++++++++++++ Runtime/GUI/UITextMesh.h | 50 ++++++ Runtime/Math/Math.h | 4 +- Runtime/Math/MathHelper.h | 11 ++ Runtime/Math/Vector2.h | 17 ++ Runtime/Rendering/DynamicMesh.h | 3 + Runtime/Scripting/GUI/Font.bind.cpp | 4 +- 23 files changed, 408 insertions(+), 242 deletions(-) create mode 100644 Data/Resources/Font/simsun.ttc delete mode 100644 Runtime/GUI/TextMesh.cpp delete mode 100644 Runtime/GUI/TextMesh.h create mode 100644 Runtime/GUI/UI9Slicing.cpp create mode 100644 Runtime/GUI/UI9Slicing.h create mode 100644 Runtime/GUI/UIMesh.cpp create mode 100644 Runtime/GUI/UIMesh.h create mode 100644 Runtime/GUI/UITextMesh.cpp create mode 100644 Runtime/GUI/UITextMesh.h create mode 100644 Runtime/Math/MathHelper.h diff --git a/Data/Resources/Font/simsun.ttc b/Data/Resources/Font/simsun.ttc new file mode 100644 index 0000000..5f22ce3 Binary files /dev/null and b/Data/Resources/Font/simsun.ttc differ diff --git a/Data/Resources/Metatable/Excel/Icons.xlsx b/Data/Resources/Metatable/Excel/Icons.xlsx index 7259175..c4c454a 100644 Binary files a/Data/Resources/Metatable/Excel/Icons.xlsx and b/Data/Resources/Metatable/Excel/Icons.xlsx differ diff --git a/Data/Resources/Shaders/Editor-Text.glsl b/Data/Resources/Shaders/Editor-Text.glsl index 34412e3..7548507 100644 --- a/Data/Resources/Shaders/Editor-Text.glsl +++ b/Data/Resources/Shaders/Editor-Text.glsl @@ -1,3 +1,5 @@ +// 渲染编辑器文字 + #version 330 core CMD_BEGIN @@ -8,6 +10,7 @@ CMD_END uniform mat4 gamelab_mat_mvp; uniform sampler2D gamelab_main_tex; +uniform vec2 gamelab_ui_position; VSH_BEGIN layout (location = 0) in vec2 vPos; @@ -19,7 +22,7 @@ out vec4 color; void main() { - vec2 pos = vPos + vec2(10, 40); + vec2 pos = vPos + gamelab_ui_position; vec4 clip = gamelab_mat_mvp * vec4(pos, -1, 1.0); gl_Position = clip; uv = vUV; @@ -38,7 +41,7 @@ void main() //vec2 uv = vec2(uv.x, 1 - uv.y); vec4 sampled = vec4(0.8,0.8,0.8,texture(gamelab_main_tex, uv).r); sampled *= color; - // vec4 sampled = vec4(1,1,1,1); + //sampled = vec4(1,1,1,1); FragColor = sampled; } FSH_END diff --git a/Data/Scripts/Editor/AssetBrowser.lua b/Data/Scripts/Editor/AssetBrowser.lua index ecaecda..0c2d03f 100644 --- a/Data/Scripts/Editor/AssetBrowser.lua +++ b/Data/Scripts/Editor/AssetBrowser.lua @@ -27,7 +27,7 @@ AssetBrowser.OnGUI = function(self) end local ortho = Matrix44.New() - ortho:SetOrtho(0, 400, 0, 400, 0.1, 10) + ortho:SetOrtho(0, 400, 400, 0, 0.1, 10) Debug.Log("AssetBrowser.OnGUI()") GL.ClearColor({0.1,0.1,0.1,1}) @@ -35,9 +35,11 @@ AssetBrowser.OnGUI = function(self) Engine.Rendering.UseShader(shader) Engine.Rendering.SetMatrix44("gamelab_mat_mvp", ortho) + Engine.Rendering.SetVector2("gamelab_ui_position", {0, 0}) --Engine.Rendering.SetTexture("gamelab_main_tex", tex) --Engine.Rendering.DrawUIQuad({0, 0, 10, 20}) - _G["default_font"]:GetCharacters("你好世界!Hello,World! Project Window Properties", 12) + -- _G["default_font"]:GetCharacters("你好世界!Hello,World! Project Window Properties", 15) + _G["default_font"]:GetCharacters("A", 17) Engine.Rendering.ResetUniformState() end diff --git a/Data/Scripts/EditorApplication.lua b/Data/Scripts/EditorApplication.lua index 103dcdf..0aae504 100644 --- a/Data/Scripts/EditorApplication.lua +++ b/Data/Scripts/EditorApplication.lua @@ -113,7 +113,7 @@ local fsh = [[ BeforeMainLoop() -local font = Engine.GUI.Font.New("./Resources/Font/consola.ttf", {512, 512}, 5, 5) +local font = Engine.GUI.Font.New("./Resources/Font/simsun.ttc", {512, 512}, 5, 5) _G["default_font"] = font while true do diff --git a/Projects/VisualStudio/Editor/Editor.vcxproj b/Projects/VisualStudio/Editor/Editor.vcxproj index 83df147..9b2fbe0 100644 --- a/Projects/VisualStudio/Editor/Editor.vcxproj +++ b/Projects/VisualStudio/Editor/Editor.vcxproj @@ -200,7 +200,9 @@ - + + + @@ -289,7 +291,9 @@ - + + + @@ -316,6 +320,7 @@ + diff --git a/Projects/VisualStudio/Editor/Editor.vcxproj.filters b/Projects/VisualStudio/Editor/Editor.vcxproj.filters index e2b1c24..432151c 100644 --- a/Projects/VisualStudio/Editor/Editor.vcxproj.filters +++ b/Projects/VisualStudio/Editor/Editor.vcxproj.filters @@ -396,9 +396,6 @@ Runtime\Scripting\GUI - - Runtime\GUI - Runtime\GUI @@ -408,6 +405,15 @@ Runtime\GUI + + Runtime\GUI + + + Runtime\GUI + + + Runtime\GUI + @@ -692,9 +698,6 @@ Runtime\GUI - - Runtime\GUI - Runtime\GUI @@ -704,6 +707,18 @@ Runtime\GUI + + Runtime\GUI + + + Runtime\GUI + + + Runtime\GUI + + + Runtime\Math + diff --git a/Runtime/GUI/Font.cpp b/Runtime/GUI/Font.cpp index 8cdfdf3..614792a 100644 --- a/Runtime/GUI/Font.cpp +++ b/Runtime/GUI/Font.cpp @@ -146,8 +146,8 @@ void Font::RenderCharacter(character::Codepoint codepoint, int pixelSize) int w = m_FTFace->glyph->bitmap.width; int h = m_FTFace->glyph->bitmap.rows; - - //TextHelper::print_glyph(m_FTFace->glyph->bitmap.buffer, w, h); + + TextHelper::print_glyph(m_FTFace->glyph->bitmap.buffer, w, h); GlyphAtals* atlas = RequestAtlas(pixelSize, Internal::Vector2(w, h)); Assert(atlas); @@ -173,6 +173,9 @@ void Font::RenderCharacter(character::Codepoint codepoint, int pixelSize) character.advance = m_FTFace->glyph->advance.x * 1/64.f; m_Characters.insert(std::pair(hash, character)); +/* + FT_Done_Face(m_FTFace); + FT_Done_FreeType(m_FTLibrary);*/ } const GlyphAtals* Font::GetGlyphAtlas(int index) diff --git a/Runtime/GUI/TextMesh.cpp b/Runtime/GUI/TextMesh.cpp deleted file mode 100644 index 2f66170..0000000 --- a/Runtime/GUI/TextMesh.cpp +++ /dev/null @@ -1,168 +0,0 @@ -#include "../Graphics/CustomVertexLayout.h" -#include "Runtime/Utilities/StaticInitiator.h" -#include "../Math/Math.h" -#include "../Graphics/Color.h" -#include "TextMesh.h" -#include "../Graphics/DefaultVertexLayout.h" -#include "Runtime/Debug/Log.h" -#include -#include -#include "Runtime/Graphics/GfxDevice.h" - -using namespace std; - -struct TextMeshVBOLayout -{ - Vector2 position; - Vector2 uv; - Color32 color; -}; - -static CustomVertexLayout s_TextMeshVBOLayout; - -static unsigned int s_VertexPerText; -static unsigned int s_SizePerVertex; -static unsigned int s_SizePerText; -static unsigned int s_SizePerIndex; -static unsigned int s_IndicesPerText; - -struct TextInfo { - const Character* ch; - float offset; -}; - -static unordered_map> s_TextInfos; - -InitializeStaticVariables([]() { - VertexAttributeDescriptor POSITION = VertexAttributeDescriptor(0, 2, VertexAttrFormat_Float, sizeof(TextMeshVBOLayout)); - VertexAttributeDescriptor UV = VertexAttributeDescriptor(sizeof(Vector2), 2, VertexAttrFormat_Float, sizeof(TextMeshVBOLayout)); - VertexAttributeDescriptor COLOR = VertexAttributeDescriptor(sizeof(Vector2)*2, 4, VertexAttrFormat_Unsigned_Byte, sizeof(TextMeshVBOLayout), true); - s_TextMeshVBOLayout.attributes.push_back(POSITION); - s_TextMeshVBOLayout.attributes.push_back(UV); - s_TextMeshVBOLayout.attributes.push_back(COLOR); - - s_VertexPerText = 4; - s_SizePerVertex = sizeof(TextMeshVBOLayout); - - s_IndicesPerText = 6; - s_SizePerIndex = VertexLayout::GetDefaultIndexSize(); - - s_SizePerText = sizeof(TextMeshVBOLayout) * 4; -}); - -// һܻԲͬatlasTextMeshʱú - -TextMesh::TextMesh(const UnicodeString& str, Font* font,int pixelSize, ETextAnchor anchor, ETextAlignment alignment) -{ - m_Font = font; - s_TextInfos.clear(); - const Vector2 atlasSize = font->GetAtlasSize(); - - // ղͬatlasൽs_TextInfos - float offset = 0; - for (int i = 0; i < str.length; ++i) - { - character::Codepoint c = str.str[i]; - const Character* ch = font->GetCharacter(c, pixelSize); - unsigned int atlasIndex = ch->atlas; - - TextInfo info; - info.ch = ch; - info.offset = offset; - - auto list = s_TextInfos.find(atlasIndex); - if (list == s_TextInfos.end()) - s_TextInfos.insert(std::pair>(atlasIndex, vector())); - - vector& v = s_TextInfos[atlasIndex]; - v.push_back(info); - - offset += ch->advance; - } - - if (s_TextInfos.size() == 0) - return; - - // VBOIBO - for (auto iter : s_TextInfos) { - unsigned int atlasIndex = iter.first; // atlas atlasIndex - vector& texts = iter.second; - int textCount = texts.size(); - - VertexBuffer* vb = new VertexBuffer(textCount * s_SizePerText, textCount * s_IndicesPerText * s_SizePerIndex, VertexBuffer::VertexBufferType_Static); - void* pVB; - uint16* pIB; - - vb->GetChunk(s_SizePerVertex, s_SizePerIndex, s_VertexPerText * textCount, s_IndicesPerText * textCount, EPrimitive::Primitive_Triangle, &pVB,(void**) &pIB); - - TextMeshVBOLayout* dst = (TextMeshVBOLayout*)pVB; - for (int i = 0; i < textCount; ++i) - { - TextInfo& text = texts[i]; - - int vOff = i * s_VertexPerText; - float pos[] = { - text.offset + text.ch->bearing.x, text.ch->bearing.y - text.ch->position.height, // bottom-left - text.offset + text.ch->bearing.x + text.ch->position.width, text.ch->bearing.y - text.ch->position.height, // bottom-right - text.offset + text.ch->bearing.x + text.ch->position.width, text.ch->bearing.y, // top-right - text.offset + text.ch->bearing.x, text.ch->bearing.y, // top-left - }; - // ϽΪUVԭ㣬shaderʱҪy - Vector4 uvQuad = Vector4(text.ch->position.x / atlasSize.x, text.ch->position.y / atlasSize.y, text.ch->position.width / atlasSize.x, text.ch->position.height / atlasSize.y); - float uv[] = { - uvQuad.x, uvQuad.y + uvQuad.w, - uvQuad.x + uvQuad.z, uvQuad.y + uvQuad.w, - uvQuad.x + uvQuad.z, uvQuad.y, - uvQuad.x, uvQuad.y, - }; - for (int j = 0; j < s_VertexPerText; ++j) - { - dst[vOff + j].position.Set(pos[2 * j], pos[2 * j + 1]); - dst[vOff + j].uv.Set(uv[2 * j], uv[2 * j + 1]); - dst[vOff + j].color.Set(255 , 255, 255, 255); - } - - int iOff = i * s_IndicesPerText; - int indices[] = { - 0, 1, 3, // right-top - 1, 2, 3, // left-bottom - }; - for (int j = 0; j < s_IndicesPerText; ++j) - pIB[iOff + j] = vOff + indices[j]; - } - - vb->FlushChunk(s_VertexPerText * textCount, s_IndicesPerText * textCount); - - m_VBOs.insert(std::pair(atlasIndex, vb)); - } - - WipeGLError(); -} - -void TextMesh::Draw() -{ - for (auto subText : m_VBOs) - { - int atlasIndex = subText.first; // atlasIndex of atlas - VertexBuffer* vbo = subText.second; - - const GlyphAtals* atlas = m_Font->GetGlyphAtlas(atlasIndex); - if (atlas == NULL) - { - log_error("Render text failed, no glyph atlas."); - continue; - } - - g_GfxDevice.SetUniformTexture("gamelab_main_tex", atlas->altas); - - CheckGLError( - throw GLException(error); - ); - vbo->Draw(s_TextMeshVBOLayout); - - CheckGLError( - throw GLException(error); - ); - g_GfxDevice.ResetUniformsState(); - } -} diff --git a/Runtime/GUI/TextMesh.h b/Runtime/GUI/TextMesh.h deleted file mode 100644 index c5f05a2..0000000 --- a/Runtime/GUI/TextMesh.h +++ /dev/null @@ -1,50 +0,0 @@ -#pragma once -#include "../Graphics/VertexBuffer.h" -#include "Font.h" -#include "Runtime/Utilities/Exception.h" -#include - -CustomException(TextMeshException); - -enum ETextAnchor -{ - TextAnchor_UpperLeft, - TextAnchor_UpperCenter, - TextAnchor_UpperRight, - TextAnchor_MiddleLeft, - TextAnchor_MiddleCenter, - TextAnchor_MiddleRight, - TextAnchor_LowerLeft, - TextAnchor_LowerCenter, - TextAnchor_LowerRight, - TextAnchor_DontCare -}; - -enum ETextAlignment { - TextAlignment_Left, - TextAlignment_Center, - TextAlignment_Right, - TextAlignment_Auto, -}; - -typedef unsigned long long TextMeshHash; - -namespace TextHelper -{ - TextMeshHash GetTextMeshHash(); -} - -class TextMesh -{ -public: - TextMesh(const UnicodeString& str, Font* font, int pixelSize, ETextAnchor anchor, ETextAlignment alignment)/*throw TextMeshException*/; - - ~TextMesh(); - - void Draw(); - -private: - Font* m_Font; - std::unordered_map m_VBOs; - -}; \ No newline at end of file diff --git a/Runtime/GUI/TextMeshGenerator.h b/Runtime/GUI/TextMeshGenerator.h index baeaf16..94bcaa2 100644 --- a/Runtime/GUI/TextMeshGenerator.h +++ b/Runtime/GUI/TextMeshGenerator.h @@ -1,6 +1,6 @@ #pragma once -#include "TextMesh.h" +#include "UITextMesh.h" #include "Runtime/Utilities/IIncrementalTask.h" #include "Font.h" @@ -24,7 +24,7 @@ public: class TextMeshGenerator : public Singleton { public: - TextMesh* GetTextMesh(const UnicodeString& str); + UITextMesh* GetTextMesh(const UnicodeString& str); private: diff --git a/Runtime/GUI/UI9Slicing.cpp b/Runtime/GUI/UI9Slicing.cpp new file mode 100644 index 0000000..01a0143 --- /dev/null +++ b/Runtime/GUI/UI9Slicing.cpp @@ -0,0 +1,30 @@ +#include "UI9Slicing.h" + +UI9Slicing::UI9Slicing(ESlicing mode, Vector2 horizontal, Vector2 vertical, Vector2 texPixelSize, Vector2 size) +{ + m_Slicing = mode; + m_Horizontal = horizontal.Clamp(0, texPixelSize.x, 0, texPixelSize.x); + m_Vertical = vertical.Clamp(0, texPixelSize.y, 0, texPixelSize.y); + + if (m_Horizontal[0] + m_Horizontal[1] > texPixelSize.x || m_Vertical[0] + m_Vertical[1] > texPixelSize.y) + { + throw UIMeshException("UI9Slicing wrong parameter."); + } + m_TexSize = texPixelSize; + m_Size = size; +} + +void UI9Slicing::Draw() +{ + + + uint8* vb; + uint16* ib; + + g_SharedVBO.GetChunk(sizeof(UIVertexLayout), sizeof(uint16), 4, 6, Primitive_Triangle, (void**)&vb, (void**)&ib); + + + + g_SharedVBO.ReleaseChunk(4, 6); + g_SharedVBO.DrawChunk(UIMesh::s_UIVertexLayout); +} diff --git a/Runtime/GUI/UI9Slicing.h b/Runtime/GUI/UI9Slicing.h new file mode 100644 index 0000000..c88ba05 --- /dev/null +++ b/Runtime/GUI/UI9Slicing.h @@ -0,0 +1,25 @@ +#pragma once + +#include "UIMesh.h" + +enum ESlicing +{ + Slicing_Simple, + Slicing_Tiled, +}; + +// Ź +class UI9Slicing : public UIMesh +{ +public: + UI9Slicing(ESlicing mode, Vector2 horizontal, Vector2 vertical, Vector2 texPixelSize, Vector2 size)/*throw UIMeshException*/; + + void Draw() override; + +private: + ESlicing m_Slicing; + Vector2 m_Horizontal; // иߵߺұߵľ + Vector2 m_Vertical; // ͬ + Vector2 m_TexSize; + Vector2 m_Size; +}; diff --git a/Runtime/GUI/UIMesh.cpp b/Runtime/GUI/UIMesh.cpp new file mode 100644 index 0000000..a68b6fd --- /dev/null +++ b/Runtime/GUI/UIMesh.cpp @@ -0,0 +1,15 @@ +#include "UIMesh.h" + +CustomVertexLayout UIMesh::s_UIVertexLayout; +unsigned int UIMesh::s_SizePerVertex; + +InitializeStaticVariables([]() { + VertexAttributeDescriptor POSITION = VertexAttributeDescriptor(0, 2, VertexAttrFormat_Float, sizeof(UIVertexLayout)); + VertexAttributeDescriptor UV = VertexAttributeDescriptor(sizeof(Vector2), 2, VertexAttrFormat_Float, sizeof(UIVertexLayout)); + VertexAttributeDescriptor COLOR = VertexAttributeDescriptor(sizeof(Vector2) * 2, 4, VertexAttrFormat_Unsigned_Byte, sizeof(UIVertexLayout), true); + UIMesh::s_UIVertexLayout.attributes.push_back(POSITION); + UIMesh::s_UIVertexLayout.attributes.push_back(UV); + UIMesh::s_UIVertexLayout.attributes.push_back(COLOR); + + UIMesh::s_SizePerVertex = sizeof(UIVertexLayout); +}); diff --git a/Runtime/GUI/UIMesh.h b/Runtime/GUI/UIMesh.h new file mode 100644 index 0000000..dd83e6e --- /dev/null +++ b/Runtime/GUI/UIMesh.h @@ -0,0 +1,32 @@ +#pragma once + +#include "Runtime/Utilities/Exception.h" +#include "Runtime/Rendering/DynamicMesh.h" +#include "Runtime/Math/Math.h" +#include "Runtime/Utilities/StaticInitiator.h" +#include "Runtime/Graphics/CustomVertexLayout.h" +#include "Runtime/Graphics/DefaultVertexLayout.h" +#include "Runtime/Graphics/Color.h" +#include "Runtime/Graphics/GfxDevice.h" + +struct UIVertexLayout +{ + Vector2 position; + Vector2 uv; + Color32 color; +}; + +CustomException(UIMeshException); + +// еUIMeshϽΪԭ +class UIMesh : public DynamicMesh +{ +public: + UIMesh() : DynamicMesh() {} + virtual ~UIMesh() {} + + virtual void Draw() = 0; + + static CustomVertexLayout s_UIVertexLayout; + static unsigned int s_SizePerVertex; +}; diff --git a/Runtime/GUI/UIQuad.h b/Runtime/GUI/UIQuad.h index bcd95a0..278848a 100644 --- a/Runtime/GUI/UIQuad.h +++ b/Runtime/GUI/UIQuad.h @@ -1,8 +1,8 @@ #pragma once -#include "../Rendering/DynamicMesh.h" #include "../Utilities/StaticInitiator.h" +#include "UIMesh.h" -class UIQuad : public DynamicMesh +class UIQuad : public UIMesh { public : UIQuad(float l, float r, float t, float b) diff --git a/Runtime/GUI/UITextMesh.cpp b/Runtime/GUI/UITextMesh.cpp new file mode 100644 index 0000000..6a10f88 --- /dev/null +++ b/Runtime/GUI/UITextMesh.cpp @@ -0,0 +1,175 @@ +#include "../Graphics/CustomVertexLayout.h" +#include "Runtime/Utilities/StaticInitiator.h" +#include "../Math/Math.h" +#include "../Graphics/Color.h" +#include "UITextMesh.h" +#include "../Graphics/DefaultVertexLayout.h" +#include "Runtime/Debug/Log.h" +#include +#include +#include "Runtime/Graphics/GfxDevice.h" + +using namespace std; + +struct TextMeshVBOLayout +{ + Vector2 position; + Vector2 uv; + Color32 color; +}; + +static CustomVertexLayout s_TextMeshVBOLayout; + +static unsigned int s_VertexPerText; +static unsigned int s_SizePerVertex; +static unsigned int s_SizePerText; +static unsigned int s_SizePerIndex; +static unsigned int s_IndicesPerText; + +struct TextInfo { + const Character* ch; + float offset; +}; + +static unordered_map> s_TextInfos; + +InitializeStaticVariables([]() { + VertexAttributeDescriptor POSITION = VertexAttributeDescriptor(0, 2, VertexAttrFormat_Float, sizeof(TextMeshVBOLayout)); + VertexAttributeDescriptor UV = VertexAttributeDescriptor(sizeof(Vector2), 2, VertexAttrFormat_Float, sizeof(TextMeshVBOLayout)); + VertexAttributeDescriptor COLOR = VertexAttributeDescriptor(sizeof(Vector2)*2, 4, VertexAttrFormat_Unsigned_Byte, sizeof(TextMeshVBOLayout), true); + s_TextMeshVBOLayout.attributes.push_back(POSITION); + s_TextMeshVBOLayout.attributes.push_back(UV); + s_TextMeshVBOLayout.attributes.push_back(COLOR); + + s_VertexPerText = 4; + s_SizePerVertex = sizeof(TextMeshVBOLayout); + + s_IndicesPerText = 6; + s_SizePerIndex = VertexLayout::GetDefaultIndexSize(); + + s_SizePerText = sizeof(TextMeshVBOLayout) * 4; +}); + +// һܻԲͬatlasUITextMeshʱú + +// Ҫ֧ +// * С +// * ê +// * 뷽ʽ +// * +// * ɫ + +UITextMesh::UITextMesh(const UnicodeString& str, Font* font,int pixelSize, ETextAnchor anchor, ETextAlignment alignment) +{ + m_Font = font; + s_TextInfos.clear(); + const Vector2 atlasSize = font->GetAtlasSize(); + + // ղͬatlasൽs_TextInfos + float offset = 0; + for (int i = 0; i < str.length; ++i) + { + character::Codepoint c = str.str[i]; + const Character* ch = font->GetCharacter(c, pixelSize); + unsigned int atlasIndex = ch->atlas; + + TextInfo info; + info.ch = ch; + info.offset = offset; + + auto list = s_TextInfos.find(atlasIndex); + if (list == s_TextInfos.end()) + s_TextInfos.insert(std::pair>(atlasIndex, vector())); + + vector& v = s_TextInfos[atlasIndex]; + v.push_back(info); + + offset += ch->advance; + } + + if (s_TextInfos.size() == 0) + return; + + // VBOIBO + for (auto iter : s_TextInfos) { + unsigned int atlasIndex = iter.first; // atlas atlasIndex + vector& texts = iter.second; + int textCount = texts.size(); + + VertexBuffer* vb = new VertexBuffer(textCount * s_SizePerText, textCount * s_IndicesPerText * s_SizePerIndex, VertexBuffer::VertexBufferType_Static); + void* pVB; + uint16* pIB; + + vb->GetChunk(s_SizePerVertex, s_SizePerIndex, s_VertexPerText * textCount, s_IndicesPerText * textCount, EPrimitive::Primitive_Triangle, &pVB,(void**) &pIB); + + TextMeshVBOLayout* dst = (TextMeshVBOLayout*)pVB; + for (int i = 0; i < textCount; ++i) + { + TextInfo& text = texts[i]; + + int vOff = i * s_VertexPerText; + // Ͻԭ + float pos[] = { + text.offset + text.ch->bearing.x, pixelSize - text.ch->bearing.y + text.ch->position.height, // bottom-left + text.offset + text.ch->bearing.x + text.ch->position.width, pixelSize - text.ch->bearing.y + text.ch->position.height, // bottom-right + text.offset + text.ch->bearing.x + text.ch->position.width, pixelSize - text.ch->bearing.y, // top-right + text.offset + text.ch->bearing.x, pixelSize - text.ch->bearing.y, // top-left + }; + Vector4 uvQuad = Vector4(text.ch->position.x / atlasSize.x, text.ch->position.y / atlasSize.y, text.ch->position.width / atlasSize.x, text.ch->position.height / atlasSize.y); + float uv[] = { + uvQuad.x, uvQuad.y + uvQuad.w, + uvQuad.x + uvQuad.z, uvQuad.y + uvQuad.w, + uvQuad.x + uvQuad.z, uvQuad.y, + uvQuad.x, uvQuad.y, + }; + for (int j = 0; j < s_VertexPerText; ++j) + { + dst[vOff + j].position.Set(pos[2 * j], pos[2 * j + 1]); + dst[vOff + j].uv.Set(uv[2 * j], uv[2 * j + 1]); + dst[vOff + j].color.Set(255 , 255, 255, 255); + } + + int iOff = i * s_IndicesPerText; + int indices[] = { + 0, 1, 3, // right-top + 1, 2, 3, // left-bottom + }; + for (int j = 0; j < s_IndicesPerText; ++j) + pIB[iOff + j] = vOff + indices[j]; + } + + vb->FlushChunk(s_VertexPerText * textCount, s_IndicesPerText * textCount); + + m_VBOs.insert(std::pair(atlasIndex, vb)); + } + + WipeGLError(); +} + +void UITextMesh::Draw() +{ + for (auto subText : m_VBOs) + { + int atlasIndex = subText.first; // atlasIndex of atlas + VertexBuffer* vbo = subText.second; + + const GlyphAtals* atlas = m_Font->GetGlyphAtlas(atlasIndex); + if (atlas == NULL) + { + log_error("Render text failed, no glyph atlas."); + continue; + } + + g_GfxDevice.SetUniformTexture("gamelab_main_tex", atlas->altas); + + CheckGLError( + throw GLException(error); + ); + vbo->Draw(s_TextMeshVBOLayout); + + CheckGLError( + throw GLException(error); + ); + g_GfxDevice.ResetUniformsState(); + } +} diff --git a/Runtime/GUI/UITextMesh.h b/Runtime/GUI/UITextMesh.h new file mode 100644 index 0000000..c88e52f --- /dev/null +++ b/Runtime/GUI/UITextMesh.h @@ -0,0 +1,50 @@ +#pragma once +#include "../Graphics/VertexBuffer.h" +#include "Font.h" +#include "Runtime/Utilities/Exception.h" +#include + +CustomException(TextMeshException); + +enum ETextAnchor +{ + TextAnchor_UpperLeft, + TextAnchor_UpperCenter, + TextAnchor_UpperRight, + TextAnchor_MiddleLeft, + TextAnchor_MiddleCenter, + TextAnchor_MiddleRight, + TextAnchor_LowerLeft, + TextAnchor_LowerCenter, + TextAnchor_LowerRight, + TextAnchor_DontCare +}; + +enum ETextAlignment { + TextAlignment_Left, + TextAlignment_Center, + TextAlignment_Right, + TextAlignment_Auto, +}; + +typedef unsigned long long TextMeshHash; + +namespace TextHelper +{ + TextMeshHash GetTextMeshHash(); +} + +class UITextMesh +{ +public: + UITextMesh(const UnicodeString& str, Font* font, int pixelSize, ETextAnchor anchor, ETextAlignment alignment)/*throw TextMeshException*/; + + ~UITextMesh(); + + void Draw(); + +private: + Font* m_Font; + std::unordered_map m_VBOs; + +}; \ No newline at end of file diff --git a/Runtime/Math/Math.h b/Runtime/Math/Math.h index aaeb264..5e08613 100644 --- a/Runtime/Math/Math.h +++ b/Runtime/Math/Math.h @@ -6,9 +6,7 @@ #include "Matrix44.h" #include "FloatConversion.h" #include "Rect.h" - -#define max(a, b)\ -(a)>(b)?(a):(b) +#include "MathHelper.h" typedef Internal::Vector2 Vector2; typedef Internal::Vector3 Vector3; diff --git a/Runtime/Math/MathHelper.h b/Runtime/Math/MathHelper.h new file mode 100644 index 0000000..3f8754a --- /dev/null +++ b/Runtime/Math/MathHelper.h @@ -0,0 +1,11 @@ +#pragma once + +#define max(a, b)\ +(a)>(b)?(a):(b) + +#define min(a, b)\ +(a)<(b)?(a):(b) + +#define clamp(v, lo, hi)\ +max((lo), min((v), (hi))) + diff --git a/Runtime/Math/Vector2.h b/Runtime/Math/Vector2.h index 27cf312..9d7e4e9 100644 --- a/Runtime/Math/Vector2.h +++ b/Runtime/Math/Vector2.h @@ -1,4 +1,6 @@ #pragma once +#include "MathHelper.h" +#include "Runtime/Utilities/Assert.h" namespace Internal { @@ -15,6 +17,21 @@ namespace Internal this->y = y; } + Vector2 Clamp(float xmin, float xmax, float ymin, float ymax) + { + Vector2 v; + v.x = clamp(x, xmin, xmax); + v.y = clamp(y, ymin, ymax); + return v; + } + + float operator[](int i) + { + if (i == 0) return x; + else if (i == 1) return y; + Assert(false); + } + bool operator == (const Vector2& v) const { return v.x == x && v.y == y; diff --git a/Runtime/Rendering/DynamicMesh.h b/Runtime/Rendering/DynamicMesh.h index 3cbb6f6..01babfc 100644 --- a/Runtime/Rendering/DynamicMesh.h +++ b/Runtime/Rendering/DynamicMesh.h @@ -5,6 +5,9 @@ class DynamicMesh { public: + DynamicMesh() {}; + virtual ~DynamicMesh() {}; + virtual void Draw() = 0; }; diff --git a/Runtime/Scripting/GUI/Font.bind.cpp b/Runtime/Scripting/GUI/Font.bind.cpp index 733fcf1..2d01925 100644 --- a/Runtime/Scripting/GUI/Font.bind.cpp +++ b/Runtime/Scripting/GUI/Font.bind.cpp @@ -5,7 +5,7 @@ #include "Runtime/Common/DataBuffer.h" #include "Runtime/GUI/utf8.h" #include "Runtime/Utilities/StaticInitiator.h" -#include "Runtime/GUI/TextMesh.h" +#include "Runtime/GUI/UITextMesh.h" static std::vector* s_Codepoints; @@ -134,7 +134,7 @@ LUA_BIND_IMPL_METHOD(Font, _GetCharacters) WipeGLError(); - TextMesh* tm = new TextMesh(str, self, size, ETextAnchor::TextAnchor_MiddleLeft, ETextAlignment::TextAlignment_Left); + UITextMesh* tm = new UITextMesh(str, self, size, ETextAnchor::TextAnchor_MiddleLeft, ETextAlignment::TextAlignment_Left); tm->Draw(); return 0; -- cgit v1.1-26-g67d0