c++ 中的字符按不同字体大小对角线移动opengl True Type 字体

发布于 2025-01-20 04:12:53 字数 3686 浏览 3 评论 0原文

我一直在试图让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

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

I've been trying to get TTF to work with my OpenGL project and this is the closest I've come to, here is my code:

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

here is an example of what i mean:
Error

It renders correctly sometimes but when you change the font size it gets messed up.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

这个俗人 2025-01-27 04:12:54

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

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

By default each row of the pixels is assumed be aligned to 4 bytes, but your pixel data is not aligned at all. You can change the alignment requirements by setting GL_UNPACK_ALIGNMENT (see 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);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文