diff --git a/src/gui/Font.cc b/src/gui/Font.cc index 5b4b207..b3a1e16 100644 --- a/src/gui/Font.cc +++ b/src/gui/Font.cc @@ -58,14 +58,6 @@ namespace jes m_loaded = false; } - Font::Glyph::~Glyph() - { - if (m_loaded) - { - glDeleteTextures(1, &m_texture_id); - } - } - bool Font::Glyph::load(FT_Face face, FT_ULong char_code) { if (FT_Load_Char(face, char_code, FT_LOAD_RENDER) != 0) @@ -84,24 +76,30 @@ namespace jes width); } - glGenTextures(1, &m_texture_id); glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, m_texture_id); + m_texture = new GLTexture(); + m_texture->create(width, height); 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, width, height, 0, GL_ALPHA, GL_UNSIGNED_BYTE, texture); + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_ALPHA, GL_UNSIGNED_BYTE, texture); delete[] texture; - float s = 1.0 / (width * 2); - float t = 1.0 / (height * 2); + float s_min = 0.5 / m_texture->get_width(); + float s_max = (width - 0.5) / m_texture->get_width(); + float t_min = 0.5 / m_texture->get_height(); + float t_max = (height - 0.5) / m_texture->get_height(); GLfloat box[4][4] = { - {(GLfloat)left, (GLfloat)(top - height), s, t}, - {(GLfloat)(left + width - 1), (GLfloat)(top - height), 1 - s, t}, - {(GLfloat)left, (GLfloat)(top - 1), s, 1 - t}, - {(GLfloat)(left + width - 1), (GLfloat)(top - 1), 1 - s, 1 - t}, + {(GLfloat)left, (GLfloat)(top - height), + s_min, t_min}, + {(GLfloat)(left + width - 1), (GLfloat)(top - height), + s_max, t_min}, + {(GLfloat)left, (GLfloat)(top - 1), + s_min, t_max}, + {(GLfloat)(left + width - 1), (GLfloat)(top - 1), + s_max, t_max}, }; glGenBuffers(1, &m_vbo_id); glBindBuffer(GL_ARRAY_BUFFER, m_vbo_id); diff --git a/src/gui/Font.h b/src/gui/Font.h index 2483aeb..9348461 100644 --- a/src/gui/Font.h +++ b/src/gui/Font.h @@ -6,6 +6,7 @@ #include FT_FREETYPE_H #include "gl3w.h" #include +#include "GLTexture.h" namespace jes { @@ -16,12 +17,11 @@ namespace jes { public: Glyph(); - ~Glyph(); bool load(FT_Face face, FT_ULong char_code); int get_advance() { return m_advance; } void render() { - glBindTexture(GL_TEXTURE_2D, m_texture_id); + m_texture->bind(); glEnableVertexAttribArray(0); glBindBuffer(GL_ARRAY_BUFFER, m_vbo_id); glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0); @@ -30,7 +30,7 @@ namespace jes protected: bool m_loaded; int m_advance; - GLuint m_texture_id; + GLTextureRef m_texture; GLuint m_vbo_id; }; typedef Ref GlyphRef; diff --git a/src/gui/GLTexture.cc b/src/gui/GLTexture.cc new file mode 100644 index 0000000..0af5466 --- /dev/null +++ b/src/gui/GLTexture.cc @@ -0,0 +1,43 @@ +#include "GLTexture.h" +#include + +using namespace std; + +namespace jes +{ + GLTexture::GLTexture() + { + glGenTextures(1, &m_id); + m_width = 0u; + m_height = 0u; + } + + GLTexture::~GLTexture() + { + glDeleteTextures(1, &m_id); + } + + uint32_t GLTexture::next_power_of_2(uint32_t n) + { + n--; + n |= n >> 1u; + n |= n >> 2u; + n |= n >> 4u; + n |= n >> 8u; + n |= n >> 16u; + n++; + return n; + } + + void GLTexture::create(unsigned int width, unsigned int height) + { + m_width = width = next_power_of_2(width); + m_height = height = next_power_of_2(height); + uint8_t * d = new uint8_t[width * height]; + memset(d, 0, width * height); + bind(); + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, width, height, 0, GL_ALPHA, GL_UNSIGNED_BYTE, d); + delete[] d; + } +} diff --git a/src/gui/GLTexture.h b/src/gui/GLTexture.h new file mode 100644 index 0000000..34c8fd2 --- /dev/null +++ b/src/gui/GLTexture.h @@ -0,0 +1,29 @@ +#ifndef GLTEXTURE_H +#define GLTEXTURE_H + +#include "jes/Ref.h" +#include "gl3w.h" +#include + +namespace jes +{ + class GLTexture + { + public: + GLTexture(); + ~GLTexture(); + GLuint get_id() { return m_id; } + void bind() { glBindTexture(GL_TEXTURE_2D, m_id); } + static uint32_t next_power_of_2(uint32_t n); + void create(unsigned int width, unsigned int height); + unsigned int get_width() { return m_width; } + unsigned int get_height() { return m_height; } + protected: + GLuint m_id; + unsigned int m_width; + unsigned int m_height; + }; + typedef Ref GLTextureRef; +} + +#endif