diff options
Diffstat (limited to 'Runtime/GUI/TextMesh.cpp')
-rw-r--r-- | Runtime/GUI/TextMesh.cpp | 168 |
1 files changed, 0 insertions, 168 deletions
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 <vector> -#include <unordered_map> -#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<unsigned int, vector<TextInfo>> 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; -}); - -// 一段文字里面的网格可能会来自不同的atlas,在生成TextMesh时做好合批 - -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<unsigned int, vector<TextInfo>>(atlasIndex, vector<TextInfo>())); - - vector<TextInfo>& v = s_TextInfos[atlasIndex]; - v.push_back(info); - - offset += ch->advance; - } - - if (s_TextInfos.size() == 0) - return; - - // 填充VBO和IBO - for (auto iter : s_TextInfos) { - unsigned int atlasIndex = iter.first; // atlas atlasIndex - vector<TextInfo>& 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<int, VertexBuffer*>(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(); - } -} |