Working on removing ui label
This commit is contained in:
10
src/dawn/scene/components/ui/text/CMakeLists.txt
Normal file
10
src/dawn/scene/components/ui/text/CMakeLists.txt
Normal file
@ -0,0 +1,10 @@
|
||||
# Copyright (c) 2022 Dominic Masters
|
||||
#
|
||||
# This software is released under the MIT License.
|
||||
# https://opensource.org/licenses/MIT
|
||||
|
||||
# Sources
|
||||
target_sources(${DAWN_TARGET_NAME}
|
||||
PRIVATE
|
||||
UILabelNew.cpp
|
||||
)
|
269
src/dawn/scene/components/ui/text/UILabelNew.cpp
Normal file
269
src/dawn/scene/components/ui/text/UILabelNew.cpp
Normal file
@ -0,0 +1,269 @@
|
||||
// Copyright (c) 2023 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#include "UILabelNew.hpp"
|
||||
#include "game/DawnGame.hpp"
|
||||
|
||||
using namespace Dawn;
|
||||
|
||||
UILabelNew::UILabelNew(SceneItem *item) :
|
||||
UIComponentRenderable(item)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void UILabelNew::onStart() {
|
||||
this->shaderBuffer.init();
|
||||
|
||||
std::vector<struct UILabelStyle> styleStack;
|
||||
struct UILabelStyle current;
|
||||
styleStack.push_back(current);
|
||||
std::vector<struct UILabelText> texts;
|
||||
|
||||
std::function<void(Xml*)> parseChildren = [&](Xml *node) {
|
||||
if(node->children.empty()) {
|
||||
struct UILabelText text;
|
||||
text.style = current;
|
||||
text.text = node->value;
|
||||
texts.push_back(text);
|
||||
} else {
|
||||
auto itNode = node->children.begin();
|
||||
while(itNode != node->children.end()) {
|
||||
auto child = *itNode;
|
||||
assertTrue(child->node == "font");
|
||||
|
||||
struct UILabelStyle style;
|
||||
if(child->attributes.contains("font")) {
|
||||
style.font = this->getGame()->assetManager.get<NewTrueTypeAsset>(child->attributes["font"]);
|
||||
} else {
|
||||
style.font = current.font;
|
||||
}
|
||||
|
||||
if(child->attributes.contains("size")) {
|
||||
style.size = std::stoi(child->attributes["size"]);
|
||||
} else {
|
||||
style.size = current.size;
|
||||
}
|
||||
|
||||
if(child->attributes.contains("style")) {
|
||||
std::string s = child->attributes["style"];
|
||||
style.style = 0;
|
||||
if(s.find("bold") != std::string::npos) style.style |= NEW_TRUETYPE_VARIANT_BOLD;
|
||||
if(s.find("italic") != std::string::npos) style.style |= NEW_TRUETYPE_VARIANT_ITALICS;
|
||||
} else {
|
||||
style.style = current.style;
|
||||
}
|
||||
|
||||
if(child->attributes.contains("color")) {
|
||||
style.color = Color::fromString(child->attributes["color"]);
|
||||
} else {
|
||||
style.color = current.color;
|
||||
}
|
||||
|
||||
styleStack.push_back(style);
|
||||
current = style;
|
||||
|
||||
parseChildren(child);
|
||||
|
||||
styleStack.pop_back();
|
||||
current = styleStack.back();
|
||||
++itNode;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
auto root = Xml::load("<root>" + this->test + "</root>");
|
||||
parseChildren(&root);
|
||||
this->rebufferQuads(texts);
|
||||
}
|
||||
|
||||
std::vector<struct ShaderPassItem> UILabelNew::getUIRenderPasses() {
|
||||
// if(this->texts.size() == 0) return {};
|
||||
|
||||
auto canvas = this->getCanvas();
|
||||
auto shader = getGame()->renderManager.fontShader;
|
||||
|
||||
struct ShaderPassItem item;
|
||||
item.shader = shader;
|
||||
item.mesh = &this->mesh;
|
||||
item.matrixValues[shader->paramModel] = transform->getWorldTransform();
|
||||
item.parameterBuffers[shader->bufferUiCanvas] = &canvas->shaderBuffer;
|
||||
item.parameterBuffers[shader->bufferFont] = &this->shaderBuffer;
|
||||
item.renderFlags = RENDER_MANAGER_RENDER_FLAG_BLEND;
|
||||
|
||||
// Map texture slots
|
||||
auto it = textureMap.begin();
|
||||
while(it != textureMap.end()) {
|
||||
shaderparameter_t param;
|
||||
switch(it->second) {
|
||||
case 0:
|
||||
param = shader->paramTexture0;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
param = shader->paramTexture1;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
param = shader->paramTexture2;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
param = shader->paramTexture3;
|
||||
break;
|
||||
|
||||
default:
|
||||
assertUnreachable();
|
||||
}
|
||||
|
||||
item.textureSlots[it->second] = &it->first->texture;
|
||||
item.textureValues[param] = it->second;
|
||||
++it;
|
||||
}
|
||||
|
||||
return { item };
|
||||
}
|
||||
|
||||
float_t UILabelNew::getWidth() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
float_t UILabelNew::getHeight() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
float_t UILabelNew::getContentWidth() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
float_t UILabelNew::getContentHeight() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void UILabelNew::rebufferQuads(std::vector<struct UILabelText> texts) {
|
||||
auto oldTexts = this->texts;
|
||||
|
||||
textureMap.clear();
|
||||
glm::vec2 position(0, 0);
|
||||
struct FontShaderBufferData fontData;
|
||||
int32_t quadIndex = 0;
|
||||
int32_t partIndex = 0;
|
||||
int32_t quadCount = 0;
|
||||
int32_t nextTexture = 0;
|
||||
|
||||
// Determine how many quads there are, and the texture indexes.
|
||||
auto itText = texts.begin();
|
||||
while(itText != texts.end()) {
|
||||
quadCount += itText->text.length();
|
||||
|
||||
// Determine font and lock it.
|
||||
assertNotNull(itText->style.font);
|
||||
itText->lockId = itText->style.font->lock(NewTrueTypeFaceTextureStyle{
|
||||
itText->style.size,
|
||||
itText->style.style
|
||||
});
|
||||
assertTrue(itText->lockId != -1);
|
||||
itText->texture = itText->style.font->getTexture(itText->lockId);
|
||||
|
||||
// Check for existing texture, if not, map it.
|
||||
if(textureMap.find(itText->texture) == textureMap.end()) {
|
||||
assertTrue(nextTexture < FONT_SHADER_TEXTURE_MAX);
|
||||
textureMap[itText->texture] = nextTexture++;
|
||||
}
|
||||
|
||||
// Set initial line height
|
||||
position.y = mathMax<float_t>(itText->style.size, position.y);
|
||||
|
||||
++itText;
|
||||
}
|
||||
|
||||
// Cleanup old texst, we do this second so we don't unlock, cleanup, and then
|
||||
// lock the same font, causing it to have to re-load.
|
||||
itText = oldTexts.begin();
|
||||
while(itText != oldTexts.end()) {
|
||||
assertTrue(itText->lockId != -1);
|
||||
assertNotNull(itText->style.font);
|
||||
itText->style.font->unlock(itText->lockId);
|
||||
++itText;
|
||||
}
|
||||
|
||||
// Update texts.
|
||||
this->texts = texts;
|
||||
|
||||
// Create mesh
|
||||
this->mesh.createBuffers(
|
||||
QUAD_VERTICE_COUNT * quadCount,
|
||||
QUAD_INDICE_COUNT * quadCount
|
||||
);
|
||||
|
||||
// Buffer the text quads
|
||||
itText = texts.begin();
|
||||
while(itText != texts.end()) {
|
||||
quadIndex += this->bufferQuads(
|
||||
*itText,
|
||||
fontData,
|
||||
textureMap,
|
||||
position,
|
||||
quadIndex,
|
||||
partIndex
|
||||
);
|
||||
++partIndex;
|
||||
++itText;
|
||||
}
|
||||
|
||||
shaderBuffer.buffer(&fontData);
|
||||
}
|
||||
|
||||
int32_t UILabelNew::bufferQuads(
|
||||
struct UILabelText text,
|
||||
struct FontShaderBufferData &bufferData,
|
||||
std::map<NewTrueTypeFaceTexture*, int32_t> &textureMap,
|
||||
glm::vec2 &position,
|
||||
int32_t quadStart,
|
||||
int32_t partIndex
|
||||
) {
|
||||
// Get string length
|
||||
int32_t len = text.text.length();
|
||||
|
||||
glm::vec2 wh = glm::vec2(
|
||||
text.texture->texture.getWidth(),
|
||||
text.texture->texture.getHeight()
|
||||
);
|
||||
|
||||
// For each char
|
||||
for(int32_t i = 0; i < len; i++) {
|
||||
char ch = text.text[i];
|
||||
int32_t j = quadStart + i;
|
||||
FT_ULong c = ch;
|
||||
auto charInfo = text.texture->getCharacterData(c);
|
||||
|
||||
// Determine texture coordinates.
|
||||
glm::vec2 uv0 = glm::vec2(0.0f, charInfo.textureY) / wh;
|
||||
glm::vec2 uv1 = uv0 + (charInfo.bitmapSize / wh);
|
||||
|
||||
// Buffer the quad.
|
||||
QuadMesh::bufferQuadMeshWithZ(&this->mesh,
|
||||
position + charInfo.bitmapPosition, uv0,
|
||||
position + charInfo.bitmapPosition + charInfo.bitmapSize, uv1,
|
||||
0.0f,
|
||||
j * QUAD_VERTICE_COUNT, j * QUAD_INDICE_COUNT
|
||||
);
|
||||
|
||||
// Move the current position along.
|
||||
position.x += charInfo.advanceX;
|
||||
position.y += charInfo.advanceY;
|
||||
|
||||
// Set the part index to the quad mappings
|
||||
bufferData.fontQuadMappings[j] = partIndex;
|
||||
}
|
||||
|
||||
// Map texture level values
|
||||
auto textureId = textureMap.find(text.texture);
|
||||
assertTrue(textureId != textureMap.end());
|
||||
bufferData.textures[partIndex] = textureId->second;
|
||||
bufferData.colors[partIndex] = text.style.color;
|
||||
|
||||
return len;
|
||||
}
|
78
src/dawn/scene/components/ui/text/UILabelNew.hpp
Normal file
78
src/dawn/scene/components/ui/text/UILabelNew.hpp
Normal file
@ -0,0 +1,78 @@
|
||||
// Copyright (c) 2023 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "scene/components/ui/UIComponentRenderable.hpp"
|
||||
#include "display/mesh/QuadMesh.hpp"
|
||||
#include "asset/assets/NewTrueTypeAsset.hpp"
|
||||
#include "util/Xml.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
struct UILabelStyle {
|
||||
struct Color color = COLOR_WHITE;
|
||||
flag_t style = 0;
|
||||
uint32_t size = 16;
|
||||
NewTrueTypeAsset *font = nullptr;
|
||||
};
|
||||
|
||||
struct UILabelText {
|
||||
std::string text;
|
||||
struct UILabelStyle style;
|
||||
|
||||
// Part index?
|
||||
// Quad start?
|
||||
// quad count?
|
||||
// position?
|
||||
// size?
|
||||
// some kind of custom data e.g. wobble or shake?
|
||||
|
||||
usagelockid_t lockId = -1;
|
||||
struct NewTrueTypeFaceTexture *texture = nullptr;
|
||||
};
|
||||
|
||||
class UILabelNew : public UIComponentRenderable {
|
||||
private:
|
||||
Mesh mesh;
|
||||
FontShaderBuffer shaderBuffer;
|
||||
std::vector<struct UILabelText> texts;
|
||||
std::map<NewTrueTypeFaceTexture*, int32_t> textureMap;
|
||||
|
||||
/**
|
||||
* Buffers the quads for the given text and updates the progressing values
|
||||
* as the buffer process continues.
|
||||
*
|
||||
* @param text Text information to buffer.
|
||||
* @param bufferData The output quad mappings for the text.
|
||||
* @param textureMap Texture map for the textures to map.
|
||||
* @param position The 2D position to buffer the quads at.
|
||||
* @param quadStart The starting quad index.
|
||||
* @param partIndex The part index to store for each quad buffered.
|
||||
* @return The number of quads buffered, not the string length.
|
||||
*/
|
||||
int32_t bufferQuads(
|
||||
struct UILabelText text,
|
||||
struct FontShaderBufferData &bufferData,
|
||||
std::map<NewTrueTypeFaceTexture*, int32_t> &textureMap,
|
||||
glm::vec2 &position,
|
||||
int32_t quadStart,
|
||||
int32_t partIndex
|
||||
);
|
||||
|
||||
|
||||
public:
|
||||
std::string test;
|
||||
|
||||
UILabelNew(SceneItem *item);
|
||||
|
||||
void onStart() override;
|
||||
std::vector<struct ShaderPassItem> getUIRenderPasses() override;
|
||||
float_t getWidth() override;
|
||||
float_t getHeight() override;
|
||||
float_t getContentWidth() override;
|
||||
float_t getContentHeight() override;
|
||||
|
||||
void rebufferQuads(std::vector<struct UILabelText> texts);
|
||||
};
|
||||
}
|
Reference in New Issue
Block a user