【问题标题】:Convert FreeType GlyphSlot Bitmap To Vulkan BGRA将 FreeType GlyphSlot 位图转换为 Vulkan BGRA
【发布时间】:2019-11-16 19:50:35
【问题描述】:

我正在尝试将 FreeType GlyphSlot 位图转换为 Vulkan BGRA 格式。

void DrawText(const std::string &text) {
    //  WIDTH & HEIGHT == dst image dimensions
    FT_GlyphSlot Slot = face->glyph;
    buffer.resize(WIDTH*HEIGHT*4);

    int dst_Pitch = WIDTH * 4;

    for (auto c : text) {
        FT_Error error = FT_Load_Char(face, c, FT_LOAD_RENDER);
        if (error) {
            printf("FreeType: Load Char Error\n");
            continue;
        }

        auto char_width = Slot->bitmap.width;
        auto char_height = Slot->bitmap.rows;

        uint8_t* src = Slot->bitmap.buffer;
        uint8_t* startOfLine = src;

        for (int y = 0; y < char_height; ++y) {
            src = startOfLine;
            for (int x = 0; x < char_width; ++x) {

                //  y * dst_Pitch   == Destination Image Row
                //  x * 4           == Destination Image Column
                int dst = (y*dst_Pitch) + (x*4);

                //  Break if we have no more space to draw on our
                //  destination texture.
                if (dst + 4 > buffer.size()) { break; }

                auto value = *src;
                src++;

                buffer[dst]     = 0xff;     // +0 == B
                buffer[dst+1]   = 0xff;     // +1 == G
                buffer[dst+2]   = 0xff;     // +2 == R
                buffer[dst+3]   = value;    // +3 == A
            }
            startOfLine += Slot->bitmap.pitch;
        }
    }
}

这给了我乱码的输出。我不确定我需要做什么才能正确转换为 Vulkan B8G8R8A8。我觉得在我们写入 Vulkan 纹理的缓冲区中从左到右移动是不正确的,也许 Vulkan 期望我以不同的方式将像素添加到缓冲区中?

我知道这段代码会把每个字母都写在另一个上面,在我可以正确绘制至少一个字母之后,我将实施利用Slot-&gt;advance

【问题讨论】:

    标签: c++ data-conversion vulkan freetype2


    【解决方案1】:

    一个问题是你用每个字符调整buffer的大小(这会将以前的数据留在新分配空间的开头)但是当存储新字符c的数据时,你会覆盖缓冲区的开头因为dst 为0。您可能希望在resize 调用之前设置dst buffer.size()

    int dst = /*previous buffer size*/;
    

    【讨论】:

    • 我没有注意到,谢谢。我仍然收到关于最终纹理的乱码输出。我相信这是因为我的应用程序需要 B8G8R8A8 格式的数据,或者我填充到缓冲区的数据只是垃圾。
    【解决方案2】:

    问题是因为我将VkImageCreateInfo tiling 设置为VK_IMAGE_TILING_OPTIMAL。将其更改为VK_IMAGE_TILING_LINEAR 后,我收到了正确的输出。

    直接取自https://www.khronos.org/registry/vulkan/specs/1.1-extensions/man/html/VkImageTiling.html

    VK_IMAGE_TILING_OPTIMAL 指定最佳平铺(纹素布局 在依赖于实现的安排中,以获得更优的内存 访问)。

    VK_IMAGE_TILING_LINEAR 指定线性平铺(纹素在 内存按行优先顺序,每行可能有一些填充)。

    虽然我现在可能不会渲染垃圾,但我的字母仍然是向后的,并且似乎是从右到左而不是从左到右绘制。 您可以在右上角看到绿色的“the”。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-09-04
      • 1970-01-01
      • 2022-01-12
      • 2020-10-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多