2D_Game_Engine
Loading...
Searching...
No Matches
textrenderer.cpp
Go to the documentation of this file.
1#include <pch.hpp>
2#include <textrenderer.hpp>
3#include <window.hpp>
4#include <global.hpp>
5
6TextRenderer::TextRenderer(const std::string &font_path,float glyph_size,bool fixed):
7 m_VBO(6,sizeof(float)*2,GL_STATIC_DRAW),
8 m_Shader("resources/shaders/text/vertex.glsl","resources/shaders/text/fragment.glsl"),
9 m_Loaded(true),
10 m_LoadedFontPath(font_path),
11 m_LoadedGlyphSize(glyph_size),
12 m_ID(std::numeric_limits<uint32_t>::max()),
13 m_FontPath(font_path),
14 m_GlyphSize(glyph_size),
15 m_Fixed(fixed)
16{
17 m_FontPath.resize(100);
18 m_LoadedFontPath.resize(100);
19
20 Init(font_path,glyph_size,fixed);
22}
23
24TextRenderer::TextRenderer(const std::string &font_path,float glyph_size,bool fixed,uint32_t id):
25 m_VBO(6,sizeof(float)*2,GL_STATIC_DRAW),
26 m_Shader("resources/shaders/text/vertex.glsl","resources/shaders/text/fragment.glsl"),
27 m_Loaded(true),
28 m_LoadedFontPath(font_path),
29 m_LoadedGlyphSize(glyph_size),
30 m_ID(id),
31 m_FontPath(font_path),
32 m_GlyphSize(glyph_size),
33 m_Fixed(fixed)
34{
35 m_FontPath.resize(100);
36 m_LoadedFontPath.resize(100);
37
38 Init(font_path,glyph_size,fixed);
40}
41
43 FreeMemory(m_Characters);
44 FreeMemory(m_Transforms);
45 FreeMemory(m_ToRender);
46
47 if(m_Loaded)
48 glDeleteTextures(1,&m_TextureArrayID);
49}
50
51void TextRenderer::DrawText(const std::string &text,float x,float y,float scale,int layer,Vec3 color){
52 PROFILE_FUNCTION();
53
54 if(!m_Loaded){
55 return;
56 }
57
58 TEXT_QUEUE->Push(this,text,x,y,scale,color,layer);
59}
60
61void TextRenderer::_DrawText(const std::string &text,float x,float y,float scale,Vec3 color){
62 PROFILE_FUNCTION();
63
64 if(!m_Loaded){
65 return;
66 }
67
68 float copyX=x;
69 m_Shader.Bind();
70 m_Shader.SetUniform3f("textColor",color.r,color.g,color.b);
71 glActiveTexture(GL_TEXTURE0);
72 glBindTexture(GL_TEXTURE_2D_ARRAY,m_TextureArrayID);
73 m_VAO.Bind();
74 m_VBO.Bind();
75
76 int workingIndex=0;
77 for(auto c:text){
78 if(c=='\0')
79 break;
80 Character ch=m_Characters[c];
81 if(c=='\n'){
82 y-=(ch.Size.y*1.3f*scale/Window::Width*Window::MAX_WIDTH);
83 x=copyX;
84 }else if(c==' ')
85 x+=((ch.Advance>>6)*scale/Window::Width*Window::MAX_WIDTH);
86 else{
87 float xpos=x+(ch.Bearing.x*scale/Window::Width*Window::MAX_WIDTH);
88 float ypos=y-((m_LoadedGlyphSize-ch.Bearing.y)*scale/Window::Width*Window::MAX_WIDTH);
89
90 m_Transforms[workingIndex]=glm::translate(glm::mat4(1.0f),glm::vec3(xpos,ypos,0))*glm::scale(glm::mat4(1.0f),glm::vec3(m_LoadedGlyphSize*scale/Window::Width*Window::MAX_WIDTH,m_LoadedGlyphSize*scale/Window::Width*Window::MAX_WIDTH,0));
91 m_ToRender[workingIndex]=ch.TexID;
92 x+=((ch.Advance>>6)*scale/Window::Width*Window::MAX_WIDTH); // bitshift by 6 to get value in pixels (2^6 = 64 (divide amount of 1/64th pixels by 64 to get amount of pixels))
93 workingIndex++;
94 if(workingIndex==CH_LIMIT-1){
95 Render(workingIndex);
96 workingIndex=0;
97 }
98 }
99 }
100 Render(workingIndex);
101}
102
103std::pair<float,float> TextRenderer::GetTextSize(std::string text,float scale){
104 PROFILE_FUNCTION();
105
106 if(!m_Loaded){
107 return std::make_pair(0.0f,0.0f);
108 }
109
110 float width_=0.0f;
111 float height_=0.0f;
112 float max_width=0.0f;
113 for(auto c:text){
114 if(c=='\0')
115 break;
116 Character ch=m_Characters[c];
117 if(c=='\n'){
118 height_+=(ch.Size.y*1.3f*scale/Window::Width*Window::MAX_WIDTH);
119 max_width=std::max(max_width,width_);
120 width_=0.0f;
121 }else if(c==' ')
122 width_+=((ch.Advance>>6)*scale/Window::Width*Window::MAX_WIDTH);
123 else{
124 width_+=((ch.Advance>>6)*scale/Window::Width*Window::MAX_WIDTH); // bitshift by 6 to get value in pixels (2^6 = 64 (divide amount of 1/64th pixels by 64 to get amount of pixels))
125 }
126 }
127 return std::make_pair(std::max(max_width,width_),std::max(height_,m_Characters['\n'].Size.y*1.3f*scale/Window::Width*Window::MAX_WIDTH));
128}
129
130void TextRenderer::Init(const std::string &font_path,float glyph_size,bool fixed){
131 PROFILE_FUNCTION();
132
133 m_Characters=(Character*)AllocateMemory(CH_NUM*sizeof(Character));
134 m_Transforms=(glm::mat4*)AllocateMemory(CH_LIMIT*sizeof(glm::mat4));
135 m_ToRender=(int*)AllocateMemory(CH_LIMIT*sizeof(int));
136
137 if(FT_Init_FreeType(&m_FT))
138 perror("FREETYPE ERROR: Couldn't init FreeType Library\n");
139
140 if(FT_New_Face(m_FT,font_path.c_str(),0,&m_Face)){
141 perror("FREETYPE ERROR: Failed to load font\n");
142 m_Loaded=false;
143 return;
144 }else{
145 FT_Select_Charmap(m_Face,ft_encoding_unicode);
146 FT_Set_Pixel_Sizes(m_Face,glyph_size,glyph_size);
147 glPixelStorei(GL_UNPACK_ALIGNMENT,1); //disable byte-alignment restriction
148
149 glGenTextures(1,&m_TextureArrayID);
150 glActiveTexture(GL_TEXTURE0);
151 glBindTexture(GL_TEXTURE_2D_ARRAY,m_TextureArrayID);
152 glTexImage3D(GL_TEXTURE_2D_ARRAY,0,GL_R8,glyph_size,glyph_size,CH_NUM,0,GL_RED,GL_UNSIGNED_BYTE,0);
153
154 for(int ch=0;ch<CH_NUM;ch++){
155 if(FT_Load_Char(m_Face,ch,FT_LOAD_RENDER)){
156 perror("FREETYPE ERROR: Failed to load Glyph\n");
157 continue;
158 }
159
160 if(m_Face->glyph->bitmap.rows>glyph_size){
161 #ifdef DEBUG
162 printf("FREETYPE WARNING: Glyph %c is too tall\n",ch);
163 #endif
164 continue;
165 }
166
167 glTexSubImage3D(
168 GL_TEXTURE_2D_ARRAY,
169 0,0,0,ch,
170 m_Face->glyph->bitmap.width,
171 m_Face->glyph->bitmap.rows,1,
172 GL_RED,GL_UNSIGNED_BYTE,
173 m_Face->glyph->bitmap.buffer
174 );
175
176 glTexParameteri(GL_TEXTURE_2D_ARRAY,GL_TEXTURE_WRAP_S,GL_CLAMP_TO_EDGE);
177 glTexParameteri(GL_TEXTURE_2D_ARRAY,GL_TEXTURE_WRAP_T,GL_CLAMP_TO_EDGE);
178 glTexParameteri(GL_TEXTURE_2D_ARRAY,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
179 glTexParameteri(GL_TEXTURE_2D_ARRAY,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
180
181 Character character={
182 ch,
183 glm::ivec2(m_Face->glyph->bitmap.width,m_Face->glyph->bitmap.rows),
184 glm::ivec2(m_Face->glyph->bitmap_left,m_Face->glyph->bitmap_top),
185 (unsigned int)m_Face->glyph->advance.x
186 };
187 m_Characters[ch]=character;
188 }
189 FT_Done_Face(m_Face);
190 }
191 FT_Done_FreeType(m_FT);
192
193 float vertices[]={
194 0.0f,1.0f,
195 0.0f,0.0f,
196 1.0f,1.0f,
197 1.0f,0.0f,
198 };
199
200 m_VBO.SetData(0,vertices,4,sizeof(float)*2);
201 m_VBL.Push(GL_FLOAT,2,false);
202 m_VAO.AddBuffer(m_VBO,m_VBL);
203}
204
205void TextRenderer::Render(int num_characters){
206 PROFILE_FUNCTION();
207
208 if(num_characters!=0){
209 m_Shader.SetUniformMat4fv("transforms",glm::value_ptr(m_Transforms[0]),num_characters);
210 m_Shader.SetUniform1iv("letterMap",&m_ToRender[0],num_characters);
211 glDrawArraysInstanced(GL_TRIANGLE_STRIP,0,4,num_characters);
212 }
213}
void Bind() const
Definition shader.cpp:68
void SetUniform1iv(const std::string &name, int *v, unsigned int num_elem)
Definition shader.cpp:128
void SetUniformMat4fv(const std::string &name, float *proj, unsigned int num_elem)
Definition shader.cpp:136
void SetUniform3f(const std::string &name, float v0, float v1, float v2)
Definition shader.cpp:120
void Push(TextRenderer *renderer, const std::string &text, float x, float y, float scale, Vec3 color, int layer)
Definition textqueue.cpp:4
std::pair< float, float > GetTextSize(std::string text, float scale)
void DrawText(const std::string &text, float x, float y, float scale, int layer, Vec3 color)
void _DrawText(const std::string &text, float x, float y, float scale, Vec3 color)
std::string m_FontPath
void AddBuffer(const VertexBuffer &vb, const VertexBufferLayout &layout)
void Bind() const
void Push(unsigned int type, unsigned int count, bool normalized)
void SetData(unsigned int vertex_index, float *data, unsigned int num_vertices, unsigned int VertexSize)
void Bind() const
void FreeMemory(void *ptr, std::source_location src=std::source_location::current())
Definition memory.cpp:11
void * AllocateMemory(size_t size, std::source_location src=std::source_location::current())
Definition memory.cpp:3
const float MAX_WIDTH
Definition window.cpp:251
bool ProjUpdate
Definition window.cpp:242
float Width
Definition window.cpp:227
return true
char ch
float b
Definition structs.hpp:17
float r
Definition structs.hpp:17
float g
Definition structs.hpp:17
constexpr unsigned int CH_LIMIT
constexpr unsigned int CH_NUM
TextQueue * TEXT_QUEUE
The text queue.
Definition window.cpp:17