refactor(render): use Texture, VertexBuffer, VertexArray classes

This commit is contained in:
2026-07-09 20:38:55 +08:00
parent 4e12c69f1b
commit c7383a4208
6 changed files with 50 additions and 86 deletions

View File

@@ -130,12 +130,11 @@ private:
glm::mat4 m_p_mat, m_v_mat, m_m_mat, m_mv_mat, m_mvp_mat, m_norm_mat; glm::mat4 m_p_mat, m_v_mat, m_m_mat, m_mv_mat, m_mvp_mat, m_norm_mat;
std::unique_ptr<VertexBuffer> m_sky_vbo; std::unique_ptr<VertexBuffer> m_sky_vbo;
std::unique_ptr<VertexBuffer> m_text_vbo = 0; std::unique_ptr<VertexBuffer> m_outline_indices_vbo;
std::unique_ptr<VertexBuffer> m_outline_indices_vbo = 0; std::unique_ptr<VertexBuffer> m_outline_vbo;
std::unique_ptr<VertexBuffer> m_outline_vbo = 0; std::unique_ptr<VertexBuffer> m_ui_vbo;
std::unique_ptr<VertexBuffer> m_ui_vbo = 0; std::unique_ptr<VertexBuffer> m_player_vbo;
std::unique_ptr<VertexBuffer> m_player_vbo = 0; std::unique_ptr<VertexBuffer> m_quad_vbo;
std::unique_ptr<VertexBuffer> m_quad_vbo = 0;
GLuint m_fbo = 0; GLuint m_fbo = 0;
std::unique_ptr<Texture> m_screen_texture; std::unique_ptr<Texture> m_screen_texture;

View File

@@ -1,5 +1,8 @@
#pragma once #pragma once
#include "Cubed/render/texture.hpp"
#include <ft2build.h> #include <ft2build.h>
#include <memory>
#include FT_FREETYPE_H #include FT_FREETYPE_H
#include "Cubed/primitive_data.hpp" #include "Cubed/primitive_data.hpp"
@@ -29,7 +32,7 @@ public:
static std::vector<Vertex2D> vertices(const std::string& text, static std::vector<Vertex2D> vertices(const std::string& text,
float x = 0.0f, float y = 0.0f, float x = 0.0f, float y = 0.0f,
float scale = 1.0f); float scale = 1.0f);
static GLuint text_texture(); static const Texture* text_texture();
static const std::string& font_path(); static const std::string& font_path();
private: private:
@@ -39,7 +42,7 @@ private:
float m_texture_width = 64; float m_texture_width = 64;
float m_texture_height = 64; float m_texture_height = 64;
static inline GLuint m_text_texture; static inline std::unique_ptr<Texture> m_text_texture;
static inline std::string m_font_path{ASSETS_PATH static inline std::string m_font_path{ASSETS_PATH
"fonts/IBMPlexSans-Regular.ttf"}; "fonts/IBMPlexSans-Regular.ttf"};
std::unordered_map<char8_t, Character> m_characters; std::unordered_map<char8_t, Character> m_characters;

View File

@@ -1,6 +1,8 @@
#pragma once #pragma once
#include "Cubed/primitive_data.hpp" #include "Cubed/primitive_data.hpp"
#include "Cubed/render/vertex_array.hpp"
#include "Cubed/render/vertex_buffer.hpp"
#include "Cubed/ui/color.hpp" #include "Cubed/ui/color.hpp"
#include <glad/glad.h> #include <glad/glad.h>
@@ -27,8 +29,7 @@ public:
Text& text(std::string_view str); Text& text(std::string_view str);
std::size_t uuid() const; std::size_t uuid() const;
static void set_loc(const Shader& shader); void render(const Shader& shader);
void render();
bool operator==(const Text& other) const; bool operator==(const Text& other) const;
@@ -38,14 +39,14 @@ private:
const std::string NAME; const std::string NAME;
const std::size_t UUID; const std::size_t UUID;
std::string m_text; std::string m_text;
glm::vec4 m_color{1.0f, 1.0f, 1.0f, 1.0f}; glm::vec4 m_color{1.0f, 1.0f, 1.0f, 1.0f};
glm::mat4 m_model_matrix; glm::mat4 m_model_matrix;
std::vector<Vertex2D> m_vertices; std::vector<Vertex2D> m_vertices;
GLuint m_vbo = 0; std::unique_ptr<VertexBuffer> m_vbo;
static inline GLuint m_color_loc = 0; std::unique_ptr<VertexArray> m_vao;
static inline GLuint m_mv_loc = 0;
void update_vertices(); void update_vertices();
void upload_to_gpu(); void upload_to_gpu();

View File

