#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); } }