Adding bitmap fonts

This commit is contained in:
2023-03-14 18:55:10 -07:00
parent f5c5d1f49d
commit 9c9c64228a
17 changed files with 328 additions and 20 deletions

View File

@ -0,0 +1,124 @@
// Copyright (c) 2023 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#include "BitmapFont.hpp"
using namespace Dawn;
void BitmapFont::buffer(
std::string text,
float_t fontSize,
float_t maxWidth,
Mesh *mesh,
struct FontMeasure *info
) {
assertNotNull(mesh);
assertNotNull(info);
assertTrue(maxWidth == -1 || maxWidth > 0);
assertTrue(this->isReady());
// Initialize primitive
mesh->createBuffers(
QUAD_VERTICE_COUNT * text.size(),
QUAD_INDICE_COUNT * text.size()
);
// Setup Scales
info->length = 0;
info->realLength = 0;
info->lines.clear();
info->lineHeight = this->getLineHeight(fontSize);
// Prepare the line counters
info->addLine(0, 0);
// Reset Dimensions
char c;
Tile tile;
info->width = info->height = 0;
float_t x = 0;
float_t y = 0;
size_t i = 0;
size_t j = 0;
glm::vec2 xy0(0, 0);
glm::vec2 tileSize = glm::vec2(tileset->getTileWidth(), tileset->getTileHeight());
// Buffer quads
while(c = text[i++]) {
if(c == FONT_SPACE) {
// Did this space cause a newline?
if(maxWidth != -1 && xy0.x > maxWidth) {
info->addLine(i, 0);
info->width = mathMax<float_t>(info->width, xy0.x);
xy0.x = 0;
xy0.y += tileSize.y;
info->height = mathMax<float_t>(info->height, xy0.y);
continue;
}
xy0.x += tileSize.x;
continue;
}
if(c == FONT_NEWLINE) {
info->addLine(i, 0);
info->width = mathMax<float_t>(info->width, xy0.x);
xy0.x = 0;
xy0.y += tileSize.y;
info->height = mathMax<float_t>(info->height, xy0.y);
continue;
}
// Check for wrapping, todo.
if(maxWidth != -1 && (xy0.x+tileSize.x) > maxWidth) {
// We've exceeded the edge, go back to the start of the word and newline.
// Go back to the previous (still current) line and remove the chars
// Next line begins with this word
}
tile = this->tileset->getTile(c);
QuadMesh::bufferQuadMesh(mesh,
xy0, tile.uv0,
xy0+tileSize, tile.uv1,
j * QUAD_VERTICE_COUNT, j * QUAD_INDICE_COUNT
);
xy0.x += tileSize.x;//TODO: Spacing?
j++;
}
info->width = mathMax<float_t>(info->width, xy0.x);
info->height = mathMax<float_t>(info->height, xy0.y + (xy0.x > 0 ? tileSize.y : 0));
}
bool_t BitmapFont::isReady() {
if(this->texture == nullptr) return false;
if(this->tileset == nullptr) return false;
return this->texture->isReady();
}
Texture * BitmapFont::getTexture() {
return this->texture;
}
void BitmapFont::draw(Mesh *mesh, int32_t start, int32_t len) {
assertNotNull(mesh);
mesh->draw(
MESH_DRAW_MODE_TRIANGLES,
start * QUAD_INDICE_COUNT,
len == -1 ? len : len * QUAD_INDICE_COUNT
);
}
float_t BitmapFont::getLineHeight(float_t fontSize) {
return 16.0f;
}
float_t BitmapFont::getDefaultFontSize() {
return 16.0f;
}

View File

@ -0,0 +1,31 @@
// Copyright (c) 2023 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "Font.hpp"
#include "display/Tileset.hpp"
namespace Dawn {
class BitmapFont : public Font {
protected:
public:
Texture *texture = nullptr;
TilesetGrid *tileset = nullptr;
void buffer(
std::string text,
float_t fontSize,
float_t maxWidth,
Mesh *mesh,
struct FontMeasure *info
) override;
bool_t isReady() override;
Texture * getTexture() override;
void draw(Mesh *mesh, int32_t startCharacter, int32_t length) override;
float_t getLineHeight(float_t fontSize) override;
float_t getDefaultFontSize() override;
};
}

