簡體   English   中英

FreeType2 為文本添加輪廓

[英]FreeType2 add outline to text

我正在嘗試為使用 freetype 繪制的文本添加邊框/輪廓。 到目前為止,我已經找到了關於它的 freetype 文檔,但它們有點不一致。 有些函數/結構在我的項目中是可見的,但有些不是。 例如,我可以像這個FT_Outline border; 但我不能調用 function 我需要調用以應用該大綱,就像文檔說我這樣做: FT_Outline_New( FT_Library library, FT_UInt numPoints, FT_Int numContours, FT_Outline *anoutline ); . 這個問題也無濟於事,幾乎所有的功能/結構都不存在於我的設置中。

我有點迷茫,我應該如何為我的文本實現大綱? 這些方法是否已經過時,如果是,現代方法是什么? 我鏈接/導入/編譯freetype錯了嗎? 我對 freetype 沒有任何錯誤,所以我認為我的 freetype 實現沒有任何錯誤。

這是我的文本渲染過程的樣子:

文本.cpp


Text::Text(text_attributes&& atrib, int gl_width, int gl_height) 
{
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

    shader = Shader("./src/opengl/shaders/text.vs", "./src/opengl/shaders/text.fs");

    glm::mat4 projection = glm::ortho(0.0f, static_cast<float>(SCR_WIDTH), 0.0f, static_cast<float>(SCR_HEIGHT));
    shader.use();
    glUniformMatrix4fv(glGetUniformLocation(shader.ID, "projection"), 1, GL_FALSE, glm::value_ptr(projection));

    if (FT_Init_FreeType(&ft))
    {
        exit(0);
    }

    std::string font_name = "./src/opengl/fonts/" + *atrib.__font_name +  ".ttf";
    
    FT_Face face;
    if (FT_New_Face(ft, font_name.c_str(), 0, &face)) {
        VI_ERROR("ERROR::FREETYPE: Failed to load font");
        exit(0) ;
    } else {
        FT_Outline border;
        
        FT_Set_Pixel_Sizes(face, 0, atrib.__font_size);

        glPixelStorei(GL_UNPACK_ALIGNMENT, 1);

        for (unsigned char c = 0; c < 128; c++)
        {
            // Load character glyph 
            if (FT_Load_Char(face, c, FT_LOAD_RENDER))
            {
                VI_ERROR("ERROR::FREETYTPE: Failed to load Glyph");
                continue;
            }

            // generate texture
            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
            );
            // set texture options
            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);
            // now store character for later use
            Character character = {
                texture,
                glm::ivec2(face->glyph->bitmap.width, face->glyph->bitmap.rows),
                glm::ivec2(face->glyph->bitmap_left, face->glyph->bitmap_top),
                static_cast<unsigned int>(face->glyph->advance.x)
            };
            Characters.insert(std::pair<char, Character>(c, character));
        }
        glBindTexture(GL_TEXTURE_2D, 0);
    }
    FT_Done_Face(face);
    FT_Done_FreeType(ft);

    glGenVertexArrays(1, &VAO);
    glGenBuffers(1, &VBO);
    glBindVertexArray(VAO);
    glBindBuffer(GL_ARRAY_BUFFER, VBO);
    glBufferData(GL_ARRAY_BUFFER, sizeof(float) * 6 * 4, NULL, GL_DYNAMIC_DRAW);
    glEnableVertexAttribArray(0);
    glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 4 * sizeof(float), 0);
    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glBindVertexArray(0);
}
void Text::render_text(std::string text, float x, float y, float z, std::string hex_color, float angle_rad, bool bg)
{   
    static const int scale = 1;

    shader.use();
    glUniform3f(glGetUniformLocation(shader.ID, "textColor"), 0.1, 0.1, 0.1);//color.get_color_float(Utils::RED), color.get_color_float(Utils::GREEN), color.get_color_float(Utils::BLUE));
    glActiveTexture(GL_TEXTURE0);
    glBindVertexArray(VAO);

    GLfloat vertices[6][4] = {
        { 0.0,  1.0,   0.0, 0.0 },
        { 0.0,  0.0,   0.0, 1.0 },
        { 1.0,  0.0,   1.0, 1.0 },

        { 0.0,  1.0,   0.0, 0.0 },
        { 1.0,  0.0,   1.0, 1.0 },
        { 1.0,  1.0,   1.0, 0.0 }
    };

    glBindBuffer(GL_ARRAY_BUFFER, VBO);
    glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vertices), vertices); // Be sure to use glBufferSubData and not glBufferData
    glBindBuffer(GL_ARRAY_BUFFER, 0);


    glm::mat4 rotateM = glm::rotate(glm::mat4(1.0f), glm::radians(angle_rad), glm::vec3(0.0f, 0.0f, 1.0f));
    glm::mat4 transOriginM = glm::translate(glm::mat4(1.0f), glm::vec3(x, y, z));

    std::string::const_iterator c;
    GLfloat char_x = 0.0f;
    for (c = text.begin(); c != text.end(); c++)
    {
        Character ch = Characters[*c];

        GLfloat w = ch.Size.x * scale;
        GLfloat h = ch.Size.y * scale;
        GLfloat xrel = char_x + ch.Bearing.x * scale;
        GLfloat yrel = y - (ch.Size.y - ch.Bearing.y) * scale;

        char_x += (ch.Advance >> 6) * scale; // Bitshift by 6 to get value in pixels (2^6 = 64 (divide amount of 1/64th pixels by 64 to get amount of pixels))

        glm::mat4 scaleM = glm::scale(glm::mat4(1.0f), glm::vec3(w, h, 1.0f));
        glm::mat4 transRelM = glm::translate(glm::mat4(1.0f), glm::vec3(xrel, yrel, z));

        glm::mat4 modelM = transOriginM * rotateM * transRelM * scaleM;

        GLint model_loc = glGetUniformLocation(shader.ID, "model");
        glUniformMatrix4fv(model_loc, 1, GL_FALSE, glm::value_ptr(modelM));

        glBindTexture(GL_TEXTURE_2D, ch.TextureID);

        glDrawArrays(GL_TRIANGLES, 0, 6);
    }
    glBindVertexArray(0);
    glBindTexture(GL_TEXTURE_2D, 0);
}

文本.h

extern "C"{
    #include <ft2build.h>
    #include FT_FREETYPE_H
}

class Text{
   Text(text_attributes&& atrib, int w, int h);
   render_text(std::string text, float x, float y, float z, std::string hex_color, float angle_rad, bool bg);
};

您還應該包括:

#include FT_GLYPH_H   //optional glyph management component
#include FT_OUTLINE_H //scalable outline management
#include FT_STROKER_H //functions to stroke outline paths

也可以看看:


如果要渲染輪廓(按指定順序):

  • FT_Stroker_New
  • FT_Stroker_Set
  • FT_Get_Glyph
  • FT_Glyph_Stroke
  • 如果字形->格式 == FT_GLYPH_FORMAT_OUTLINE
    • FT_Raster_Params 參數
      • params.flags = FT_RASTER_FLAG_AA | FT_RASTER_FLAG_DIRECT
      • params.gray_spans = outlineRenderCallback
      • params.user = user_data
    • FT_Outline_Render

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM