Versuch, ein Zeichen mit FreeType2 und this online tutorial zu rendern, aber einige Probleme und die Ergebnisse sind ziemlich unregelmäßig. Ich habe mir die anderen Fragen auf dieser Webseite here und here angesehen und diese Korrekturen vorgenommen, aber ich bin immer noch ziemlich ratlos. Ich habe es bis zum Ende gemacht, aber die Bitmap-Anzeige ist nicht richtig:OpenGL FreeType2 Bitmap nicht rendern
Nicht nur das, aber die Anzeige ist abhängig von dem Charakter, den ich zu machen werde versuchen. Einige werden leer angezeigt, während andere als Rechteck angezeigt werden. Code ist unten, jeder Rat würde sehr geschätzt werden.
Hauptprogramm:
#include <iostream>
#include <fstream>
#include <vector>
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#define GLM_FORCE_RADIANS
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtx/transform.hpp>
#include <ft2build.h>
#include FT_FREETYPE_H
#include "OGLT.hpp"
OGLT Toolkit;
GLuint vao, vbo[2], shader, uniform_color, tex, uniform_tex;
static void key_callback(GLFWwindow * window, int key, int scancode, int action, int mods){
if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS)
glfwSetWindowShouldClose(window, GL_TRUE);
}
void MyInitialize(){
// Initialize FreeType
FT_Library library;
FT_Face face;
int error = FT_Init_FreeType(&library);
if (error){
std::cout << "An error occurred during library initialization!\n";
}
//error = FT_New_Face(library, "open-sans/OpenSans-Regular.ttf", 0, &face);
error = FT_New_Face(library, "/usr/share/fonts/truetype/droid/DroidSans.ttf", 0, &face);
if(error == FT_Err_Unknown_File_Format){
std::cout << "The font file could be opened and read, but it appears " <<
"that its font format is unsupported.\n";
}
else if(error){
std::cout << "Another error code means that the font file could not be " <<
"opened or read, or that it is broken.\n";
}
else std::cout << "Font file sucessfully loaded!\n";
FT_Set_Pixel_Sizes(face, 0, 100);
// Initialize GLEW and load shaders
Toolkit.StartGLEW();
// OpenGL state initialization
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glPixelStorei(GL_UNPACK_ALIGNMENT,1);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LESS);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
// Vertex buffer initialization
FT_Load_Char(face, 'W', FT_LOAD_RENDER);
FT_GlyphSlot g = face->glyph;
float x = 0.0f, y = 0.0f;
float sx = 2.0/1000.0;
float sy = 2.0/800.0;
float x2 = x + g->bitmap_left * sx;
float y2 = -y - g->bitmap_top * sy;
float w = g->bitmap.width * sx;
float h = g->bitmap.rows * sy;
static float letter[] = {
x2, -y2, 0.0f,
x2+w, -y2, 0.0f,
x2, -y2-h, 0.0f,
x2+w, -y2-h, 0.0f,
};
static float letter_uv[] = {
0.0f, 0.0f,
1.0f, 0.0f,
0.0f, 1.0f,
1.0f, 1.0f
};
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
glGenBuffers(2, vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo[0]);
glBufferData(GL_ARRAY_BUFFER, sizeof(letter), letter, GL_STATIC_DRAW);
GLuint VertexAttributeID = 0;
glVertexAttribPointer(VertexAttributeID, 3, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(VertexAttributeID);
glBindBuffer(GL_ARRAY_BUFFER, vbo[1]);
glBufferData(GL_ARRAY_BUFFER, sizeof(letter_uv), letter, GL_STATIC_DRAW);
GLuint UvAttributeID = 1;
glVertexAttribPointer(UvAttributeID, 2, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(UvAttributeID);
glBindVertexArray(0);
glBindBuffer(GL_ARRAY_BUFFER, vbo[0]);
glActiveTexture(GL_TEXTURE0);
glGenTextures(1, &tex);
glBindTexture(GL_TEXTURE_2D, tex);
glTexImage2D(GL_TEXTURE_2D, 0, GL_R8, g->bitmap.width, g->bitmap.rows, 0,
GL_RED, GL_UNSIGNED_BYTE, g->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);
shader = Toolkit.LoadShaders("test_vertex.glsl", "test_fragment.glsl");
uniform_color = glGetUniformLocation(shader, "color");
uniform_tex = glGetUniformLocation(shader, "texture_sampler");
}
void MyDisplay(GLFWwindow * window){
int width, height;
glfwGetFramebufferSize(window, &width, &height);
glViewport(0, 0, width, height);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glUseProgram(shader);
glm::vec4 ColorVec = glm::vec4(0.0f, 1.0f, 0.0f, 1.0f);
glUniform4fv(uniform_color, 1, &ColorVec[0]);
glUniform1i(uniform_tex, 0);
glBindVertexArray(vao);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, tex);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
glBindVertexArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindTexture(GL_TEXTURE_2D, 0);
glUseProgram(0);
}
int main(){
// Initialize window
GLFWwindow * window;
// Initialize the library
if(!glfwInit()) return -1;
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
// Create a windowed mode window and its OpenGL context
window = glfwCreateWindow(1000, 800, "Font Test", NULL, NULL);
if(!window){
glfwTerminate();
return -1;
}
// Make the window's context current
glfwMakeContextCurrent(window);
glfwSwapInterval(1);
glfwSetKeyCallback(window, key_callback);
MyInitialize();
// Loop until the user closes the window
while(!glfwWindowShouldClose(window)){
// Render here
MyDisplay(window);
// Swap front and back buffers
glfwSwapBuffers(window);
// Poll for and process events
glfwPollEvents();
}
glfwDestroyWindow(window);
glfwTerminate();
return 0;
}
Vertex-Shader:
#version 330 core
layout (location = 0) in vec3 vertex;
layout (location = 1) in vec2 vertex_uv;
out vec2 uv;
void main(){
gl_Position = vec4(vertex.xyz, 1);
uv = vertex_uv;
}
Fragment-Shader:
#version 330 core
in vec2 uv;
uniform vec4 color;
uniform sampler2D texture_sampler;
out vec4 color_out;
void main(){
color_out = vec4(1.0, 1.0, 1.0, texture(texture_sampler, uv).r) * color;
}