View File

@ -1,11 +1,12 @@
# 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
TrueTypeFont.cpp
FontMeasure.cpp
# 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
BitmapFont.cpp
TrueTypeFont.cpp
FontMeasure.cpp
)

View File

@ -9,6 +9,7 @@ target_sources(${DAWN_TARGET_NAME}
UICanvas.cpp
UIComponent.cpp
UILabel.cpp
UIImage.cpp
)
add_subdirectory(menu)

View File

@ -28,8 +28,8 @@ UIComponentDimensional * UIComponent::getParentDimensional() {
void UIComponent::updateAlignment() {
if(!this->alignmentNeedsUpdating) return;
auto dimensional = this->getParentDimensional();
auto align = (glm::vec4)this->alignment;
auto dimensional = this->getParentDimensional();
auto translate = this->transform->getLocalPosition();
UIComponent::calculateDimensions(
@ -51,7 +51,6 @@ void UIComponent::updateAlignment() {
this->transform->setLocalPosition(translate);
this->alignmentNeedsUpdating = false;
this->eventAlignmentUpdated.invoke();
}

View File

@ -0,0 +1,66 @@
// Copyright (c) 2023 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#include "UIImage.hpp"
#include "game/DawnGame.hpp"
using namespace Dawn;
UIImage::UIImage(SceneItem *item) :
texture(nullptr),
UIComponent(item)
{
}
float_t UIImage::getContentWidth() {
if(this->texture != nullptr) return this->texture->getWidth();
return this->width;
}
float_t UIImage::getContentHeight() {
if(this->texture != nullptr) return this->texture->getHeight();
return this->height;
}
std::vector<struct ShaderPassItem> UIImage::getPassItems(
glm::mat4 proj, glm::mat4 view
) {
struct ShaderPassItem item;
auto shader = &getGame()->renderManager.uiShaderProgram;
item.shaderProgram = shader;
item.colorValues[shader->paramColor] = this->color;
item.matrixValues[shader->paramProjection] = proj;
item.matrixValues[shader->paramView] = view;
item.matrixValues[shader->paramModel] = this->transform->getWorldTransform();
if(this->texture == nullptr) {
item.boolValues[shader->paramHasTexture] = false;
} else {
item.boolValues[shader->paramHasTexture] = true;
item.textureSlots[0] = this->texture;
item.textureValues[shader->paramTexture] = 0;
}
item.w = this->transform->getWorldPosition().z;
item.renderFlags = RENDER_MANAGER_RENDER_FLAG_BLEND;
item.mesh = &mesh;
return { item };
}
void UIImage::onStart() {
UIComponent::onStart();
useEvent([&]{
QuadMesh::bufferPositions(&mesh,
glm::vec2(0, 0), glm::vec2(width, height), 0
);
}, this->eventAlignmentUpdated);
QuadMesh::initQuadMesh(&mesh,
glm::vec2(0, 0), glm::vec2(0, 0),
glm::vec2(width, height), glm::vec2(1, 1),
0.0f
);
}

View File

@ -0,0 +1,30 @@
// Copyright (c) 2023 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "UIComponent.hpp"
#include "display/mesh/QuadMesh.hpp"
namespace Dawn {
class UIImage : public UIComponent, public UIComponentRenderable {
private:
Mesh mesh;
public:
struct Color color = COLOR_WHITE;
// StateProperty<float_t> width;
// StateProperty<float_t> height;
StateProperty<Texture*> texture;
UIImage(SceneItem *item);
float_t getContentWidth() override;
float_t getContentHeight() override;
std::vector<struct ShaderPassItem> getPassItems(
glm::mat4 proj, glm::mat4 view
) override;
void onStart() override;
};
}

View File

@ -82,7 +82,6 @@ std::vector<struct ShaderPassItem> UILabel::getPassItems(
}
float_t UILabel::getContentWidth() {
if(this->maxWidth > 0) return this->maxWidth;
if(!this->hasText()) return 0;
this->updateMesh();
return this->measure.getWidth();