diff --git a/src/gui/Glyph.cc b/src/gui/Glyph.cc new file mode 100644 index 0000000..8f0a40d --- /dev/null +++ b/src/gui/Glyph.cc @@ -0,0 +1,52 @@ +#include "Glyph.h" + +#define round_up_26_6(val) (((val) + 63) >> 6u) + +bool Glyph::load(FT_Face face, FT_ULong char_code) +{ + if (FT_Load_Char(face, char_code, FT_LOAD_RENDER) != 0) + return false; + + m_texture = glcxx::Texture::create(); + m_texture->bind(GL_TEXTURE_2D); + int width = face->glyph->bitmap.width; + int rounded_width = glcxx::Texture::next_power_of_2(width); + int height = face->glyph->bitmap.rows; + int rounded_height = glcxx::Texture::next_power_of_2(height); + m_advance = round_up_26_6(face->glyph->advance.x); + uint8_t * texture = new uint8_t[rounded_width * rounded_height]; + memset(texture, 0, rounded_width * rounded_height); + for (int i = 0; i < height; i++) + { + memcpy(&texture[rounded_width * i], + &face->glyph->bitmap.buffer[width * (height - i - 1)], + width); + } + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, rounded_width, rounded_height, 0, GL_ALPHA, GL_UNSIGNED_BYTE, texture); + delete[] texture; + + m_array = glcxx::Array::create(); + m_array->bind(); + + int left = face->glyph->bitmap_left; + int top = face->glyph->bitmap_top; + float s_max = width / (float)rounded_width; + float t_max = height / (float)rounded_height; + m_buffer = glcxx::Buffer::create(GL_ARRAY_BUFFER, GL_STATIC_DRAW, { + (GLfloat)left, (GLfloat)(top - height), 0.0, 0.0, + (GLfloat)(left + width), (GLfloat)(top - height), s_max, 0.0, + (GLfloat)left, (GLfloat)top, 0.0, t_max, + (GLfloat)(left + width), (GLfloat)top, s_max, t_max, + }); + + glEnableVertexAttribArray(0); + glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0); + + return true; +} diff --git a/src/gui/Glyph.h b/src/gui/Glyph.h new file mode 100644 index 0000000..d86584b --- /dev/null +++ b/src/gui/Glyph.h @@ -0,0 +1,26 @@ +#ifndef GLYPH_H +#define GLYPH_H + +#include +#include FT_FREETYPE_H +#include "glcxx.hpp" + +class Glyph +{ +public: + bool load(FT_Face face, FT_ULong char_code); + int get_advance() { return m_advance; } + void render() + { + m_array->bind(); + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + } + +protected: + int m_advance; + std::shared_ptr m_texture; + std::shared_ptr m_buffer; + std::shared_ptr m_array; +}; + +#endif