在 C++ opengl truetype 字体中,字符通过不同的字体大小变为对角线

Character goes diagonal by diffrent font sizes in c++ opengl true type font

我一直在尝试让 TTF 与我的 OpenGL 项目一起工作,这是我最接近的,这是我的代码:

#include "App.h"

std::array <float, 4> background_col = {0.25, 0.25, 0.25, 1.0}  ;
std::string name                     = "OpenGL"                 ;
std::string icon                     = "data/images/dot.png"    ;
const int width                      = 800                      ;
const int height                     = 800                      ;
bool anti_aliasing                   = true                     ;
bool FPS_60_CAP                      = true                     ;
bool movable                         = false                    ;
    
Core::Base::MVP mvp;

int a = 32;

void key_callback(GLFWwindow *window, int key, int scancode, int action, int mods)
{
    if (action == GLFW_PRESS) { a += 1; }
    info(a);
}

double mouseX, mouseY;
double pmouseX, pmouseY;

glm::vec2 t(0);

void mouse(GLFWwindow * window) {
    pmouseX = mouseX;
    pmouseY = mouseY;

    double xpos, ypos;
    glfwGetCursorPos(window, &xpos, &ypos);
    mouseX = xpos;
    mouseY = height - ypos;

    if (glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_LEFT)  && movable) {
        t.x += mouseX - pmouseX;
        t.y += mouseY - pmouseY;
        mvp.translate(0, t);
    }
}

void App::run()
{
    Core::Window window(true, anti_aliasing);
    window.make_Window(glfwCreateWindow(width, height, name.c_str(), NULL, NULL), key_callback, icon);

    srand(time(NULL));
    mvp.view = glm::ortho(0.0f, (float)width, 0.0f, (float)height);

    Core::Renderer renderer;
    Core::Player player;

    // 1. TODO: Implement Text
    // 2. TODO: Implement UI

    FT_Library ft;
    FT_Error err = FT_Init_FreeType(&ft);
    
    if (err != 0) {
        printf("Failed to initialize FreeType\n");
        exit(EXIT_FAILURE);
    }
    
    FT_Int major, minor, patch;
    FT_Library_Version(ft, &major, &minor, &patch);
    printf("FreeType's version is %d.%d.%d\n", major, minor, patch);
    
    FT_Face face;
    err = FT_New_Face(ft, "data/fonts/arial.ttf", 0, &face);

    if (err != 0) {
        printf("Failed to load face\n");
        exit(EXIT_FAILURE);
    }

    while (!glfwWindowShouldClose(window.window))
    {
        glClearColor(background_col[0], background_col[1], background_col[2], background_col[3]);
        glClear(GL_COLOR_BUFFER_BIT);

//        mouse(window.window);
//        renderer.Render({ Core::Draw::Ellipse({400, 400, {1,0,1,1}}, 100, 75, true) }, mvp);

        err = FT_Set_Pixel_Sizes(face, 0, a);
    
        if (err != 0) {
            printf("Failed to set pixel size\n");
            exit(EXIT_FAILURE);
        }
        
        FT_UInt glyph_index = FT_Get_Char_Index(face, 'o');
        FT_Int32 load_flags = FT_LOAD_DEFAULT;
        
        err = FT_Load_Glyph(face, glyph_index, load_flags);
        
        if (err != 0) {
            printf("Failed to load glyph\n");
            exit(EXIT_FAILURE);
        }
        
        err = FT_Render_Glyph(face->glyph, FT_RENDER_MODE_NORMAL);
        
        if (err != 0) {
            printf("Failed to render the glyph\n");
            exit(EXIT_FAILURE);
        }

        glDrawPixels( face->glyph->bitmap.width, face->glyph->bitmap.rows, GL_ALPHA, GL_UNSIGNED_BYTE, face->glyph->bitmap.buffer);

        Core::viewport(window.window);
        glfwSwapBuffers(window.window);
        glfwSwapInterval(FPS_60_CAP);
        glfwPollEvents();
    }
    
    alcCloseDevice(player.Device);
    window.~Window();
}

这是我的意思的一个例子: Error

它有时会正确呈现,但当您更改字体大小时它会变得混乱。

默认情况下,假设每行像素对齐到 4 个字节,但您的像素数据根本没有对齐。您可以通过设置 GL_UNPACK_ALIGNMENT(参见 glDrawPixels and glPixelStore)来更改对齐要求:

glPixelStore(GL_UNPACK_ALIGNMENT, 1);
glDrawPixels( face->glyph->bitmap.width, face->glyph->bitmap.rows, GL_ALPHA, GL_UNSIGNED_BYTE, face->glyph->bitmap.buffer);