Brenta Engine 1.0
Loading...
Searching...
No Matches
text.cpp
1/*
2 * MIT License
3 *
4 * Copyright (c) 2024 Giovanni Santini
5
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 all
15 * copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 * SOFTWARE.
24 *
25 */
26
27#include "text.hpp"
28
29#include "engine_logger.hpp"
30
31#include <filesystem>
32
33using namespace Brenta;
34using namespace Brenta::Types;
35
36Types::ShaderName Text::textShader;
37Types::VAO Text::textVao;
38Types::Buffer Text::textVbo;
39std::map<char, Types::Character> Text::characters;
40
42{
43 Text::textVbo = Types::Buffer(GL_ARRAY_BUFFER);
44 Text::textVao.Init();
45 ;
46
47 INFO("Text initialized");
48}
49
50void Text::Load(std::string font, unsigned int fontSize)
51{
52 if (textVao.GetVAO() == 0)
53 {
54 ERROR("Text not initialized");
55 return;
56 }
57 FT_Library ft;
58 if (FT_Init_FreeType(&ft))
59 {
60 ERROR("Could not init FreeType library");
61 return;
62 }
63
64 Shader::New("TextShader", GL_VERTEX_SHADER,
65 std::filesystem::absolute("engine/shaders/text.vs"),
66 GL_FRAGMENT_SHADER,
67 std::filesystem::absolute("engine/shaders/text.fs"));
68 textShader = "TextShader";
69 Shader::Use(textShader);
70
71 // find path to font
72 std::string font_name = std::filesystem::absolute("assets/fonts/" + font);
73 if (font_name.empty())
74 {
75 ERROR("Could not find font");
76 return;
77 }
78
79 FT_Face face;
80 if (FT_New_Face(ft, font_name.c_str(), 0, &face))
81 {
82 ERROR("Could not load font");
83 return;
84 }
85 else
86 {
87 // set size to load glyphs as
88 FT_Set_Pixel_Sizes(face, 0, 48);
89
90 // disable byte-alignment restriction
91 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
92
93 // load first 128 characters of ASCII set
94 for (unsigned char c = 0; c < 128; c++)
95 {
96 // Load character glyph
97 if (FT_Load_Char(face, c, FT_LOAD_RENDER))
98 {
99 ERROR("Could not load glyph");
100 continue;
101 }
102 // generate texture
103 unsigned int texture;
104 glGenTextures(1, &texture);
105 Texture::BindTexture(GL_TEXTURE_2D, texture);
106 glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, face->glyph->bitmap.width,
107 face->glyph->bitmap.rows, 0, GL_RED, GL_UNSIGNED_BYTE,
108 face->glyph->bitmap.buffer);
109 // set texture options
110 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
111 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
112 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
113 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
114 // now store character for later use
115 Character character = {
116 texture,
117 glm::ivec2(face->glyph->bitmap.width, face->glyph->bitmap.rows),
118 glm::ivec2(face->glyph->bitmap_left, face->glyph->bitmap_top),
119 static_cast<unsigned int>(face->glyph->advance.x)};
120 characters.insert(std::pair<char, Character>(c, character));
121 }
122 Texture::BindTexture(GL_TEXTURE_2D, 0);
123 }
124 // destroy FreeType once we're finished
125 FT_Done_Face(face);
126 FT_Done_FreeType(ft);
127
128 // configure VAO/VBO for texture quads
129 textVao.Bind();
130 textVbo.Bind();
131 glBufferData(GL_ARRAY_BUFFER, sizeof(float) * 6 * 4, NULL, GL_DYNAMIC_DRAW);
132 glEnableVertexAttribArray(0);
133 glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 4 * sizeof(float), 0);
134 textVbo.Unbind();
135 textVao.Unbind();
136}
137
138void Text::RenderText(std::string text, float x, float y, float scale,
139 glm::vec3 color)
140{
141 if (textVao.GetVAO() == 0)
142 {
143 ERROR("Text not initialized");
144 return;
145 }
146
147 Shader::Use(textShader);
148 unsigned int textShaderId = Shader::GetId(textShader);
149
150 glUniform3f(glGetUniformLocation(textShaderId, "textColor"), color.x,
151 color.y, color.z);
152
153 glm::mat4 projection =
154 glm::ortho(0.0f, static_cast<float>(Screen::GetWidth()), 0.0f,
155 static_cast<float>(Screen::GetHeight()));
156 glUniformMatrix4fv(glGetUniformLocation(textShaderId, "projection"), 1,
157 GL_FALSE, glm::value_ptr(projection));
158
159 glActiveTexture(GL_TEXTURE0);
160 textVao.Bind();
161
162 // iterate through all characters
163 std::string::const_iterator c;
164 for (c = text.begin(); c != text.end(); c++)
165 {
166 Character ch = characters[*c];
167
168 float xpos = x + ch.Bearing.x * scale;
169 float ypos = y - (ch.Size.y - ch.Bearing.y) * scale;
170
171 float w = ch.Size.x * scale;
172 float h = ch.Size.y * scale;
173
174 // update VBO for each character
175
176 float vertices[6][4] = {
177 {xpos, ypos + h, 0.0, 0.0}, {xpos, ypos, 0.0, 1.0},
178 {xpos + w, ypos, 1.0, 1.0},
179
180 {xpos, ypos + h, 0.0, 0.0}, {xpos + w, ypos, 1.0, 1.0},
181 {xpos + w, ypos + h, 1.0, 0.0}};
182
183 // render glyph texture over quad
184 glBindTexture(GL_TEXTURE_2D, ch.TextureID);
185
186 // update content of VBO memory
187 glBindBuffer(GL_ARRAY_BUFFER, textVbo.id);
188 glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vertices), vertices);
189
190 glBindBuffer(GL_ARRAY_BUFFER, 0);
191 // render quad
192 glDrawArrays(GL_TRIANGLES, 0, 6);
193 // now advance cursors for next glyph (note that advance is number
194 // of 1/64 pixels)
195 x += (ch.Advance >> 6)
196 * scale; // bitshift by 6 to get value in pixels (2^6 = 64)
197 }
198 glBindVertexArray(0);
199 glBindTexture(GL_TEXTURE_2D, 0);
200
201 /*
202 // Render a test triangle
203 Shader::Use(textShader);
204
205 float vertices[6][4] = {
206 -0.5f, -0.5f, 0.0f, 0.0f,
207 0.5f, -0.5f, 0.0f, 0.0f,
208 0.0f, 0.5f, 0.0f, 1.0f,
209
210 -0.5f, -0.5f, 0.0f, 0.0f,
211 0.5f, -0.5f, 0.0f, 0.0f,
212 0.0f, 0.5f, 0.0f, 0.0f
213 };
214 textVao.Bind();
215 textVbo.Bind();
216 glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vertices), vertices);
217 textVbo.Unbind();
218
219 glDrawArrays(GL_TRIANGLES, 0, 6);
220 */
221}
static int GetHeight()
Get the height of the window.
Definition screen.cpp:110
static int GetWidth()
Get the width of the window.
Definition screen.cpp:105
static unsigned int GetId(Types::ShaderName shader_name)
Get the ID of a shader.
Definition shader.cpp:33
static void New(std::string shader_name, GLenum type, std::string path, Args... args)
Create a new shader.
Definition shader.hpp:93
static void Use(Types::ShaderName shader_name)
Use the shader.
Definition shader.cpp:43
static void Load(std::string font_name, unsigned int fontSize)
Load a font.
Definition text.cpp:50
static void RenderText(std::string text, float x, float y, float scale, glm::vec3 color)
Render text.
Definition text.cpp:138
static std::map< char, Types::Character > characters
Map of characters.
Definition text.hpp:78
static void Init()
Initialize the text subsystem.
Definition text.cpp:41
static void BindTexture(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.
Definition texture.cpp:56
Buffer wrapper around OpenGL buffer objects.
Definition buffer.hpp:50
void Bind()
Bind the buffer object.
Definition buffer.cpp:62
void Unbind()
Unbind the buffer object.
Definition buffer.cpp:72
unsigned int id
Buffer object id, generated by OpenGL.
Definition buffer.hpp:55
Vertex Array Object (VAO)
Definition vao.hpp:45
void Init()
Init Constructor.
Definition vao.cpp:33
unsigned int GetVAO()
Get the VAO.
Definition vao.cpp:39
void Unbind()
Unbind the VAO.
Definition vao.cpp:59
void Bind()
Bind the VAO.
Definition vao.cpp:49
Character struct.
Definition text.hpp:54