From fd7f62693ebeaf12ad2e3b521a50e6097d101435 Mon Sep 17 00:00:00 2001 From: omigamedev Date: Mon, 6 Feb 2017 21:08:41 +0000 Subject: [PATCH] refactor font code into classes --- engine/app.cpp | 72 +++------------------------------------- engine/app.h | 13 ++------ engine/font.cpp | 87 +++++++++++++++++++++++++++++++++++++++++++++++++ engine/font.h | 36 ++++++++++++++++++++ engine/shape.h | 1 - 5 files changed, 131 insertions(+), 78 deletions(-) diff --git a/engine/app.cpp b/engine/app.cpp index c20daf8..67b5113 100644 --- a/engine/app.cpp +++ b/engine/app.cpp @@ -107,35 +107,12 @@ void App::init() printf("error loading image\n"); #if _WIN32 - FILE* font_file = fopen("C:\\Windows\\Fonts\\arial.ttf", "rb"); + const char* ttf = "C:\\Windows\\Fonts\\arial.ttf"; #else - FILE* font_file = fopen("/Library/Fonts/Arial.ttf", "rb"); + const char* ttf = "/Library/Fonts/Arial.ttf"; #endif - if (font_file) - { - fseek(font_file, 0, SEEK_END); - long sz = ftell(font_file); - auto data = std::make_unique(sz); - fseek(font_file, 0, SEEK_SET); - auto bytes = fread(data.get(), 1, sz, font_file); - assert(bytes==sz); - auto bitmap = std::make_unique(w*h); - chars.resize(num_chars); - int ret = stbtt_BakeFontBitmap(data.get(), 0, 50, bitmap.get(), w, h, start_char, num_chars, chars.data()); - font_tex.create(w, h, GL_RED, bitmap.get()); - - glGenBuffers(2, font_buffers); - glGenVertexArrays(1, &font_array); - - glBindVertexArray(font_array); - glEnableVertexAttribArray(0); - glEnableVertexAttribArray(1); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, font_buffers[1]); - glBindBuffer(GL_ARRAY_BUFFER, font_buffers[0]); - glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(glm::vec4), (GLvoid*)0); - glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(glm::vec4), (GLvoid*)(sizeof(float)*2)); - glBindVertexArray(0); - } + FontManager::load(kFont::Arial_11, ttf); + text.create(); plane.create<1>(400, 400); glEnable(GL_TEXTURE_2D); @@ -172,7 +149,6 @@ void App::update(float dt) layout[main_id].update(width, height); } - /* glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); glEnable(GL_SCISSOR_TEST); for (auto& n : layout[main_id]) @@ -185,48 +161,10 @@ void App::update(float dt) } } glDisable(GL_SCISSOR_TEST); -*/ + glm::mat4 proj = glm::ortho(0.f, width, height, 0.f, -1.f, 1.f); glm::mat4 tran = glm::translate(glm::vec3(200, 200, 0)); - - if (chars.size()) - { - static char str[64]; - static int counter = 0; - counter++; - sprintf(str, "frame %04d", counter); - const auto len = strlen(str); - float x = 0; - float y = 0; - std::vector v; - std::vector idx; - for (int i = 0; i < len; i++) - { - int c = str[i] - start_char; - stbtt_aligned_quad q; - stbtt_GetBakedQuad(chars.data(), w, h, c, &x, &y, &q, true); - auto n = v.size(); - v.emplace_back(q.x0, q.y1, q.s0, q.t1); - v.emplace_back(q.x0, q.y0, q.s0, q.t0); - v.emplace_back(q.x1, q.y0, q.s1, q.t0); - v.emplace_back(q.x1, q.y1, q.s1, q.t1); - idx.push_back(n+0); - idx.push_back(n+1); - idx.push_back(n+2); - idx.push_back(n+0); - idx.push_back(n+2); - idx.push_back(n+3); - } - font_array_count = (int)idx.size(); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, font_buffers[1]); - glBufferData(GL_ELEMENT_ARRAY_BUFFER, idx.size() * sizeof(GLushort), idx.data(), GL_STATIC_DRAW); - glBindBuffer(GL_ARRAY_BUFFER, font_buffers[0]); - glBufferData(GL_ARRAY_BUFFER, v.size() * sizeof(glm::vec4), v.data(), GL_STATIC_DRAW); - glBindBuffer(GL_ARRAY_BUFFER, 0); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); - } - glActiveTexture(GL_TEXTURE0); font_tex.bind(); sampler.bind(0); diff --git a/engine/app.h b/engine/app.h index 3df4d0a..b039a7c 100644 --- a/engine/app.h +++ b/engine/app.h @@ -4,23 +4,16 @@ #include "shape.h" #include "texture.h" #include "layout.h" +#include "font.h" class App { Sampler sampler; Texture2D tex; LayoutManager layout; - stbtt_fontinfo font; - Texture2D font_tex; - std::vector chars; Plane plane; - GLuint font_array; - int font_array_count = 0; - GLuint font_buffers[2]; - const int w = 512; - const int h = 512; - const int num_chars = 96; - const int start_char = 32; + Font font; + TextMesh text; public: static App I; float width; diff --git a/engine/font.cpp b/engine/font.cpp index f0c44fd..7df9a81 100644 --- a/engine/font.cpp +++ b/engine/font.cpp @@ -1,5 +1,92 @@ #include "pch.h" #include "font.h" +std::map FontManager::m_fonts; +bool Font::load(const char* ttf) +{ + FILE* font_file = fopen(ttf, "rb"); + if (font_file) + { + fseek(font_file, 0, SEEK_END); + long sz = ftell(font_file); + auto data = std::make_unique(sz); + fseek(font_file, 0, SEEK_SET); + auto bytes = fread(data.get(), 1, sz, font_file); + assert(bytes==sz); + auto bitmap = std::make_unique(w*h); + chars.resize(num_chars); + int ret = stbtt_BakeFontBitmap(data.get(), 0, 50, bitmap.get(), w, h, start_char, num_chars, chars.data()); + font_tex.create(w, h, GL_RED, bitmap.get()); + fclose(font_file); + return true; + } + return false; +} +bool FontManager::load(kFont id, const char *ttf) +{ + return m_fonts[id].load(ttf); +} + +const Font& FontManager::get(kFont id) +{ + return m_fonts[id]; +} + +bool TextMesh::create() +{ + glGenBuffers(2, font_buffers); + glGenVertexArrays(1, &font_array); + + glBindVertexArray(font_array); + glEnableVertexAttribArray(0); + glEnableVertexAttribArray(1); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, font_buffers[1]); + glBindBuffer(GL_ARRAY_BUFFER, font_buffers[0]); + glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(glm::vec4), (GLvoid*)0); + glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(glm::vec4), (GLvoid*)(sizeof(float)*2)); + glBindVertexArray(0); + return true; +} + +void TextMesh::update(kFont id, const char* text) +{ + auto& f = FontManager::get(id); + if (f.chars.size()) + { + static char str[64]; + static int counter = 0; + counter++; + sprintf(str, "frame %04d", counter); + const auto len = strlen(str); + float x = 0; + float y = 0; + std::vector v; + std::vector idx; + for (int i = 0; i < len; i++) + { + int c = str[i] - f.start_char; + stbtt_aligned_quad q; + stbtt_GetBakedQuad((stbtt_bakedchar*)f.chars.data(), f.w, f.h, c, &x, &y, &q, true); + auto n = v.size(); + v.emplace_back(q.x0, q.y1, q.s0, q.t1); + v.emplace_back(q.x0, q.y0, q.s0, q.t0); + v.emplace_back(q.x1, q.y0, q.s1, q.t0); + v.emplace_back(q.x1, q.y1, q.s1, q.t1); + idx.push_back(n+0); + idx.push_back(n+1); + idx.push_back(n+2); + idx.push_back(n+0); + idx.push_back(n+2); + idx.push_back(n+3); + } + font_array_count = (int)idx.size(); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, font_buffers[1]); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, idx.size() * sizeof(GLushort), idx.data(), GL_STATIC_DRAW); + glBindBuffer(GL_ARRAY_BUFFER, font_buffers[0]); + glBufferData(GL_ARRAY_BUFFER, v.size() * sizeof(glm::vec4), v.data(), GL_STATIC_DRAW); + glBindBuffer(GL_ARRAY_BUFFER, 0); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + } +} diff --git a/engine/font.h b/engine/font.h index 531a62b..269340c 100644 --- a/engine/font.h +++ b/engine/font.h @@ -1,4 +1,40 @@ #pragma once +#include "texture.h" +#include "util.h" +enum class kFont : uint16_t +{ + Arial_11 = const_hash("arial-16"), +}; +class Font +{ +public: + const int w = 512; + const int h = 512; + const int num_chars = 96; + const int start_char = 32; + stbtt_fontinfo font; + Texture2D font_tex; + std::vector chars; + + bool load(const char* ttf); +}; +class FontManager +{ + static std::map m_fonts; +public: + static bool load(kFont id, const char* ttf); + static const Font& get(kFont id); +}; + +class TextMesh +{ +public: + GLuint font_array = 0; + int font_array_count = 0; + GLuint font_buffers[2] = {0, 0}; + bool create(); + void update(kFont id, const char* text); +}; diff --git a/engine/shape.h b/engine/shape.h index 8a04faa..617e120 100644 --- a/engine/shape.h +++ b/engine/shape.h @@ -9,7 +9,6 @@ protected: GLvoid* ioff[2]{ 0 }; struct vertex_t { glm::vec4 pos; glm::vec2 uvs; }; public: -// att::AttrubutesMap attribs; bool create_buffers(GLvoid* idx, GLvoid* vertices, int isize, int vsize); void draw_fill() const; void draw_stroke() const;