TTF Prog
This commit is contained in:
@ -53,16 +53,17 @@ namespace Dawn {
|
||||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
#define COLOR_WHITE { 1.0f, 1.0f, 1.0f, 1.0f }
|
||||
#define COLOR_RED { 1.0f, 0, 0, 1.0f }
|
||||
#define COLOR_GREEN { 0, 1.0f, 0, 1.0f }
|
||||
#define COLOR_BLUE { 0, 0, 1.0f, 1.0f }
|
||||
#define COLOR_BLACK { 0, 0, 0, 1.0f }
|
||||
#define COLOR_MAGENTA { 1.0f, 0, 1.0f, 1.0f }
|
||||
#define COLOR_DARK_GREY { 0.19607843137254901961f, 0.19607843137254901961f, 0.19607843137254901961f, 1.0f }
|
||||
#define COLOR_LIGHT_GREY { 0.8f, 0.8f, 0.8f, 1.0f }
|
||||
#define COLOR_CORNFLOWER_BLUE { 0.39215686274509803922f, 0.58431372549019607843f, 0.92941176470588235294f, 1.0f }
|
||||
#define COLOR_WHITE_TRANSPARENT { 1.0f, 1.0f, 1.0f, 0 }
|
||||
#define COLOR_BLACK_TRANSPARENT { 0, 0, 0, 0 }
|
||||
#define COLOR_TRANSPARENT COLOR_BLACK_TRANSPARENT
|
||||
#define COLOR_DEF(r,g,b,a) { r, g, b, a }
|
||||
#define COLOR_WHITE COLOR_DEF(1.0f, 1.0f, 1.0f, 1.0f)
|
||||
#define COLOR_RED COLOR_DEF(1.0f, 0, 0, 1.0f)
|
||||
#define COLOR_GREEN COLOR_DEF(0, 1.0f, 0, 1.0f)
|
||||
#define COLOR_BLUE COLOR_DEF(0, 0, 1.0f, 1.0f)
|
||||
#define COLOR_BLACK COLOR_DEF(0, 0, 0, 1.0f)
|
||||
#define COLOR_MAGENTA COLOR_DEF(1.0f, 0, 1.0f, 1.0f)
|
||||
#define COLOR_DARK_GREY COLOR_DEF(0.2f, 0.2f, 0.2f, 1.0f)
|
||||
#define COLOR_LIGHT_GREY COLOR_DEF(0.8f, 0.8f, 0.8f, 1.0f)
|
||||
#define COLOR_CORNFLOWER_BLUE COLOR_DEF(0.4f, 0.6f, 0.9f, 1.0f)
|
||||
#define COLOR_WHITE_TRANSPARENT COLOR_DEF(1.0f, 1.0f, 1.0f, 0.0f)
|
||||
#define COLOR_BLACK_TRANSPARENT COLOR_DEF(0.0f, 0.0f, 0.0f, 0.0f)
|
||||
#define COLOR_TRANSPARENT COLOR_BLACK_TRANSPARENT
|
||||
}
|
@ -7,9 +7,18 @@
|
||||
|
||||
using namespace Dawn;
|
||||
|
||||
FontManager::FontManager() {
|
||||
|
||||
}
|
||||
|
||||
void FontManager::init() {
|
||||
// Init FreeType
|
||||
if(FT_Init_FreeType(&fontLibrary)) {
|
||||
std::cout << "ERROR::FREETYPE: Could not init FreeType Library" << std::endl;
|
||||
assertUnreachable();
|
||||
}
|
||||
}
|
||||
|
||||
FontManager::~FontManager() {
|
||||
|
||||
}
|
@ -14,6 +14,10 @@ namespace Dawn {
|
||||
public:
|
||||
FT_Library fontLibrary;
|
||||
|
||||
FontManager();
|
||||
|
||||
void init();
|
||||
|
||||
~FontManager();
|
||||
};
|
||||
}
|
@ -7,17 +7,30 @@
|
||||
|
||||
using namespace Dawn;
|
||||
|
||||
void Dawn::_newTrueTypePlaceholder(
|
||||
FT_Face face,
|
||||
Texture &texture,
|
||||
std::map<FT_ULong, struct TrueTypeCharacterInfo> &charStore
|
||||
NewTrueTypeFaceTexture::NewTrueTypeFaceTexture(
|
||||
NewTrueTypeFace *trueTypeFace,
|
||||
FT_Face &face,
|
||||
struct NewTrueTypeFaceTextureStyle style
|
||||
) {
|
||||
assertNotNull(trueTypeFace);
|
||||
assertTrue(this->style.fontSize < 256);
|
||||
|
||||
this->trueTypeFace = trueTypeFace;
|
||||
this->face = &face;
|
||||
this->style = style;
|
||||
|
||||
// Set freetype font size prior to baking.
|
||||
if(FT_Set_Pixel_Sizes(face, 0, this->style.fontSize)) {
|
||||
assertUnreachable();
|
||||
}
|
||||
|
||||
size_t w = 0, h = 0;
|
||||
FT_ULong c;
|
||||
|
||||
// First pass, determine the textures' dimensions.
|
||||
for(c = NEW_TRUETYPE_CHAR_BEGIN; c < NEW_TRUETYPE_CHAR_END; c++) {
|
||||
// Load the character
|
||||
if(FT_Load_Char(face, c, FT_LOAD_RENDER)) {
|
||||
if(FT_Load_Char(face, c, FT_LOAD_RENDER | FT_LOAD_MONOCHROME)) {
|
||||
assertUnreachable();
|
||||
}
|
||||
|
||||
@ -26,16 +39,18 @@ void Dawn::_newTrueTypePlaceholder(
|
||||
h += face->glyph->bitmap.rows;
|
||||
}
|
||||
|
||||
assertTrue(w > 0);
|
||||
assertTrue(h > 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 *)memoryAllocate(w * h * sizeof(uint8_t));
|
||||
memorySet(buffer, 0x00, sizeof(uint8_t) * w * h);
|
||||
uint8_t *buffer = (uint8_t *)memoryFillWithZero(w * h * sizeof(uint8_t));
|
||||
|
||||
size_t offset = 0;
|
||||
struct NewTrueTypeCharacter info;
|
||||
for(c = NEW_TRUETYPE_CHAR_BEGIN; c < NEW_TRUETYPE_CHAR_END; c++) {
|
||||
// Load the character
|
||||
if(FT_Load_Char(face, c, FT_LOAD_RENDER)) {
|
||||
@ -43,26 +58,51 @@ void Dawn::_newTrueTypePlaceholder(
|
||||
}
|
||||
|
||||
// Store the character information
|
||||
struct TrueTypeCharacterInfo info;
|
||||
info.advance = glm::vec2(face->glyph->advance.x, face->glyph->advance.y);
|
||||
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.bitmapPosition = glm::vec2(face->glyph->bitmap_left, -face->glyph->bitmap_top);
|
||||
info.textureY = y;
|
||||
charStore[c] = info;
|
||||
this->characterData[c] = info;
|
||||
|
||||
// Buffer the pixels, oh dear GOD there has to be a more efficient way.
|
||||
for(uint32_t i = 0; i < face->glyph->bitmap.rows; i++) {
|
||||
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;
|
||||
}
|
||||
|
||||
texture.setSize(w, h, TEXTURE_FORMAT_R);
|
||||
texture.buffer(buffer);
|
||||
this->texture.setSize(w, h, TEXTURE_FORMAT_R);
|
||||
this->texture.buffer(buffer);
|
||||
memoryFree(buffer);
|
||||
}
|
||||
|
||||
struct NewTrueTypeCharacter NewTrueTypeFaceTexture::getCharacterData(FT_ULong c) {
|
||||
return this->characterData[c];
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
NewTrueTypeFace::NewTrueTypeFace(FT_Face *face) {
|
||||
assertNotNull(face);
|
||||
this->face = face;
|
||||
}
|
||||
|
||||
usagelockid_t NewTrueTypeFace::lock(struct NewTrueTypeFaceTextureStyle style) {
|
||||
|
||||
}
|
||||
|
||||
NewTrueTypeFace::~NewTrueTypeFace() {
|
||||
auto it = this->textures.begin();
|
||||
while(it != this->textures.end()) {
|
||||
delete *it;
|
||||
it = this->textures.erase(it);
|
||||
}
|
||||
}
|
@ -6,22 +6,90 @@
|
||||
#pragma once
|
||||
#include "dawnlibs.hpp"
|
||||
#include "util/mathutils.hpp"
|
||||
#include "util/flag.hpp"
|
||||
#include "display/Texture.hpp"
|
||||
#include "util/UsageLock.hpp"
|
||||
|
||||
#define NEW_TRUETYPE_CHAR_BEGIN 0x00
|
||||
#define NEW_TRUETYPE_CHAR_END 0xFF
|
||||
#define NEW_TRUETYPE_CHAR_BEGIN 32
|
||||
#define NEW_TRUETYPE_CHAR_END 192
|
||||
|
||||
#define NEW_TRUETYPE_VARIANT_BOLD FLAG_DEFINE(0)
|
||||
#define NEW_TRUETYPE_VARIANT_ITALICS FLAG_DEFINE(1)
|
||||
|
||||
namespace Dawn {
|
||||
struct TrueTypeCharacterInfo {
|
||||
glm::vec2 advance;
|
||||
class NewTrueTypeFace;
|
||||
|
||||
typedef uint32_t newtruetypelock_t;
|
||||
|
||||
struct NewTrueTypeCharacter {
|
||||
int32_t advanceX;
|
||||
int32_t advanceY;
|
||||
glm::vec2 bitmapSize;
|
||||
glm::vec2 bitmapPosition;
|
||||
float_t textureY;
|
||||
};
|
||||
|
||||
void _newTrueTypePlaceholder(
|
||||
FT_Face face,
|
||||
Texture &texture,
|
||||
std::map<FT_ULong, struct TrueTypeCharacterInfo> &charStore
|
||||
);
|
||||
|
||||
struct NewTrueTypeFaceTextureStyle {
|
||||
uint32_t fontSize;
|
||||
flag_t style;
|
||||
};
|
||||
|
||||
class NewTrueTypeFaceTexture {
|
||||
protected:
|
||||
FT_Face *face;
|
||||
NewTrueTypeFace *trueTypeFace;
|
||||
std::map<FT_ULong, struct NewTrueTypeCharacter> characterData;
|
||||
struct NewTrueTypeFaceTextureStyle style;
|
||||
UsageLock locks;
|
||||
|
||||
public:
|
||||
Texture texture;
|
||||
|
||||
/**
|
||||
* Construct a new New True Type Face Texture object
|
||||
*
|
||||
* @param trueTypeFace Face that this texture belongs to.
|
||||
* @param face The freetype face object.
|
||||
* @param style Style that this font has, used for locking.
|
||||
*/
|
||||
NewTrueTypeFaceTexture(
|
||||
NewTrueTypeFace *trueTypeFace,
|
||||
FT_Face &face,
|
||||
struct NewTrueTypeFaceTextureStyle style
|
||||
);
|
||||
|
||||
/**
|
||||
* Returns the character data for the given character.
|
||||
*
|
||||
* @param c Character to get data for.
|
||||
* @return The Character data for the given character.
|
||||
*/
|
||||
struct NewTrueTypeCharacter getCharacterData(FT_ULong c);
|
||||
|
||||
/**
|
||||
* Destroys this true type face texture.
|
||||
*/
|
||||
~NewTrueTypeFaceTexture();
|
||||
|
||||
friend class NewTrueTypeFace;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
class NewTrueTypeFace {
|
||||
protected:
|
||||
std::vector<NewTrueTypeFaceTexture*> textures;
|
||||
FT_Face *face;
|
||||
std::map<struct NewTrueTypeFaceTextureStyle, NewTrueTypeFaceTexture*> texturesByStyle;
|
||||
std::map<struct NewTrueTypeFaceTextureStyle, std::vector<usagelockid_t>> locksByStyle;
|
||||
|
||||
public:
|
||||
NewTrueTypeFace(FT_Face *face);
|
||||
usagelockid_t lock(struct NewTrueTypeFaceTextureStyle style);
|
||||
void unlock(usagelockid_t lock);
|
||||
NewTrueTypeFaceTexture * getTexture(usagelockid_t lock);
|
||||
~NewTrueTypeFace();
|
||||
};
|
||||
}
|
@ -8,7 +8,125 @@
|
||||
|
||||
using namespace Dawn;
|
||||
|
||||
void _uiLabelBake(
|
||||
UILabelNew::UILabelNew(SceneItem *item) : UIComponentRenderable(item) {
|
||||
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
|
||||
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(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);
|
||||
|
||||
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() {
|
||||
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;
|
||||
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 };
|
||||
}
|
||||
|
||||
|
||||
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::bakeTexture(
|
||||
struct UILabelFontDef &fontDef,
|
||||
FT_Face &face,
|
||||
uint32_t fontSize
|
||||
@ -78,155 +196,45 @@ void _uiLabelBake(
|
||||
memoryFree(buffer);
|
||||
}
|
||||
|
||||
|
||||
|
||||
int32_t _uiLabelQuad(
|
||||
int32_t UILabelNew::bufferQuads(
|
||||
std::string text,
|
||||
Mesh *mesh,
|
||||
struct FontShaderBufferData &bufferData,
|
||||
struct UILabelFontDef &fontDef,
|
||||
glm::vec2 &position,
|
||||
int32_t quadStart,
|
||||
int32_t partIndex
|
||||
) {
|
||||
// Get string length
|
||||
int32_t len = text.length();
|
||||
if(mesh == nullptr) return len;
|
||||
|
||||
// Loop each char
|
||||
|
||||
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 = text[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);
|
||||
|
||||
QuadMesh::bufferQuadMeshWithZ(mesh,
|
||||
// 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);
|
||||
bufferData.fontQuadParts[j] = partIndex;
|
||||
|
||||
// Set the part index to the quad mappings
|
||||
bufferData.fontQuadMappings[j] = partIndex;
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
|
||||
|
||||
UILabelNew::UILabelNew(SceneItem *item) : UIComponentRenderable(item) {
|
||||
|
||||
}
|
||||
|
||||
void UILabelNew::onStart() {
|
||||
std::cout << "Hello new Label" << std::endl;
|
||||
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();
|
||||
}
|
||||
_uiLabelBake(defFace, face, 32);
|
||||
|
||||
|
||||
if(FT_New_Face(
|
||||
getGame()->renderManager.getFontManager()->fontLibrary,
|
||||
// "/usr/share/fonts/TTF/arialbd.ttf",
|
||||
"C:\\Windows\\Fonts\\arialbd.ttf",
|
||||
0,
|
||||
&faceBold
|
||||
)) {
|
||||
assertUnreachable();
|
||||
}
|
||||
_uiLabelBake(defFaceBold, faceBold, 32);
|
||||
|
||||
|
||||
if(FT_New_Face(
|
||||
getGame()->renderManager.getFontManager()->fontLibrary,
|
||||
// "/usr/share/fonts/TTF/ariali.ttf",
|
||||
"C:\\Windows\\Fonts\\ariali.ttf",
|
||||
0,
|
||||
&faceItalics
|
||||
)) {
|
||||
assertUnreachable();
|
||||
}
|
||||
_uiLabelBake(defFaceItalics, faceItalics, 32);
|
||||
|
||||
struct FontShaderBufferData fontData;
|
||||
|
||||
glm::vec2 position = glm::vec2(32, 32);
|
||||
|
||||
testMesh.createBuffers(QUAD_VERTICE_COUNT * 96, QUAD_INDICE_COUNT * 96);
|
||||
auto x = _uiLabelQuad(
|
||||
"Hello ",
|
||||
&this->testMesh,
|
||||
fontData,
|
||||
defFace,
|
||||
position,
|
||||
0,
|
||||
0
|
||||
);
|
||||
x += _uiLabelQuad(
|
||||
"World",
|
||||
&this->testMesh,
|
||||
fontData,
|
||||
defFaceItalics,
|
||||
position,
|
||||
x,
|
||||
1
|
||||
);
|
||||
|
||||
fontData.fontParts[0].color = COLOR_MAGENTA;
|
||||
fontData.fontParts[0].texture = 0;
|
||||
fontData.fontParts[1].color = COLOR_RED;
|
||||
fontData.fontParts[1].texture = 1;
|
||||
shaderBuffer.buffer(&fontData);
|
||||
}
|
||||
|
||||
std::vector<struct ShaderPassItem> UILabelNew::getUIRenderPasses() {
|
||||
auto canvas = this->getCanvas();
|
||||
auto shader = getGame()->renderManager.fontShader;
|
||||
|
||||
struct ShaderPassItem item;
|
||||
item.shader = shader;
|
||||
item.mesh = &testMesh;
|
||||
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;
|
||||
item.textureSlots[0] = &defFace.texture;
|
||||
item.textureSlots[1] = &defFaceItalics.texture;
|
||||
item.textureValues[shader->paramTexture0] = 0;
|
||||
item.textureValues[shader->paramTexture1] = 1;
|
||||
|
||||
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;
|
||||
}
|
@ -7,38 +7,17 @@
|
||||
#include "scene/components/ui/UIComponentRenderable.hpp"
|
||||
#include "display/mesh/QuadMesh.hpp"
|
||||
|
||||
|
||||
#define NEW_LABEL_CHAR_BEGIN 32
|
||||
#define NEW_LABEL_CHAR_END 192
|
||||
|
||||
namespace Dawn {
|
||||
struct UILabelChar {
|
||||
int32_t advanceX;
|
||||
int32_t advanceY;
|
||||
glm::vec2 bitmapSize;
|
||||
glm::vec2 bitmapPosition;
|
||||
float_t textureY;
|
||||
};
|
||||
|
||||
struct UILabelFontDef {
|
||||
Texture texture;
|
||||
uint32_t fontSize;
|
||||
FT_Face *face;
|
||||
std::map<FT_ULong, struct UILabelChar> charStore;
|
||||
};
|
||||
|
||||
struct UILabelPart {
|
||||
struct UILabelStyle {
|
||||
struct Color;
|
||||
UILabelFontDef *fontDef;
|
||||
std::string text;
|
||||
};
|
||||
|
||||
class UILabelNew : public UIComponentRenderable {
|
||||
protected:
|
||||
private:
|
||||
Mesh mesh;
|
||||
FontShaderBuffer shaderBuffer;
|
||||
|
||||
Mesh testMesh;
|
||||
|
||||
FT_Face face;
|
||||
FT_Face faceBold;
|
||||
FT_Face faceItalics;
|
||||
@ -47,6 +26,27 @@ namespace Dawn {
|
||||
struct UILabelFontDef defFaceBold;
|
||||
struct UILabelFontDef defFaceItalics;
|
||||
|
||||
/**
|
||||
* Buffers the quads for the given text and updates the progressing values
|
||||
* as the buffer process continues.
|
||||
*
|
||||
* @param text Text to buffer.
|
||||
* @param bufferData The output quad mappings for the text.
|
||||
* @param fontDef The font definition to use.
|
||||
* @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(
|
||||
std::string text,
|
||||
struct FontShaderBufferData &bufferData,
|
||||
struct UILabelFontDef &fontDef,
|
||||
glm::vec2 &position,
|
||||
int32_t quadStart,
|
||||
int32_t partIndex
|
||||
);
|
||||
|
||||
public:
|
||||
UILabelNew(SceneItem *item);
|
||||
|
||||
|
@ -19,18 +19,18 @@ void FontShader::compile() {
|
||||
"#version 330 core\n"
|
||||
"layout (location = 0) in vec3 aPos;\n"
|
||||
"layout (location = 1) in vec2 aTexCoord;\n"
|
||||
|
||||
"layout (std140) uniform ub_UICanvas {\n"
|
||||
"mat4 u_View;\n"
|
||||
"mat4 u_Projection;\n"
|
||||
"};"
|
||||
"struct FontShaderPart {\n"
|
||||
"vec4 color;\n"
|
||||
"int texture;\n"
|
||||
"};\n"
|
||||
|
||||
"layout (shared) uniform ub_Font {\n"
|
||||
"FontShaderPart u_FontParts[" MACRO_STRINGIFY(FONT_SHADER_PARTS_MAX) "];\n"
|
||||
"int u_FontQuadParts[" MACRO_STRINGIFY(FONT_SHADER_QUADS_MAX) "];\n"
|
||||
"int u_FontQuadMappings[" MACRO_STRINGIFY(FONT_SHADER_QUADS_MAX) "];\n"
|
||||
"int u_FontTextures[" MACRO_STRINGIFY(FONT_SHADER_PARTS_MAX) "];\n"
|
||||
"vec4 u_FontColors[" MACRO_STRINGIFY(FONT_SHADER_PARTS_MAX) "];\n"
|
||||
"};\n"
|
||||
|
||||
"uniform mat4 u_Model;\n"
|
||||
"out vec2 o_TextCoord;\n"
|
||||
"out vec4 o_VertColor;\n"
|
||||
@ -40,10 +40,9 @@ void FontShader::compile() {
|
||||
"gl_Position = u_Projection * u_View * u_Model * vec4(aPos.xy, 0, 1.0);\n"
|
||||
"o_TextCoord = vec2(aTexCoord.x, aTexCoord.y);\n"
|
||||
"int quadIndex = gl_VertexID / " MACRO_STRINGIFY(QUAD_VERTICE_COUNT) ";\n"
|
||||
"int partIndex = quadIndex < 5 ? 0 : 1;\n"
|
||||
// "int partIndex = u_FontQuadParts[0];\n"
|
||||
"o_VertColor = u_FontParts[partIndex].color;\n"
|
||||
"o_TextIndex = u_FontParts[partIndex].texture;\n"
|
||||
"int partIndex = u_FontQuadMappings[quadIndex];\n"
|
||||
"o_VertColor = u_FontColors[partIndex];\n"
|
||||
"o_TextIndex = u_FontTextures[partIndex];\n"
|
||||
"}",
|
||||
|
||||
// Fragment Shader
|
||||
@ -54,16 +53,19 @@ void FontShader::compile() {
|
||||
"out vec4 o_Color;\n"
|
||||
"uniform sampler2D u_Text0;\n"
|
||||
"uniform sampler2D u_Text1;\n"
|
||||
"uniform sampler2D u_Text2;\n"
|
||||
|
||||
"void main() {\n"
|
||||
"o_Color = o_VertColor;\n"
|
||||
"vec4 textColor;\n"
|
||||
"vec4 tColor;"
|
||||
"if(o_TextIndex == 0) \n{"
|
||||
"textColor = texture(u_Text0, o_TextCoord);\n"
|
||||
"tColor = texture(u_Text0, o_TextCoord);\n"
|
||||
"} else if(o_TextIndex == 1) \n{"
|
||||
"tColor = texture(u_Text1, o_TextCoord);\n"
|
||||
"} else {\n"
|
||||
"textColor = texture(u_Text1, o_TextCoord);\n"
|
||||
"tColor = texture(u_Text2, o_TextCoord);\n"
|
||||
"}\n"
|
||||
"o_Color.a = textColor.r;\n"
|
||||
"o_Color.a *= tColor.r;\n"
|
||||
"}\n"
|
||||
);
|
||||
#else
|
||||
@ -75,4 +77,5 @@ void FontShader::compile() {
|
||||
this->bufferFont = this->getBufferLocationByName("ub_Font");
|
||||
this->paramTexture0 = this->getParameterByName("u_Text0");
|
||||
this->paramTexture1 = this->getParameterByName("u_Text1");
|
||||
this->paramTexture2 = this->getParameterByName("u_Text2");
|
||||
}
|
@ -7,24 +7,18 @@
|
||||
#include "UIShader.hpp"
|
||||
#include "util/macro.hpp"
|
||||
|
||||
#define FONT_SHADER_PARTS_MAX 6
|
||||
#define FONT_SHADER_QUADS_MAX 64
|
||||
#define FONT_SHADER_PARTS_MAX 4
|
||||
#define FONT_SHADER_QUADS_MAX 32
|
||||
#define FONT_SHADER_TEXTURE_MAX 8
|
||||
|
||||
namespace Dawn {
|
||||
#pragma pack(push, 1)
|
||||
struct FontShaderPart {
|
||||
struct Color color;
|
||||
int32_t texture;
|
||||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
#pragma pack(push, 1)
|
||||
// #pragma pack(push, 4)
|
||||
struct FontShaderBufferData {
|
||||
struct FontShaderPart fontParts[FONT_SHADER_PARTS_MAX];
|
||||
int32_t fontQuadParts[FONT_SHADER_QUADS_MAX];
|
||||
int32_t fontQuadMappings[FONT_SHADER_QUADS_MAX];
|
||||
int32_t textures[FONT_SHADER_PARTS_MAX];
|
||||
struct Color colors[FONT_SHADER_PARTS_MAX];
|
||||
};
|
||||
#pragma pack(pop)
|
||||
// #pragma pack(pop)
|
||||
|
||||
class FontShaderBuffer : public ShaderParameterBuffer<struct FontShaderBufferData> {
|
||||
|
||||
@ -35,6 +29,7 @@ namespace Dawn {
|
||||
shaderparameter_t paramModel;
|
||||
shaderparameter_t paramTexture0;
|
||||
shaderparameter_t paramTexture1;
|
||||
shaderparameter_t paramTexture2;
|
||||
shaderbufferlocation_t bufferUiCanvas;
|
||||
shaderbufferlocation_t bufferFont;
|
||||
|
||||
|
@ -18,6 +18,7 @@ set(
|
||||
DAWN_SHARED_SOURCES
|
||||
${D}/assert/assert.cpp
|
||||
${D}/util/Xml.cpp
|
||||
${D}/util/UsageLock.cpp
|
||||
|
||||
CACHE INTERNAL
|
||||
${DAWN_CACHE_TARGET}
|
||||
|
27
src/dawnshared/util/UsageLock.cpp
Normal file
27
src/dawnshared/util/UsageLock.cpp
Normal file
@ -0,0 +1,27 @@
|
||||
// Copyright (c) 2023 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#include "util/UsageLock.hpp"
|
||||
|
||||
using namespace Dawn;
|
||||
|
||||
UsageLock::UsageLock() {
|
||||
this->onEmpty = []() {};
|
||||
this->onFirstLock = []() {};
|
||||
}
|
||||
|
||||
usagelockid_t UsageLock::createLock() {
|
||||
usagelockid_t lock = this->nextLock++;
|
||||
this->locks.push_back(lock);
|
||||
if(this->locks.size() == 1) this->onFirstLock();
|
||||
return lock;
|
||||
}
|
||||
|
||||
void UsageLock::removeLock(usagelockid_t lock) {
|
||||
auto it = std::find(this->locks.begin(), this->locks.end(), lock);
|
||||
if(it == this->locks.end()) return;
|
||||
this->locks.erase(it);
|
||||
if(this->locks.size() == 0) this->onEmpty();
|
||||
}
|
39
src/dawnshared/util/UsageLock.hpp
Normal file
39
src/dawnshared/util/UsageLock.hpp
Normal file
@ -0,0 +1,39 @@
|
||||
// Copyright (c) 2023 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#include "assert/assert.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
typedef uint32_t usagelockid_t;
|
||||
|
||||
class UsageLock {
|
||||
protected:
|
||||
usagelockid_t nextLock = 0;
|
||||
std::vector<usagelockid_t> locks;
|
||||
|
||||
public:
|
||||
std::function<void()> onEmpty;
|
||||
std::function<void()> onFirstLock;
|
||||
|
||||
/**
|
||||
* Construct a new usage lock object.
|
||||
*/
|
||||
UsageLock();
|
||||
|
||||
/**
|
||||
* Creates a new lock.
|
||||
*
|
||||
* @return Lock created for this specific instance.
|
||||
*/
|
||||
usagelockid_t createLock();
|
||||
|
||||
/**
|
||||
* Removes a lock.
|
||||
*
|
||||
* @param lock Lck to remove.
|
||||
*/
|
||||
void removeLock(usagelockid_t lock);
|
||||
};
|
||||
}
|
Reference in New Issue
Block a user