@@ -34,7 +34,6 @@ Renderer::~Renderer() {
m_outline_indices_vbo.reset(); m_outline_indices_vbo.reset();
m_sky_vbo.reset(); m_sky_vbo.reset();
m_ui_vbo.reset(); m_ui_vbo.reset();
m_text_vbo.reset();
m_player_vbo.reset(); m_player_vbo.reset();
glBindVertexArray(0); glBindVertexArray(0);
m_vao.clear(); m_vao.clear();
@@ -141,7 +140,6 @@ void Renderer::init(bool debug_on) {
m_player_vbo = std::make_unique<VertexBuffer>(); m_player_vbo = std::make_unique<VertexBuffer>();
m_quad_vbo = std::make_unique<VertexBuffer>(); m_quad_vbo = std::make_unique<VertexBuffer>();
m_sky_vbo = std::make_unique<VertexBuffer>(); m_sky_vbo = std::make_unique<VertexBuffer>();
m_text_vbo = std::make_unique<VertexBuffer>();
m_ui_vbo = std::make_unique<VertexBuffer>(); m_ui_vbo = std::make_unique<VertexBuffer>();
m_vao[2].bind(); m_vao[2].bind();
@@ -200,12 +198,6 @@ void Renderer::init_quad() {
void Renderer::init_text() { void Renderer::init_text() {
m_vao[4].bind(); m_vao[4].bind();
m_text_vbo->buffer_data(NULL, sizeof(float) * 6 * 4,
BufferUsage::DYNAMIC_DRAW);
const auto& shader = get_shader("text");
Text::set_loc(shader);
DebugCollector::get().init_text(); DebugCollector::get().init_text();
} }
@@ -395,8 +387,6 @@ void Renderer::render_sky() {
void Renderer::render_text() { void Renderer::render_text() {
m_vao[4].bind();
const auto& shader = get_shader("text"); const auto& shader = get_shader("text");
shader.use(); shader.use();
@@ -410,7 +400,7 @@ void Renderer::render_text() {
auto& texts = DebugCollector::get().all_texts(); auto& texts = DebugCollector::get().all_texts();
for (auto& t : texts) { for (auto& t : texts) {
t.second.render(); t.second.render(shader);
} }
glEnable(GL_DEPTH_TEST); glEnable(GL_DEPTH_TEST);

View File

@@ -1,9 +1,7 @@
#include "Cubed/tools/font.hpp" #include "Cubed/tools/font.hpp"
#include "Cubed/constants.hpp" #include "Cubed/constants.hpp"
#include "Cubed/shader.hpp"
#include "Cubed/tools/log.hpp" #include "Cubed/tools/log.hpp"
#include "Cubed/tools/shader_tools.hpp"
namespace fs = std::filesystem; namespace fs = std::filesystem;
@@ -26,7 +24,6 @@ Font::~Font() {
FT_Done_Face(m_face); FT_Done_Face(m_face);
FT_Done_FreeType(m_ft); FT_Done_FreeType(m_ft);
glDeleteTextures(1, &m_text_texture);
} }
void Font::load_character(char8_t c) { void Font::load_character(char8_t c) {
@@ -36,10 +33,9 @@ void Font::load_character(char8_t c) {
} }
const auto& width = m_face->glyph->bitmap.width; const auto& width = m_face->glyph->bitmap.width;
const auto& height = m_face->glyph->bitmap.rows; const auto& height = m_face->glyph->bitmap.rows;
glBindTexture(GL_TEXTURE_2D_ARRAY, m_text_texture); m_text_texture->tex_sub_image_3d(TextureFormat::RED, GL_UNSIGNED_BYTE,
glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, static_cast<int>(c), width, m_face->glyph->bitmap.buffer, 0, 0,
height, 1, GL_RED, GL_UNSIGNED_BYTE, static_cast<int>(c), width, height);
m_face->glyph->bitmap.buffer);
Character character = { Character character = {
glm::vec2{0.0f, 0.0f}, glm::vec2{0.0f, 0.0f},
@@ -54,22 +50,16 @@ void Font::load_character(char8_t c) {
void Font::setup_font_character() { void Font::setup_font_character() {
glPixelStorei(GL_UNPACK_ALIGNMENT, 1); glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
m_text_texture = std::make_unique<Texture>(TextureType::TEXTURE_2D_ARRAY);
glGenTextures(1, &m_text_texture); m_text_texture->tex_image_3d(TextureFormat::RED, TextureFormat::RED,
glBindTexture(GL_TEXTURE_2D_ARRAY, m_text_texture); GL_UNSIGNED_BYTE, nullptr, m_texture_width,
glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RED, m_texture_width, m_texture_height, MAX_CHARACTER);
m_texture_height, MAX_CHARACTER, 0, GL_RED, GL_UNSIGNED_BYTE,
nullptr);
for (char8_t c = 0; c < 128; c++) { for (char8_t c = 0; c < 128; c++) {
load_character(c); load_character(c);
} }
m_text_texture->set_linear();
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); m_text_texture->set_clamp_to_edge(false, true, true);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glBindTexture(GL_TEXTURE_2D_ARRAY, 0);
} }
std::vector<Vertex2D> Font::vertices(const std::string& text, float x, float y, std::vector<Vertex2D> Font::vertices(const std::string& text, float x, float y,
@@ -110,7 +100,7 @@ std::vector<Vertex2D> Font::vertices(const std::string& text, float x, float y,
return vertices; return vertices;
} }
GLuint Font::text_texture() { return m_text_texture; } const Texture* Font::text_texture() { return m_text_texture.get(); }
const std::string& Font::font_path() { return m_font_path; } const std::string& Font::font_path() { return m_font_path; }

View File

@@ -9,30 +9,30 @@
namespace Cubed { namespace Cubed {
Text::Text(std::string_view name) : NAME(name), UUID(HASH::str(name)) {} Text::Text(std::string_view name)
: NAME(name), UUID(HASH::str(name)),
m_vbo(std::make_unique<VertexBuffer>()),
m_vao(std::make_unique<VertexArray>()) {}
Text::Text(std::string_view name, std::string_view str, glm::vec2 pos, Text::Text(std::string_view name, std::string_view str, glm::vec2 pos,
Color color) Color color)
: NAME(name), UUID(HASH::str(name)) { : NAME(name), UUID(HASH::str(name)),
m_vbo(std::make_unique<VertexBuffer>()),
m_vao(std::make_unique<VertexArray>()) {
m_text.assign(str); m_text.assign(str);
m_pos = pos; m_pos = pos;
m_color = color_value(color); m_color = color_value(color);
update_vertices(); update_vertices();
} }
Text::~Text() { Text::~Text() { m_vbo.reset(); }
if (m_vbo != 0) {
glDeleteBuffers(1, &m_vbo);
}
}
Text::Text(Text&& other) noexcept Text::Text(Text&& other) noexcept
: m_scale(other.m_scale), m_pos(other.m_pos), NAME(other.NAME), : m_scale(other.m_scale), m_pos(other.m_pos), NAME(other.NAME),
UUID(other.UUID), m_text(std::move(other.m_text)), m_color(other.m_color), UUID(other.UUID), m_text(std::move(other.m_text)), m_color(other.m_color),
m_model_matrix(other.m_model_matrix), m_model_matrix(other.m_model_matrix),
m_vertices(std::move(other.m_vertices)), m_vbo(other.m_vbo) { m_vertices(std::move(other.m_vertices)), m_vbo(std::move(other.m_vbo)),
other.m_vbo = 0; m_vao(std::move(other.m_vao)) {}
}
Text& Text::color(Color color) { Text& Text::color(Color color) {
m_color = color_value(color); m_color = color_value(color);
@@ -51,45 +51,24 @@ Text& Text::scale(float s) {
std::size_t Text::uuid() const { return UUID; } std::size_t Text::uuid() const { return UUID; }
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) { Text& Text::text(std::string_view str) {
m_text.assign(str); m_text.assign(str);
update_vertices(); update_vertices();
return *this; return *this;
} }
void Text::render() { void Text::render(const Shader& shader) {
ASSERT_MSG(m_vbo != 0, "VBO not initialized!"); ASSERT_MSG(m_vbo != 0, "VBO not initialized!");
ASSERT_MSG(!m_vertices.empty(), "Text String Not Set"); ASSERT_MSG(!m_vertices.empty(), "Text String Not Set");
glActiveTexture(GL_TEXTURE0); Font::text_texture()->bind(0);
glBindTexture(GL_TEXTURE_2D_ARRAY, Font::text_texture()); m_vao->bind();
ASSERT_MSG(m_color_loc, "m_color_loc is null");
m_model_matrix = m_model_matrix =
glm::translate(glm::mat4(1.0f), glm::vec3(m_pos.x, m_pos.y, 0.0f)) * 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)); 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); shader.set_loc("textColor", glm::vec3(m_color.x, m_color.y, m_color.z));
glUniformMatrix4fv(m_mv_loc, 1, GL_FALSE, glm::value_ptr(m_model_matrix)); shader.set_loc("mv_matrix", 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()); glDrawArrays(GL_TRIANGLES, 0, m_vertices.size());
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindTexture(GL_TEXTURE_2D_ARRAY, 0);
} }
void Text::update_vertices() { void Text::update_vertices() {
@@ -98,13 +77,15 @@ void Text::update_vertices() {
} }
void Text::upload_to_gpu() { void Text::upload_to_gpu() {
if (m_vbo == 0) {
glGenBuffers(1, &m_vbo);
}
ASSERT_MSG(m_vbo, "Vbo Is Not Gen"); ASSERT_MSG(m_vbo, "Vbo Is Not Gen");
glBindBuffer(GL_ARRAY_BUFFER, m_vbo); m_vao->bind();
glBufferData(GL_ARRAY_BUFFER, m_vertices.size() * sizeof(Vertex2D), m_vbo->buffer_data(m_vertices.data(), m_vertices.size() * sizeof(Vertex2D),
m_vertices.data(), GL_DYNAMIC_DRAW); BufferUsage::DYNAMIC_DRAW);
m_vao->attribute(0, 2, GL_FLOAT, sizeof(Vertex2D), (void*)0);
m_vao->attribute(1, 2, GL_FLOAT, sizeof(Vertex2D),
(void*)offsetof(Vertex2D, s));
m_vao->attribute(2, 1, GL_FLOAT, sizeof(Vertex2D),
(void*)offsetof(Vertex2D, layer));
} }
bool Text::operator==(const Text& other) const { return UUID == other.uuid(); } bool Text::operator==(const Text& other) const { return UUID == other.uuid(); }