Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // Std. Includes
- #include <iostream>
- #include <map>
- #include <string>
- // GLAD
- #include <glad/glad.h>
- // GLFW
- #include <GLFW/glfw3.h>
- // GLM
- #include <glm/glm.hpp>
- #include <glm/gtc/matrix_transform.hpp>
- #include <glm/gtc/type_ptr.hpp>
- // FreeType
- #include <ft2build.h>
- #include FT_FREETYPE_H
- // GL includes
- #include <shader/shader.h>
- // Properties
- const GLuint WIDTH = 800, HEIGHT = 600;
- struct Character {
- GLuint textureID;
- glm::ivec2 size;
- glm::ivec2 bearing;
- GLuint advance;
- GLuint xoffset;
- };
- std::map<GLchar, Character> characters;
- GLuint VAO, VBO, fontTexture;
- void renderText(Shader &s, std::string text, GLfloat x, GLfloat y, GLfloat scale, glm::vec3 color);
- // The MAIN function, from here we start our application and run the Game loop
- int main()
- {
- // Init GLFW
- glfwInit();
- glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
- glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
- glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
- glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);
- GLFWwindow* window = glfwCreateWindow(WIDTH, HEIGHT, "LearnOpenGL", nullptr, nullptr); // Windowed
- glfwMakeContextCurrent(window);
- if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
- {
- std::cout << "Failed to initialize GLAD" << std::endl;
- return -1;
- }
- // Define the viewport dimensions
- glViewport(0, 0, WIDTH, HEIGHT);
- // Set OpenGL options
- glEnable(GL_CULL_FACE);
- glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- Shader shader("text.vert", "text.frag");
- glm::mat4 projection = glm::ortho(0.0f, float(WIDTH), 0.0f, float(HEIGHT));
- shader.use();
- shader.setMat4("projection", projection);
- 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, "arial.ttf", 0, &face))
- std::cout << "ERROR::FREETYPE: Failed to load font" << std::endl;
- FT_Set_Pixel_Sizes(face, 0, 48);
- if (FT_Load_Char(face, 'X', FT_LOAD_RENDER))
- std::cout << "ERROR::FREETYPE: Failed to load Glyph" << std::endl;
- glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
- glGenTextures(1, &fontTexture);
- glBindTexture(GL_TEXTURE_2D, fontTexture);
- glTexImage2D(
- GL_TEXTURE_2D,
- 0,
- GL_RED,
- face->glyph->bitmap.width * 250,
- face->glyph->bitmap.rows * 250,
- 0,
- GL_RED,
- GL_UNSIGNED_BYTE,
- NULL
- );
- GLuint font_texture_width = 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;
- }
- GLuint texture;
- glGenTextures(1, &texture);
- glBindTexture(GL_TEXTURE_2D, texture);
- glTexImage2D(
- GL_TEXTURE_2D,
- 0,
- GL_RED,
- face->glyph->bitmap.width,
- face->glyph->bitmap.rows,
- 0,
- GL_RED,
- GL_UNSIGNED_BYTE,
- face->glyph->bitmap.buffer
- );
- 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);
- Character character = {
- texture,
- glm::ivec2(face->glyph->bitmap.width, face->glyph->bitmap.rows),
- glm::ivec2(face->glyph->bitmap_left, face->glyph->bitmap_top),
- face->glyph->advance.x,
- font_texture_width
- };
- font_texture_width += character.size.x;
- characters.insert(std::pair<GLchar, Character>(c, character));
- }
- glBindTexture(GL_TEXTURE_2D, 0);
- FT_Done_Face(face);
- FT_Done_FreeType(ft);
- for (auto ch : characters)
- font_texture_width += ch.second.size.x;
- glGenTextures(1, &fontTexture);
- glBindTexture(GL_TEXTURE_2D, fontTexture);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, font_texture_width, 100, 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);
- std::cout << glGetError();
- for (GLubyte c = 0; c < 128; ++c)
- glCopyImageSubData( characters[c].textureID, GL_TEXTURE_2D, 0, 0, 0, 0,
- fontTexture, GL_TEXTURE_2D, 0, characters[c].xoffset, 0, 0,
- characters[c].size.x, characters[c].size.y, 0);
- glGenVertexArrays(1, &VAO);
- glGenBuffers(1, &VBO);
- glBindVertexArray(VAO);
- glBindBuffer(GL_ARRAY_BUFFER, VBO);
- 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);
- // Game loop
- while (!glfwWindowShouldClose(window))
- {
- // Check and call events
- glfwPollEvents();
- // Clear the colorbuffer
- glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
- glClear(GL_COLOR_BUFFER_BIT);
- renderText(shader, "This is sample text", 25.0f, 25.0f, 1.0f, glm::vec3(0.5, 0.8f, 0.2f));
- renderText(shader, "(C) LearnOpenGL.com", 540.0f, 570.0f, 0.5f, glm::vec3(0.3, 0.7f, 0.9f));
- // Swap the buffers
- glfwSwapBuffers(window);
- }
- glfwTerminate();
- return 0;
- }
- void renderText(Shader &s, std::string text, GLfloat x, GLfloat y, GLfloat scale, glm::vec3 color)
- {
- s.use();
- s.setVec3("textColor", color);
- glActiveTexture(GL_TEXTURE0);
- glBindVertexArray(VAO);
- std::string::const_iterator c;
- glBindTexture(GL_TEXTURE_2D, fontTexture);
- 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;
- GLfloat vertices[6][4] = {
- { xpos + characters[*c].xoffset, ypos + h, 0.0, 0.0 },
- { xpos + characters[*c].xoffset, ypos, 0.0, 1.0 },
- { xpos + w + characters[*c].xoffset, ypos, 1.0, 1.0 },
- { xpos + characters[*c].xoffset, ypos + h, 0.0, 0.0 },
- { xpos + w + characters[*c].xoffset, ypos, 1.0, 1.0 },
- { xpos + w + characters[*c].xoffset, ypos + h, 1.0, 0.0 }
- };
- glBindBuffer(GL_ARRAY_BUFFER, VBO);
- glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vertices), vertices);
- glBindBuffer(GL_ARRAY_BUFFER, 0);
- glDrawArrays(GL_TRIANGLES, 0, 6);
- x += (ch.advance >> 6) * scale;
- }
- glBindVertexArray(0);
- glBindTexture(GL_TEXTURE_2D, 0);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement