Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include "font.h"
- #include <iostream>
- #include <ft2build.h>
- #include <freetype/freetype.h>
- #include <stb_image/stb_image.h>
- #define STB_IMAGE_IMPLEMENTATION
- Font::Font(std::string fontPath, int pixels)
- : quadVAO(0), quadVBO(0), faceVAO(0), faceVBO(0)
- {
- FT_Library ft;
- if (FT_Init_FreeType(&ft))
- std::cout << "ERROR::FREETYPE: Could not init FreeType Library" << std::endl;
- FT_Face face;
- if (FT_New_Face(ft, fontPath.c_str(), 0, &face))
- std::cout << "ERROR::FREETYPE: Failed to load font" << std::endl;
- FT_Set_Pixel_Sizes(face, 0, pixels);
- if (FT_Load_Char(face, 'W', FT_LOAD_RENDER))
- std::cout << "ERROR::FREETYPE: Failed to load Glyph" << std::endl;
- glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
- this->textureSize.x = face->glyph->bitmap.width * 12;
- this->textureSize.y = face->glyph->bitmap.rows * 12;
- //if (this->textureSize.y > this->textureSize.x)
- // textureSize.x = textureSize.y;
- //else
- // textureSize.y = textureSize.x;
- glGenTextures(1, &this->texture);
- glBindTexture(GL_TEXTURE_2D, this->texture);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, this->textureSize.x, this->textureSize.y, 0, GL_RED, GL_UNSIGNED_BYTE, NULL);
- 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);
- glm::vec2 place_size;
- place_size.x = face->glyph->bitmap.width;
- FT_Load_Char(face, '@', FT_LOAD_RENDER);
- place_size.y = face->glyph->bitmap.rows;
- const_cast<glm::vec2 *> (&place_size);
- Font::Character character = {
- glm::ivec2(0, 0),
- glm::ivec2(0, 0),
- glm::ivec2(0, 0),
- 0
- };
- for (GLubyte c = 0; c < 128; ++c)
- {
- if (FT_Load_Char(face, c, FT_LOAD_RENDER))
- {
- std::cout << "ERROR::FREETYPE: Failed to load Glyph" << std::endl;
- continue;
- }
- character = {
- glm::ivec2(face->glyph->bitmap.width, face->glyph->bitmap.rows),
- glm::ivec2(face->glyph->bitmap_left, face->glyph->bitmap_top),
- character.position,
- static_cast<GLuint>(face->glyph->advance.x)
- };
- if (c % 11 || c == 0)
- {
- character.position.x += place_size.x;
- }
- else
- {
- character.position.x = 0;
- character.position.y += place_size.y;
- }
- glTexSubImage2D(
- GL_TEXTURE_2D,
- 0,
- character.position.x,
- character.position.y,
- character.size.x,
- character.size.y,
- GL_RED,
- GL_UNSIGNED_BYTE,
- face->glyph->bitmap.buffer
- );
- characters.insert(std::pair<GLchar, Character>(c, character));
- }
- glGetError();
- FT_Done_Face(face);
- FT_Done_FreeType(ft);
- glGenVertexArrays(1, &faceVAO);
- glGenBuffers(1, &faceVBO);
- glBindVertexArray(faceVAO);
- glBindBuffer(GL_ARRAY_BUFFER, faceVBO);
- glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * 6 * 4, NULL, GL_DYNAMIC_DRAW);
- glEnableVertexAttribArray(0);
- glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 4 * sizeof(GLfloat), 0);
- glBindBuffer(GL_ARRAY_BUFFER, 0);
- glBindVertexArray(0);
- glBindVertexArray(0);
- }
- Font::~Font()
- {
- glDeleteBuffers(1, &quadVBO);
- glDeleteBuffers(1, &faceVBO);
- glDeleteVertexArrays(1, &quadVAO);
- glDeleteVertexArrays(1, &faceVAO);
- glDeleteTextures(1, &texture);
- }
- void Font::renderBitmap(Shader & shader)
- {
- shader.use();
- shader.setBool("bitmap", 1);
- shader.setVec3("textColor", glm::vec3(1.0f));
- glActiveTexture(GL_TEXTURE0);
- glBindTexture(GL_TEXTURE_2D, this->texture);
- if (quadVAO == 0)
- {
- float quadVertices[] = {
- // positions // texture Coords
- 1.0f, -1.0f, 1.0f, 1.0f,
- 1.0f, 1.0f, 1.0f, 0.0f,
- -1.0f, -1.0f, 0.0f, 1.0f,
- -1.0f, 1.0f, 0.0f, 0.0f
- };
- // setup plane VAO
- glGenVertexArrays(1, &quadVAO);
- glGenBuffers(1, &quadVBO);
- glBindVertexArray(quadVAO);
- glBindBuffer(GL_ARRAY_BUFFER, quadVBO);
- glBufferData(GL_ARRAY_BUFFER, sizeof(quadVertices), quadVertices, GL_STATIC_DRAW);
- glEnableVertexAttribArray(0);
- glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (void*)0);
- }
- //std::cout << "RenderQuad: " << glGetError() << std::endl;
- glBindVertexArray(quadVAO);
- glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
- glBindVertexArray(0);
- glBindTexture(GL_TEXTURE_2D, 0);
- shader.setBool("bitmap", 0);
- }
- void Font::renderText(Shader & shader, std::string text, GLfloat x, GLfloat y, GLfloat scale, glm::vec3 color)
- {
- shader.use();
- shader.setVec3("textColor", color);
- shader.setInt("text", 0);
- shader.setBool("bitmap", 0);
- glActiveTexture(GL_TEXTURE0);
- glBindTexture(GL_TEXTURE_2D, this->texture);
- glBindVertexArray(this->faceVAO);
- // Iterate through all characters
- std::string::const_iterator c;
- for (c = text.begin(); c != text.end(); c++)
- {
- Character ch = characters[*c];
- GLfloat xpos = x + ch.bearing.x * scale;
- GLfloat ypos = y - (ch.size.y - ch.bearing.y) * scale;
- GLfloat w = ch.size.x * scale;
- GLfloat h = ch.size.y * scale;
- glm::vec2 TexCoords[2][2];
- TexCoords[0][0] = glm::vec2(ch.position.x / textureSize.x, ch.position.y / textureSize.y);
- TexCoords[1][0] = glm::vec2(ch.size.x / textureSize.x + TexCoords[0][0].x, TexCoords[0][0].y);
- TexCoords[0][1] = glm::vec2(TexCoords[0][0].x, ch.size.y / textureSize.y + TexCoords[0][0].y);
- TexCoords[1][1] = glm::vec2(TexCoords[1][0].x, TexCoords[0][1].y);
- // Update VBO for each character
- GLfloat vertices[6][4] = {
- { xpos, ypos + h, TexCoords[0][0].x, TexCoords[0][0].y},
- { xpos, ypos, TexCoords[0][1].x, TexCoords[0][1].y},
- { xpos + w, ypos, TexCoords[1][1].x, TexCoords[1][1].y},
- { xpos, ypos + h, TexCoords[0][0].x, TexCoords[0][0].y},
- { xpos + w, ypos, TexCoords[1][1].x, TexCoords[1][1].y},
- { xpos + w, ypos + h, TexCoords[1][0].x, TexCoords[1][0].y}
- };
- //GLfloat vertices[6][4] = {
- // { xpos, ypos + h, 0.0, 0.0},
- // { xpos, ypos, 0.0, 1.0},
- // { xpos + w, ypos, 1.0, 1.0},
- // { xpos, ypos + h, 0.0, 0.0},
- // { xpos + w, ypos, 1.0, 1.0},
- // { xpos + w, ypos + h, 1.0, 0.0}
- //};
- // Render glyph texture over quad
- // Update content of VBO memory
- //std::cout << "Przed bind faceVAO: " << glGetError() << std::endl;
- glBindBuffer(GL_ARRAY_BUFFER, faceVBO);
- glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vertices), vertices);
- glBindBuffer(GL_ARRAY_BUFFER, 0);
- // Render quad
- glDrawArrays(GL_TRIANGLES, 0, 6);
- // Now advance cursors for next glyph (note that advance is number of 1/64 pixels)
- x += (ch.advance >> 6) * scale; // Bitshift by 6 to get value in pixels (2^6 = 64)
- }
- glBindVertexArray(0);
- glBindTexture(GL_TEXTURE_2D, 0);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement