将FreeType GlyphSlot位图转换为Vulkan BGRA

问题描述 投票:0回答:2

我正在尝试将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->advance来实现。

c++ data-conversion vulkan freetype2
2个回答
0
投票

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

int dst = /*previous buffer size*/;

0
投票

问题是由于我将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指定线性平铺(内存以行为主的顺序,可能在每行上都有填充)。

© www.soinside.com 2019 - 2024. All rights reserved.