2015-10-14 3 views
0

Кто-нибудь когда-либо интегрировал FreeType с DirectX 11 для рендеринга шрифтов? Единственная статья, которую я, кажется, нахожу, - DirectX 11 Font Rendering. Кажется, я не могу соответствовать правильному DXGI_FORMAT для рендеринга растрового изображения в градациях серого, которое создает FreeType для глифа.DirectX 11 и FreeType

ответ

2

Там три способа обработки полутоновых текстур в Direct3D 11:

Вариант (1): Вы можете использовать формат RGB и тиражирования каналы. Например, вы должны использовать DXGI_R8G8B8A8_UNORM и установить R, G, B на один монохромный канал и A на все непрозрачные (0xFF). Вы можете обрабатывать монохромные + альфа-данные (2 канала) таким же образом.

Это преобразование поддерживается при загрузке .DDS форматов яркости (D3DFMT_L8, D3DFMT_L8A8) от DirectXTex библиотеки и инструмент texconv командной строки с помощью переключателя -xlum.

Это делает текстуру в 4 раза большей в памяти, но легко интегрируется с использованием стандартных шейдеров.

Вариант (2): Вы сохраняете монохромную текстуру как один канал, используя DXGI_FORMAT_R8_UNORM в качестве своего формата. Затем вы выполняете визуализацию с использованием пользовательского шейдера, который реплицирует красный канал в RGB во время выполнения.

Это на самом деле то, что учебник блоге вы связаны делает:

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

Для монохромного + Alpha (2-канальный) вы будете использовать DXGI_FORMAT_R8G8_UNORM, а затем пользовательский шейдер будет использовать .rrrg как Swizzle.

Вариант (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 

Полученная текстура затем визуализируется с использованием стандартного альфа-смешивания шейдер. Поскольку он использует 1 байт на пиксель, это фактически тот же размер, как если бы вы использовали DXGI_FORMAT_R8_UNORM.

Этот метод не работает для двухканальных данных, но отлично подходит для монохромных изображений с альфа-смешением, таких как шрифтовые глифы.

+0

Спасибо за подробное объяснение Чак! Вариант № 2 больше связан с тем, что мне нужно. Я думал, что DXGI_FORMAT_R8_UNORM был правильным, но не был уверен. Мне также нужно было немного обновить свой пиксельный шейдер, чтобы правильно перескакивать через RGB. –