2016-07-30 108 views
0

尝试渲染使用FreeType2和this online tutorial的字符,但有一些问题,结果非常不规则。我查看了本网站herehere上的其他问题,并进行了更正,但我仍然非常难过。我将它进行到底,但该位图显示不正确:OpenGL FreeType2位图不渲染

Font bitmap

不仅如此,但显示取决于我想要呈现的字符。有些显示为空白,而其他显示为矩形。代码如下,任何意见将不胜感激。

主程序:

#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; 
} 

顶点着色器:

#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; 
} 

片段着色器:

#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; 
} 

回答

1

如果你试图显示不同的字符,你会看到,你只显示一个它的一部分将导致你错误的原因。这是一个在上传紫外线缓冲,一个简单的错误copy_paste的代码:

glBufferData(GL_ARRAY_BUFFER, sizeof(letter_uv), letter, GL_STATIC_DRAW); 

的第三个参数被前人的精力letter_uv