c++ - DirectX 11 和 FreeType

标签 c++ directx freetype

有人曾经将 FreeType 与 DirectX 11 集成用于字体渲染吗?我似乎找到的唯一文章是 DirectX 11 Font Rendering 。我似乎无法匹配正确的 DXGI_FORMAT 来渲染 FreeType 为字形创建的灰度位图。

最佳答案

Direct3D 11 中有三种处理灰度纹理的方法:

选项 (1):您可以使用 RGB 格式并复制 channel 。例如,您可以使用 DXGI_R8G8B8A8_UNORM并将 R、G、B 设置为单个单色 channel ,将 A 设置为全部不透明 (0xFF)。您可以以相同的方式处理 Monochrome + Alpha(2 channel )数据。

This conversion is supported when loading .DDS luminance formats (D3DFMT_L8, D3DFMT_L8A8) by DirectXTex library and the texconv command-line tool with the -xlum switch.

这使得纹理在内存中的大小增加了 4 倍,但可以使用标准着色器轻松集成。

选项 (2):使用 DXGI_FORMAT_R8_UNORM 将单色纹理保留为单个 channel 作为你的格式。然后,您可以使用自定义着色器进行渲染,该着色器在运行时将红色 channel 复制到 RGB。

这实际上就是您链接到的教程博客文章正在做的事情:

///////// PIXEL SHADER
float4 main(float2 uv : TEXCOORD0) : SV_Target0
{
    return float4(Decal.Sample(Bilinear, uv).rrr, 1.f);
}

对于单色 + Alpha(2 channel ),您可以使用 DXGI_FORMAT_R8G8_UNORM然后你的自定义着色器将使用 .rrrg作为调酒。

选项 (3):您可以将单色数据压缩到 DXGI_FORMAT_BC2使用自定义编码器格式化。这是在 DirectX Tool Kit 中实现的的MakeSpriteFont使用时的工具/TextureFormat:CompressedMono

// CompressBlock (16 pixels (4x4 block) stored as 16 bytes)
long alphaBits = 0; 
int rgbBits = 0; 

int pixelCount = 0;

for (int y = 0; y < 4; y++) 
{ 
    for (int x = 0; x < 4; x++) 
    { 
        long alpha; 
        int rgb; 

        // This is the single monochrome channel
        int value = bitmapData[blockX + x, blockY + y];

        if (options.NoPremultiply) 
        { 
            // If we are not premultiplied, RGB is always white and we have 4 bit alpha. 
            alpha = value >> 4; 
            rgb = 0; 
        } 
        else 
        { 
            // For premultiplied encoding, quantize the source value to 2 bit precision. 
            if (value < 256 / 6) 
            { 
                alpha = 0; 
                rgb = 1; 
            } 
            else if (value < 256 / 2) 
            { 
                alpha = 5; 
                rgb = 3; 
            } 
            else if (value < 256 * 5 / 6) 
            { 
                alpha = 10; 
                rgb = 2; 
            } 
            else 
            { 
                alpha = 15; 
                rgb = 0; 
            } 
        } 

        // Add this pixel to the alpha and RGB bit masks. 
        alphaBits |= alpha << (pixelCount * 4); 
        rgbBits |= rgb << (pixelCount * 2); 

        pixelCount++;
    } 
} 

// The resulting BC2 block is:
// uint64_t = alphaBits
// uint16_t = 0xFFFF
// uint16_t = 0x0
// uint32_t = rgbBits

然后使用标准 alpha 混合着色器渲染生成的纹理。由于它每个像素使用 1 个字节,因此这实际上与使用 DXGI_FORMAT_R8_UNORM 的大小相同。 .

此技术不适用于 2 channel 数据,但对于字体字形等 alpha 混合单色图像非常有效。

关于c++ - DirectX 11 和 FreeType,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33129524/

相关文章:

安卓NDK : keeping alive C++ objects

c++ - 如何为 C++ 创建命令行模拟器 GUI

c++ - 将 QString 从父 QT 传递给子 QT

c++ - 按键时发送输出

opengl - unity3d,多个渲染目标 - Direct3D/OpenGl 中的不同行为

c++ - DirectX 绘制顶点数组,不绘制顶点 vector

opengl - 文本未正确渲染 - 使用 FreeType2 的 OpenGL

c++ - 在自定义文本区域中呈现光标的正确方法?

c# - 如何用三角形覆盖多边形

c++ - 使用 FreeType 加载彩色字体