将FreeType字形位图转换为Vulkan BGRA

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

zhaohevip 回答:将FreeType字形位图转换为Vulkan BGRA

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

int dst = /*previous buffer size*/;
,

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

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

本文链接:https://www.f2er.com/3088790.html

大家都在问