feat: add text class

This commit is contained in:
2026-04-16 10:44:05 +08:00
parent a8726b06c3
commit 311c675852
9 changed files with 252 additions and 40 deletions

View File

@@ -104,6 +104,8 @@ void Renderer::init() {
glBindBuffer(GL_ARRAY_BUFFER, m_text_vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(float)* 6 * 4, NULL, GL_DYNAMIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
init_text();
}
const Shader& Renderer::get_shader(const std::string& name) const {
@@ -112,6 +114,23 @@ const Shader& Renderer::get_shader(const std::string& name) const {
return it->second;
}
void Renderer::init_text() {
const auto& shader = get_shader("text");
Text::set_loc(shader);
m_version_text
.position(0.0f, 100.0f)
.scale(0.8f)
.color(Color::WHITE)
.text("Version: v0.0.1-Debug");
m_fps_text
.position(0.0f, 50.0f)
.text("FPS: 0");
m_player_pos_text
.position(0.0f, 150.0f)
.scale(0.8f)
.text("x: 0.00 y: 0.00 z: 0.00");
}
void Renderer::render() {
glClearColor(0.0, 0.0, 0.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT);
@@ -192,15 +211,15 @@ void Renderer::render_text() {
m_proj_loc = shader.loc("projection");
glUniformMatrix4fv(m_proj_loc, 1, GL_FALSE, glm::value_ptr(m_ui_proj));
Font::render_text(shader, std::string{"FPS: " + std::to_string(static_cast<int>(App::get_fps()))}, 0.0f, 50.0f, 1.0f, glm::vec3(1.0f, 1.0f, 1.0f));
Font::render_text(shader, "Version: v0.0.1-Debug", 0.0f, 100.0f, 0.8f, glm::vec3(1.0f, 1.0f, 1.0f));
m_fps_text.text(std::string{"FPS: " + std::to_string(static_cast<int>(App::get_fps()))});
const auto& player = m_world.get_player("TestPlayer");
const auto& pos = player.get_player_pos();
std::string player_pos = std::format("x: {:.2f} y: {:.2f} z: {:.2f}", pos.x, pos.y, pos.z);
Font::render_text(shader, player_pos, 0.0f, 150.0f, 0.8f, glm::vec3(1.0f, 1.0f, 1.0f));
m_player_pos_text.text(player_pos);
m_fps_text.render();
m_player_pos_text.render();
m_version_text.render();
glEnable(GL_DEPTH_TEST);
}

View File

@@ -7,9 +7,9 @@ layout (location = 2) in float layer;
out vec2 tc;
flat out int tex_layer;
uniform mat4 projection;
uniform mat4 mv_matrix;
void main(void) {
gl_Position = projection * vec4(pos, 0.0, 1.0);
gl_Position = projection * mv_matrix * vec4(pos, 0.0, 1.0);
tc = texCoord;
tex_layer = int(layer);
}

View File

@@ -1,12 +1,10 @@
#include <Cubed/config.hpp>
#include <Cubed/shader.hpp>
#include <Cubed/tools/font.hpp>
#include <Cubed/tools/log.hpp>
#include <Cubed/tools/shader_tools.hpp>
Font::Font() {
if (FT_Init_FreeType(&m_ft)) {
@@ -24,9 +22,7 @@ Font::~Font() {
FT_Done_Face(m_face);
FT_Done_FreeType(m_ft);
for (const auto& [key, character] : m_characters) {
glDeleteTextures(1, &m_text_texture);
}
glDeleteTextures(1, &m_text_texture);
}
void Font::load_character(char8_t c) {
@@ -36,6 +32,7 @@ void Font::load_character(char8_t c) {
}
const auto& width = m_face->glyph->bitmap.width;
const auto& height = m_face->glyph->bitmap.rows;
glBindTexture(GL_TEXTURE_2D_ARRAY, m_text_texture);
glTexSubImage3D(
GL_TEXTURE_2D_ARRAY,
0,
@@ -90,13 +87,9 @@ void Font::setup_font_character() {
glBindTexture(GL_TEXTURE_2D_ARRAY, 0);
}
void Font::render_text(const Shader& shader, const std::string& text, float x, float y, float scale, const glm::vec3& color) {
std::vector<Vertex2D> Font::vertices(const std::string &text, float x, float y, float scale) {
static Font font;
glUniform3f(shader.loc("textColor"), color.x, color.y, color.z);
glActiveTexture(GL_TEXTURE0);
std::vector<Vertex2D> vertices;
for (char8_t c : text) {
@@ -122,22 +115,10 @@ void Font::render_text(const Shader& shader, const std::string& text, float x, f
x += (ch.advance >> 6) * scale;
}
GLuint vbo;
glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(Vertex2D), vertices.data(), GL_STATIC_DRAW);
glBindTexture(GL_TEXTURE_2D_ARRAY, font.m_text_texture);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex2D), (void*)0);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex2D), (void*)offsetof(Vertex2D, s));
glVertexAttribPointer(2, 1, GL_FLOAT, GL_FALSE, sizeof(Vertex2D), (void*)offsetof(Vertex2D, layer));
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
glEnableVertexAttribArray(2);
glDrawArrays(GL_TRIANGLES, 0, vertices.size());
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindTexture(GL_TEXTURE_2D_ARRAY, 0);
glDeleteBuffers(1, &vbo);
return vertices;
}
GLuint Font::text_texture() {
return m_text_texture;
}

90
src/ui/text.cpp Normal file
View File

@@ -0,0 +1,90 @@
#include <Cubed/ui/text.hpp>
#include <Cubed/shader.hpp>
#include <Cubed/tools/font.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>
Text::Text() {
}
Text::Text(std::string_view str, glm::vec2 pos, Color color) {
m_text.assign(str);
m_pos = pos;
m_color = color_value(color);
update_vertices();
}
Text::~Text() {
if (m_vbo != 0) {
glDeleteBuffers(1, &m_vbo);
}
}
Text& Text::color(Color color) {
m_color = color_value(color);
return *this;
}
Text& Text::position(float x, float y) {
m_pos = glm::vec2{x, y};
return *this;
}
Text& Text::scale(float s) {
m_scale = s;
return *this;
}
void Text::set_loc(const Shader& shader) {
m_color_loc = shader.loc("textColor");
m_mv_loc = shader.loc("mv_matrix");
}
Text& Text::text(std::string_view str) {
m_text.assign(str);
update_vertices();
return *this;
}
void Text::render() {
CUBED_ASSERT_MSG(!m_vertices.empty(), "Text String Not Set");
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D_ARRAY, Font::text_texture());
CUBED_ASSERT_MSG(m_color_loc, "m_color_loc is null");
m_model_matrix = glm::translate(glm::mat4(1.0f), glm::vec3(m_pos.x, m_pos.y, 0.0f)) *
glm::scale(glm::mat4(1.0f), glm::vec3(m_scale, m_scale, 1.0f));
glUniform3f(m_color_loc, m_color.x, m_color.y, m_color.z);
glUniformMatrix4fv(m_mv_loc, 1, GL_FALSE, glm::value_ptr(m_model_matrix));
glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex2D), (void*)0);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex2D), (void*)offsetof(Vertex2D, s));
glVertexAttribPointer(2, 1, GL_FLOAT, GL_FALSE, sizeof(Vertex2D), (void*)offsetof(Vertex2D, layer));
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
glEnableVertexAttribArray(2);
glDrawArrays(GL_TRIANGLES, 0, m_vertices.size());
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindTexture(GL_TEXTURE_2D_ARRAY, 0);
}
void Text::update_vertices() {
m_vertices = Font::vertices(m_text);
upload_to_gpu();
}
void Text::upload_to_gpu() {
if (m_vbo == 0) {
glGenBuffers(1, &m_vbo);
}
CUBED_ASSERT_MSG(m_vbo, "Vbo Is Not Gen");
glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
glBufferData(GL_ARRAY_BUFFER, m_vertices.size() * sizeof(Vertex2D), m_vertices.data(), GL_DYNAMIC_DRAW);
}