Advertisement
Guest User

Untitled

a guest
Jun 18th, 2019
122
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.58 KB | None | 0 0
  1. #include "font.h"
  2. #include <iostream>
  3. #include <ft2build.h>
  4. #include <freetype/freetype.h>
  5. #include <stb_image/stb_image.h>
  6. #define STB_IMAGE_IMPLEMENTATION
  7.  
  8. Font::Font(std::string fontPath, int pixels)
  9.     : quadVAO(0), quadVBO(0), faceVAO(0), faceVBO(0)
  10. {
  11.     FT_Library ft;
  12.     if (FT_Init_FreeType(&ft))
  13.         std::cout << "ERROR::FREETYPE: Could not init FreeType Library" << std::endl;
  14.    
  15.     FT_Face face;
  16.     if (FT_New_Face(ft, fontPath.c_str(), 0, &face))
  17.         std::cout << "ERROR::FREETYPE: Failed to load font" << std::endl;
  18.     FT_Set_Pixel_Sizes(face, 0, pixels);
  19.    
  20.     if (FT_Load_Char(face, 'W', FT_LOAD_RENDER))
  21.         std::cout << "ERROR::FREETYPE: Failed to load Glyph" << std::endl;
  22.  
  23.     glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
  24.    
  25.     this->textureSize.x = face->glyph->bitmap.width * 12;
  26.     this->textureSize.y = face->glyph->bitmap.rows * 12;
  27.     //if (this->textureSize.y > this->textureSize.x)
  28.     //  textureSize.x = textureSize.y;
  29.     //else
  30.     //  textureSize.y = textureSize.x;
  31.  
  32.     glGenTextures(1, &this->texture);
  33.     glBindTexture(GL_TEXTURE_2D, this->texture);
  34.     glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, this->textureSize.x, this->textureSize.y, 0, GL_RED, GL_UNSIGNED_BYTE, NULL);
  35.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
  36.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
  37.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  38.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  39.    
  40.     glm::vec2 place_size;
  41.     place_size.x = face->glyph->bitmap.width;
  42.     FT_Load_Char(face, '@', FT_LOAD_RENDER);
  43.     place_size.y = face->glyph->bitmap.rows;
  44.     const_cast<glm::vec2 *> (&place_size);
  45.  
  46.     Font::Character character = {
  47.         glm::ivec2(0, 0),
  48.         glm::ivec2(0, 0),
  49.         glm::ivec2(0, 0),
  50.         0
  51.     };
  52.  
  53.     for (GLubyte c = 0; c < 128; ++c)
  54.     {
  55.         if (FT_Load_Char(face, c, FT_LOAD_RENDER))
  56.         {
  57.             std::cout << "ERROR::FREETYPE: Failed to load Glyph" << std::endl;
  58.             continue;
  59.         }
  60.  
  61.         character = {
  62.             glm::ivec2(face->glyph->bitmap.width, face->glyph->bitmap.rows),
  63.             glm::ivec2(face->glyph->bitmap_left, face->glyph->bitmap_top),
  64.             character.position,
  65.             static_cast<GLuint>(face->glyph->advance.x)
  66.         };
  67.         if (c % 11 || c == 0)
  68.         {
  69.             character.position.x += place_size.x;
  70.         }
  71.         else
  72.         {
  73.             character.position.x = 0;
  74.             character.position.y += place_size.y;
  75.         }
  76.         glTexSubImage2D(
  77.             GL_TEXTURE_2D,
  78.             0,
  79.             character.position.x,
  80.             character.position.y,
  81.             character.size.x,
  82.             character.size.y,
  83.             GL_RED,
  84.             GL_UNSIGNED_BYTE,
  85.             face->glyph->bitmap.buffer
  86.         );
  87.  
  88.         characters.insert(std::pair<GLchar, Character>(c, character));
  89.     }
  90.     glGetError();
  91.     FT_Done_Face(face);
  92.     FT_Done_FreeType(ft);
  93.     glGenVertexArrays(1, &faceVAO);
  94.     glGenBuffers(1, &faceVBO);
  95.     glBindVertexArray(faceVAO);
  96.     glBindBuffer(GL_ARRAY_BUFFER, faceVBO);
  97.     glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * 6 * 4, NULL, GL_DYNAMIC_DRAW);
  98.     glEnableVertexAttribArray(0);
  99.     glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 4 * sizeof(GLfloat), 0);
  100.     glBindBuffer(GL_ARRAY_BUFFER, 0);
  101.     glBindVertexArray(0);
  102.     glBindVertexArray(0);
  103. }
  104.  
  105. Font::~Font()
  106. {
  107.     glDeleteBuffers(1, &quadVBO);
  108.     glDeleteBuffers(1, &faceVBO);
  109.     glDeleteVertexArrays(1, &quadVAO);
  110.     glDeleteVertexArrays(1, &faceVAO);
  111.     glDeleteTextures(1, &texture);
  112. }
  113.  
  114. void Font::renderBitmap(Shader & shader)
  115. {
  116.     shader.use();
  117.     shader.setBool("bitmap", 1);
  118.     shader.setVec3("textColor", glm::vec3(1.0f));
  119.     glActiveTexture(GL_TEXTURE0);
  120.     glBindTexture(GL_TEXTURE_2D, this->texture);
  121.     if (quadVAO == 0)
  122.     {
  123.         float quadVertices[] = {
  124.             // positions        // texture Coords
  125.             1.0f, -1.0f, 1.0f, 1.0f,
  126.             1.0f,  1.0f, 1.0f, 0.0f,
  127.             -1.0f, -1.0f, 0.0f, 1.0f,
  128.             -1.0f, 1.0f, 0.0f, 0.0f
  129.         };
  130.         // setup plane VAO
  131.         glGenVertexArrays(1, &quadVAO);
  132.         glGenBuffers(1, &quadVBO);
  133.         glBindVertexArray(quadVAO);
  134.         glBindBuffer(GL_ARRAY_BUFFER, quadVBO);
  135.         glBufferData(GL_ARRAY_BUFFER, sizeof(quadVertices), quadVertices, GL_STATIC_DRAW);
  136.         glEnableVertexAttribArray(0);
  137.         glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (void*)0);
  138.     }
  139.     //std::cout << "RenderQuad: " << glGetError() << std::endl;
  140.     glBindVertexArray(quadVAO);
  141.     glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
  142.     glBindVertexArray(0);
  143.     glBindTexture(GL_TEXTURE_2D, 0);
  144.     shader.setBool("bitmap", 0);
  145. }
  146. void Font::renderText(Shader & shader, std::string text, GLfloat x, GLfloat y, GLfloat scale, glm::vec3 color)
  147. {
  148.     shader.use();
  149.     shader.setVec3("textColor", color);
  150.     shader.setInt("text", 0);
  151.     shader.setBool("bitmap", 0);
  152.     glActiveTexture(GL_TEXTURE0);
  153.     glBindTexture(GL_TEXTURE_2D, this->texture);
  154.     glBindVertexArray(this->faceVAO);
  155.  
  156.     // Iterate through all characters
  157.     std::string::const_iterator c;
  158.     for (c = text.begin(); c != text.end(); c++)
  159.     {
  160.         Character ch = characters[*c];
  161.  
  162.         GLfloat xpos = x + ch.bearing.x * scale;
  163.         GLfloat ypos = y - (ch.size.y - ch.bearing.y) * scale;
  164.  
  165.         GLfloat w = ch.size.x * scale;
  166.         GLfloat h = ch.size.y * scale;
  167.         glm::vec2 TexCoords[2][2];
  168.         TexCoords[0][0] = glm::vec2(ch.position.x / textureSize.x, ch.position.y / textureSize.y);
  169.         TexCoords[1][0] = glm::vec2(ch.size.x / textureSize.x + TexCoords[0][0].x, TexCoords[0][0].y);
  170.         TexCoords[0][1] = glm::vec2(TexCoords[0][0].x, ch.size.y / textureSize.y + TexCoords[0][0].y);
  171.         TexCoords[1][1] = glm::vec2(TexCoords[1][0].x, TexCoords[0][1].y);
  172.         // Update VBO for each character
  173.         GLfloat vertices[6][4] = {
  174.             { xpos,     ypos + h,   TexCoords[0][0].x, TexCoords[0][0].y},
  175.             { xpos,     ypos,       TexCoords[0][1].x, TexCoords[0][1].y},
  176.             { xpos + w, ypos,       TexCoords[1][1].x, TexCoords[1][1].y},
  177.  
  178.             { xpos,     ypos + h,   TexCoords[0][0].x, TexCoords[0][0].y},
  179.             { xpos + w, ypos,       TexCoords[1][1].x, TexCoords[1][1].y},
  180.             { xpos + w, ypos + h,   TexCoords[1][0].x, TexCoords[1][0].y}
  181.         };
  182.        
  183.         //GLfloat vertices[6][4] = {
  184.         //  { xpos,     ypos + h,   0.0, 0.0},
  185.         //  { xpos,     ypos,       0.0, 1.0},
  186.         //  { xpos + w, ypos,       1.0, 1.0},
  187.  
  188.         //  { xpos,     ypos + h,   0.0, 0.0},
  189.         //  { xpos + w, ypos,       1.0, 1.0},
  190.         //  { xpos + w, ypos + h,   1.0, 0.0}
  191.         //};
  192.         // Render glyph texture over quad
  193.         // Update content of VBO memory
  194.         //std::cout << "Przed bind faceVAO: " << glGetError() << std::endl;
  195.         glBindBuffer(GL_ARRAY_BUFFER, faceVBO);
  196.         glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vertices), vertices);
  197.         glBindBuffer(GL_ARRAY_BUFFER, 0);
  198.         // Render quad
  199.         glDrawArrays(GL_TRIANGLES, 0, 6);
  200.         // Now advance cursors for next glyph (note that advance is number of 1/64 pixels)
  201.         x += (ch.advance >> 6) * scale; // Bitshift by 6 to get value in pixels (2^6 = 64)
  202.     }
  203.     glBindVertexArray(0);
  204.     glBindTexture(GL_TEXTURE_2D, 0);
  205. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement