137 lines
4.2 KiB
C++
137 lines
4.2 KiB
C++
#include "pch.h"
|
|
#include "log.h"
|
|
#include "font.h"
|
|
#include "shader.h"
|
|
#include "asset.h"
|
|
|
|
std::map<kFont, Font> FontManager::m_fonts;
|
|
Sampler FontManager::m_sampler;
|
|
|
|
bool Font::load(const char* ttf, int font_size)
|
|
{
|
|
Asset file;
|
|
LOG("Font::load %s", ttf);
|
|
if (file.open(ttf) && file.read_all())
|
|
{
|
|
LOG("Font::load loaded");
|
|
auto bitmap = std::make_unique<uint8_t[]>(w*h);
|
|
chars.resize(num_chars);
|
|
stbtt_BakeFontBitmap(file.m_data, 0, (float)font_size, bitmap.get(), w, h, start_char, num_chars, chars.data());
|
|
font_tex.create(w, h, GL_R8, GL_RED, bitmap.get());
|
|
file.close();
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
void FontManager::init()
|
|
{
|
|
m_sampler.create();
|
|
}
|
|
|
|
bool FontManager::load(kFont id, const char* ttf, int sz)
|
|
{
|
|
return m_fonts[id].load(ttf, sz);
|
|
}
|
|
|
|
const Font& FontManager::get(kFont id)
|
|
{
|
|
return m_fonts[id];
|
|
}
|
|
|
|
bool TextMesh::create()
|
|
{
|
|
glGenBuffers(2, font_buffers);
|
|
#if USE_VBO
|
|
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);
|
|
#endif // USE_VBO
|
|
return true;
|
|
}
|
|
|
|
void TextMesh::update(kFont id, const char* text)
|
|
{
|
|
font_id = id;
|
|
auto& f = FontManager::get(id);
|
|
if (f.chars.size())
|
|
{
|
|
const auto len = strlen(text);
|
|
float x = 0;
|
|
float y = 0;
|
|
std::vector<glm::vec4> v;
|
|
std::vector<GLushort> idx;
|
|
glm::vec2 bbmin;
|
|
glm::vec2 bbmax;
|
|
for (int i = 0; i < len; i++)
|
|
{
|
|
int c = text[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 = (int)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);
|
|
bbmin = glm::min(bbmin, { q.x0, q.y0 });
|
|
bbmax = glm::max(bbmax, { q.x1, q.y1 });
|
|
}
|
|
for (int i = 0; i < len*4; i++)
|
|
{
|
|
v[i] -= glm::vec4(bbmin, 0, 0);
|
|
}
|
|
bb = bbmax - bbmin;
|
|
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);
|
|
}
|
|
}
|
|
|
|
void TextMesh::draw()
|
|
{
|
|
auto& f = FontManager::get(font_id);
|
|
if (f.font_tex.ready())
|
|
{
|
|
glActiveTexture(GL_TEXTURE0);
|
|
f.font_tex.bind();
|
|
FontManager::m_sampler.bind(0);
|
|
|
|
#if USE_VBO
|
|
glBindVertexArray(font_array);
|
|
glDrawElements(GL_TRIANGLES, font_array_count, GL_UNSIGNED_SHORT, 0);
|
|
glBindVertexArray(0);
|
|
#else
|
|
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));
|
|
glDrawElements(GL_TRIANGLES, font_array_count, GL_UNSIGNED_SHORT, 0);
|
|
glDisableVertexAttribArray(0);
|
|
glDisableVertexAttribArray(1);
|
|
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
|
#endif // USE_VBO
|
|
|
|
f.font_tex.unbind();
|
|
FontManager::m_sampler.unbind();
|
|
}
|
|
}
|