79 if (text::vao.get_vao() == 0)
81 ERROR(
"{}: not initialized", text::subsystem_name);
85 if (FT_Init_FreeType(&ft))
87 ERROR(
"{}: could not init FreeType library", text::subsystem_name);
92 GL_VERTEX_SHADER,
"src/shaders/text.vs",
93 GL_FRAGMENT_SHADER,
"src/shaders/text.fs");
94 text::shader =
"TextShader";
98 std::string font_name = font_path;
99 if (font_name.empty())
101 ERROR(
"{}: could not find font", text::subsystem_name);
106 if (FT_New_Face(ft, font_name.c_str(), 0, &face))
108 ERROR(
"{}: could not load font", text::subsystem_name);
114 FT_Set_Pixel_Sizes(face, 0, font_size);
117 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
120 for (
unsigned char c = 0; c < 128; c++)
123 if (FT_Load_Char(face, c, FT_LOAD_RENDER))
125 ERROR(
"{}: could not load glyph", text::subsystem_name);
132 glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, face->glyph->bitmap.width,
133 face->glyph->bitmap.rows, 0, GL_RED, GL_UNSIGNED_BYTE,
134 face->glyph->bitmap.buffer);
136 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
137 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
138 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
139 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
143 glm::ivec2(face->glyph->bitmap.width, face->glyph->bitmap.rows),
144 glm::ivec2(face->glyph->bitmap_left, face->glyph->bitmap_top),
145 static_cast<unsigned int>(face->glyph->advance.x)};
146 characters.insert(std::pair<char, types::character>(c, character_));
152 FT_Done_FreeType(ft);
157 glBufferData(GL_ARRAY_BUFFER,
sizeof(
float) * 6 * 4, NULL, GL_DYNAMIC_DRAW);
158 glEnableVertexAttribArray(0);
159 glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 4 *
sizeof(
float), 0);
167 if (text::vao.get_vao() == 0)
169 ERROR(
"{}: not initialized", text::subsystem_name);
176 glUniform3f(glGetUniformLocation(textShaderId,
"textColor"), color.x, color.y,
179 glm::mat4 projection =
180 glm::ortho(0.0f,
static_cast<float>(window::get_width()), 0.0f,
181 static_cast<float>(window::get_height()));
182 glUniformMatrix4fv(glGetUniformLocation(textShaderId,
"projection"), 1,
183 GL_FALSE, glm::value_ptr(projection));
185 glActiveTexture(GL_TEXTURE0);
189 std::string::const_iterator c;
190 for (c =
text.begin(); c !=
text.end(); c++)
194 float xpos = x + ch.bearing.x * scale;
195 float ypos = y - (ch.size.y - ch.bearing.y) * scale;
197 float w = ch.size.x * scale;
198 float h = ch.size.y * scale;
202 float vertices[6][4] = {
203 {xpos, ypos + h, 0.0, 0.0}, {xpos, ypos, 0.0, 1.0},
204 {xpos + w, ypos, 1.0, 1.0},
206 {xpos, ypos + h, 0.0, 0.0}, {xpos + w, ypos, 1.0, 1.0},
207 {xpos + w, ypos + h, 1.0, 0.0}};
210 glBindTexture(GL_TEXTURE_2D, ch.texture_id);
213 glBindBuffer(GL_ARRAY_BUFFER, text::vbo.
id);
214 glBufferSubData(GL_ARRAY_BUFFER, 0,
sizeof(vertices), vertices);
216 glBindBuffer(GL_ARRAY_BUFFER, 0);
218 glDrawArrays(GL_TRIANGLES, 0, 6);
221 x += (ch.advance >> 6)
224 glBindVertexArray(0);
225 glBindTexture(GL_TEXTURE_2D, 0);
std::expected< void, subsystem::error > terminate() override
Cleaup resources.
bool is_initialized() override
Returns true if the subsystem is initialized.
static void render_text(std::string text, float x, float y, float scale, glm::vec3 color)
Render text.
std::string name() override
Returns the name of the sybsystem.
static void load(std::string font_name, int font_size=48)
Load a font.
static std::map< char, types::character > characters
Map of characters.
std::expected< void, subsystem::error > initialize() override
Initialize the text subsystem.
static void bind_texture(GLenum target, unsigned int texture, GLint wrapping=GL_REPEAT, GLint filtering_min=GL_NEAREST, GLint filtering_mag=GL_NEAREST, GLboolean hasMipmap=GL_TRUE, GLint mipmap_min=GL_LINEAR_MIPMAP_LINEAR, GLint mipmap_mag=GL_LINEAR)
Bind a texture.