About 3/4 done with new font system

This commit is contained in:
2023-06-09 23:12:10 -07:00
parent 8b3ecc88a6
commit 1af1f9ef14
23 changed files with 383 additions and 332 deletions

View File

@ -8,87 +8,94 @@
using namespace Dawn;
UILabelNew::UILabelNew(SceneItem *item) : UIComponentRenderable(item) {
UILabelNew::UILabelNew(SceneItem *item) :
UIComponentRenderable(item),
font(nullptr),
fontSize(16),
style(0)
{
}
void UILabelNew::rebufferQuads() {
this->mesh.createBuffers(QUAD_VERTICE_COUNT * 128, QUAD_INDICE_COUNT * 128);
auto texture = this->font->getTexture(this->fontLock);
texture.
}
void UILabelNew::onStart() {
this->shaderBuffer.init();
if(FT_New_Face(
getGame()->renderManager.getFontManager()->fontLibrary,
"/usr/share/fonts/TTF/arial.ttf",
// "C:\\Windows\\Fonts\\arial.ttf",
0,
&face
)) {
assertUnreachable();
}
UILabelNew::bakeTexture(defFace, face, 32);
useEffect([&]{
if(fontLock != -1) {
font.previous->unlock(fontLock);
fontLock = -1;
}
if(FT_New_Face(
getGame()->renderManager.getFontManager()->fontLibrary,
"/usr/share/fonts/TTF/arialbd.ttf",
// "C:\\Windows\\Fonts\\arialbd.ttf",
0,
&faceBold
)) {
assertUnreachable();
}
UILabelNew::bakeTexture(defFaceBold, faceBold, 32);
if(font == nullptr) return;
fontLock = font->lock(NewTrueTypeFaceTextureStyle{
fontSize,
style
});
}, font);
if(FT_New_Face(
getGame()->renderManager.getFontManager()->fontLibrary,
"/usr/share/fonts/TTF/ariali.ttf",
// "C:\\Windows\\Fonts\\ariali.ttf",
0,
&faceItalics
)) {
assertUnreachable();
}
UILabelNew::bakeTexture(defFaceItalics, faceItalics, 32);
useEffect([&]{
if(font == nullptr) return;
struct FontShaderBufferData fontData;
glm::vec2 position = glm::vec2(32, 32);
if(fontLock != -1) {
font->unlock(fontLock);
fontLock = -1;
}
mesh.createBuffers(QUAD_VERTICE_COUNT * 128, QUAD_INDICE_COUNT * 128);
auto x = UILabelNew::bufferQuads(
"Hello ",
fontData,
defFace,
position,
0,
0
);
x += UILabelNew::bufferQuads(
" World",
fontData,
defFaceItalics,
position,
x,
1
);
x += UILabelNew::bufferQuads(
" How are you?",
fontData,
defFaceBold,
position,
x,
2
);
fontLock = font->lock(NewTrueTypeFaceTextureStyle{
fontSize,
style
});
}, { &fontSize, &style });
fontData.colors[0] = COLOR_MAGENTA;
fontData.textures[0] = 0;
fontData.colors[1] = COLOR_RED;
fontData.textures[1] = 1;
fontData.colors[2] = COLOR_GREEN;
fontData.textures[2] = 2;
shaderBuffer.buffer(&fontData);
// struct FontShaderBufferData fontData;
// glm::vec2 position = glm::vec2(32, 32);
// mesh.createBuffers(QUAD_VERTICE_COUNT * 128, QUAD_INDICE_COUNT * 128);
// auto x = UILabelNew::bufferQuads(
// "Hello ",
// fontData,
// defFace,
// position,
// 0,
// 0
// );
// x += UILabelNew::bufferQuads(
// " World",
// fontData,
// defFaceItalics,
// position,
// x,
// 1
// );
// x += UILabelNew::bufferQuads(
// " How are you?",
// fontData,
// defFaceBold,
// position,
// x,
// 2
// );
// fontData.colors[0] = COLOR_MAGENTA;
// fontData.textures[0] = 0;
// fontData.colors[1] = COLOR_RED;
// fontData.textures[1] = 1;
// fontData.colors[2] = COLOR_GREEN;
// fontData.textures[2] = 2;
// shaderBuffer.buffer(&fontData);
}
std::vector<struct ShaderPassItem> UILabelNew::getUIRenderPasses() {
if(this->fontLock == -1) return {};
auto canvas = this->getCanvas();
auto shader = getGame()->renderManager.fontShader;
@ -99,12 +106,12 @@ std::vector<struct ShaderPassItem> UILabelNew::getUIRenderPasses() {
item.parameterBuffers[shader->bufferUiCanvas] = &canvas->shaderBuffer;
item.parameterBuffers[shader->bufferFont] = &this->shaderBuffer;
item.renderFlags = RENDER_MANAGER_RENDER_FLAG_BLEND;
item.textureSlots[0] = &defFace.texture;
item.textureSlots[1] = &defFaceItalics.texture;
item.textureSlots[2] = &defFaceBold.texture;
item.textureValues[shader->paramTexture0] = 0;
item.textureValues[shader->paramTexture1] = 1;
item.textureValues[shader->paramTexture2] = 2;
// item.textureSlots[0] = &defFace.texture;
// item.textureSlots[1] = &defFaceItalics.texture;
// item.textureSlots[2] = &defFaceBold.texture;
// item.textureValues[shader->paramTexture0] = 0;
// item.textureValues[shader->paramTexture1] = 1;
// item.textureValues[shader->paramTexture2] = 2;
return { item };
}
@ -126,115 +133,115 @@ float_t UILabelNew::getContentHeight() {
return 0;
}
void UILabelNew::bakeTexture(
struct UILabelFontDef &fontDef,
FT_Face &face,
uint32_t fontSize
) {
fontDef.face = &face;
fontDef.fontSize = fontSize;
// void UILabelNew::bakeTexture(
// struct UILabelFontDef &fontDef,
// FT_Face &face,
// uint32_t fontSize
// ) {
// fontDef.face = &face;
// fontDef.fontSize = fontSize;
if(FT_Set_Pixel_Sizes(face, 0, fontSize)) {
assertUnreachable();
}
// if(FT_Set_Pixel_Sizes(face, 0, fontSize)) {
// assertUnreachable();
// }
size_t w = 0, h = 0;
FT_ULong c;
// size_t w = 0, h = 0;
// FT_ULong c;
for(c = NEW_LABEL_CHAR_BEGIN; c < NEW_LABEL_CHAR_END; c++) {
// Load the character
if(FT_Load_Char(face, c, FT_LOAD_RENDER | FT_LOAD_MONOCHROME)) {
assertUnreachable();
}
// for(c = NEW_LABEL_CHAR_BEGIN; c < NEW_LABEL_CHAR_END; c++) {
// // Load the character
// if(FT_Load_Char(face, c, FT_LOAD_RENDER | FT_LOAD_MONOCHROME)) {
// assertUnreachable();
// }
// Update the width and height
w = mathMax<size_t>(w, face->glyph->bitmap.width);
h += face->glyph->bitmap.rows;
}
// // Update the width and height
// w = mathMax<size_t>(w, face->glyph->bitmap.width);
// h += face->glyph->bitmap.rows;
// }
assertTrue(w > 0);
assertTrue(h > 0);
// assertTrue(w > 0);
// assertTrue(h > 0);
// Now buffer pixels to the texture
float_t y = 0;
// // Now buffer pixels to the texture
// float_t y = 0;
// I'd love to just buffer straight to the GPU, but it seems that is a bit
// unstable right now.
uint8_t *buffer = (uint8_t *)memoryFillWithZero(w * h * sizeof(uint8_t));
// // I'd love to just buffer straight to the GPU, but it seems that is a bit
// // unstable right now.
// uint8_t *buffer = (uint8_t *)memoryFillWithZero(w * h * sizeof(uint8_t));
size_t offset = 0;
for(c = NEW_LABEL_CHAR_BEGIN; c < NEW_LABEL_CHAR_END; c++) {
// Load the character
if(FT_Load_Char(face, c, FT_LOAD_RENDER)) {
assertUnreachable();
}
// size_t offset = 0;
// for(c = NEW_LABEL_CHAR_BEGIN; c < NEW_LABEL_CHAR_END; c++) {
// // Load the character
// if(FT_Load_Char(face, c, FT_LOAD_RENDER)) {
// assertUnreachable();
// }
// Store the character information
struct UILabelChar info;
info.advanceX = face->glyph->advance.x;
info.advanceY = face->glyph->advance.y;
info.bitmapSize = glm::vec2(face->glyph->bitmap.width, face->glyph->bitmap.rows);
info.bitmapPosition = glm::vec2(face->glyph->bitmap_left, -face->glyph->bitmap_top);
info.textureY = y;
fontDef.charStore[c] = info;
// // Store the character information
// struct UILabelChar info;
// info.advanceX = face->glyph->advance.x;
// info.advanceY = face->glyph->advance.y;
// info.bitmapSize = glm::vec2(face->glyph->bitmap.width, face->glyph->bitmap.rows);
// info.bitmapPosition = glm::vec2(face->glyph->bitmap_left, -face->glyph->bitmap_top);
// info.textureY = y;
// fontDef.charStore[c] = info;
// Buffer the pixels, oh dear GOD there has to be a more efficient way.
for(int32_t i = 0; i < face->glyph->bitmap.rows; i++) {
memoryCopy(
(void *)(face->glyph->bitmap.buffer + (i * face->glyph->bitmap.width)),
(void *)(buffer + offset),
face->glyph->bitmap.width * sizeof(uint8_t)
);
offset += w * sizeof(uint8_t);
assertTrue(offset <= (w * h * sizeof(uint8_t)));
}
y += face->glyph->bitmap.rows;
}
// // Buffer the pixels, oh dear GOD there has to be a more efficient way.
// for(int32_t i = 0; i < face->glyph->bitmap.rows; i++) {
// memoryCopy(
// (void *)(face->glyph->bitmap.buffer + (i * face->glyph->bitmap.width)),
// (void *)(buffer + offset),
// face->glyph->bitmap.width * sizeof(uint8_t)
// );
// offset += w * sizeof(uint8_t);
// assertTrue(offset <= (w * h * sizeof(uint8_t)));
// }
// y += face->glyph->bitmap.rows;
// }
fontDef.texture.setSize(w, h, TEXTURE_FORMAT_R);
fontDef.texture.buffer(buffer);
memoryFree(buffer);
}
// fontDef.texture.setSize(w, h, TEXTURE_FORMAT_R);
// fontDef.texture.buffer(buffer);
// memoryFree(buffer);
// }
int32_t UILabelNew::bufferQuads(
std::string text,
struct FontShaderBufferData &bufferData,
struct UILabelFontDef &fontDef,
glm::vec2 &position,
int32_t quadStart,
int32_t partIndex
) {
// Get string length
int32_t len = text.length();
// int32_t UILabelNew::bufferQuads(
// std::string text,
// struct FontShaderBufferData &bufferData,
// struct UILabelFontDef &fontDef,
// glm::vec2 &position,
// int32_t quadStart,
// int32_t partIndex
// ) {
// // Get string length
// int32_t len = text.length();
glm::vec2 wh = glm::vec2(fontDef.texture.getWidth(), fontDef.texture.getHeight());
// glm::vec2 wh = glm::vec2(fontDef.texture.getWidth(), fontDef.texture.getHeight());
// For each char
for(int32_t i = 0; i < len; i++) {
char ch = text[i];
int32_t j = quadStart + i;
FT_ULong c = ch;
auto &charInfo = fontDef.charStore[c];
// // For each char
// for(int32_t i = 0; i < len; i++) {
// char ch = text[i];
// int32_t j = quadStart + i;
// FT_ULong c = ch;
// auto &charInfo = fontDef.charStore[c];
// Determine texture coordinates.
glm::vec2 uv0 = glm::vec2(0.0f, charInfo.textureY) / wh;
glm::vec2 uv1 = uv0 + (charInfo.bitmapSize / wh);
// // 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
);
// // 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 += (float_t)(charInfo.advanceX >> 6);
position.y += (float_t)(charInfo.advanceY >> 6);
// // Move the current position along.
// position.x += (float_t)(charInfo.advanceX >> 6);
// position.y += (float_t)(charInfo.advanceY >> 6);
// Set the part index to the quad mappings
bufferData.fontQuadMappings[j] = partIndex;
}
// // Set the part index to the quad mappings
// bufferData.fontQuadMappings[j] = partIndex;
// }
return len;
}
// return len;
// }

View File

@ -6,11 +6,12 @@
#pragma once
#include "scene/components/ui/UIComponentRenderable.hpp"
#include "display/mesh/QuadMesh.hpp"
#include "asset/assets/NewTrueTypeAsset.hpp"
namespace Dawn {
struct UILabelStyle {
struct Color;
UILabelFontDef *fontDef;
// UILabelFontDef *fontDef;
};
class UILabelNew : public UIComponentRenderable {
@ -18,13 +19,15 @@ namespace Dawn {
Mesh mesh;
FontShaderBuffer shaderBuffer;
FT_Face face;
FT_Face faceBold;
FT_Face faceItalics;
usagelockid_t fontLock = -1;
struct UILabelFontDef defFace;
struct UILabelFontDef defFaceBold;
struct UILabelFontDef defFaceItalics;
// FT_Face face;
// FT_Face faceBold;
// FT_Face faceItalics;
// struct UILabelFontDef defFace;
// struct UILabelFontDef defFaceBold;
// struct UILabelFontDef defFaceItalics;
/**
* Buffers the quads for the given text and updates the progressing values
@ -38,16 +41,22 @@ namespace Dawn {
* @param partIndex The part index to store for each quad buffered.
* @return The number of quads buffered, not the string length.
*/
int32_t bufferQuads(
std::string text,
struct FontShaderBufferData &bufferData,
struct UILabelFontDef &fontDef,
glm::vec2 &position,
int32_t quadStart,
int32_t partIndex
);
// int32_t bufferQuads(
// std::string text,
// struct FontShaderBufferData &bufferData,
// struct UILabelFontDef &fontDef,
// glm::vec2 &position,
// int32_t quadStart,
// int32_t partIndex
// );
void rebufferQuads();
public:
StateProperty<NewTrueTypeAsset*> font;
StateProperty<uint32_t> fontSize;
StateProperty<flag_t> style;
UILabelNew(SceneItem *item);
void onStart() override;