2015-10-14 1 views
0

Est-ce que quelqu'un a déjà intégré FreeType avec DirectX 11 pour le rendu des polices? Le seul article que je semble trouver est DirectX 11 Font Rendering. Je ne peux pas sembler correspondre le DXGI_FORMAT correct pour rendre le bitmap en niveaux de gris que FreeType crée pour un glyphe.DirectX 11 et FreeType

Répondre

2

Il y a trois façons de gérer les textures Direct3D 11 niveaux de gris:

Option (1): Vous pouvez utiliser un format RVB et reproduire les canaux. Par exemple, vous utiliseriez DXGI_R8G8B8A8_UNORM et définissez R, G, B sur le canal monochrome unique et le A sur tout opaque (0xFF). Vous pouvez gérer les données Monochrome + Alpha (2 canaux) de la même manière.

Cette conversion est supportée lors du chargement .DDS formats de luminance (D3DFMT_L8, D3DFMT_L8A8) par DirectXTex bibliothèque et l'outil de ligne de commande texconv avec le commutateur -xlum.

Cela rend la texture jusqu'à 4 fois plus grande en mémoire, mais s'intègre facilement en utilisant des shaders standards.

Option (2): Vous conservez la texture monochrome comme un seul canal en utilisant DXGI_FORMAT_R8_UNORM comme format. Vous effectuez ensuite le rendu à l'aide d'un shader personnalisé qui réplique le canal rouge en RVB au moment de l'exécution.

C'est en fait ce que le billet de blog tutoriel vous lié à fait:

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

Noir & Blanc + Alpha (2 canaux) vous utiliseriez DXGI_FORMAT_R8G8_UNORM et shader personnalisé utiliseriez .rrrg comme swizzle.

Option (3): Vous pouvez compresser les données monochromes au format DXGI_FORMAT_BC2 à l'aide d'un codeur personnalisé. Ceci est mis en œuvre dans l'outil de MakeSpriteFontDirectX Tool Kit lors de l'utilisation /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 

La texture obtenue est ensuite rendue en utilisant une norme shader alpha-mélange. Comme il utilise 1 octet par pixel, c'est effectivement la même taille que si vous utilisiez DXGI_FORMAT_R8_UNORM.

Cette technique ne fonctionne pas pour les données 2 canaux, mais fonctionne très bien pour les images monochromes mélangées alpha comme Glyphes de police.

+0

Merci pour l'explication détaillée Chuck! L'option 2 est plus en ligne avec ce dont j'avais besoin. Je pensais que DXGI_FORMAT_R8_UNORM était le bon format, mais je n'étais pas sûr. J'avais aussi besoin de mettre à jour mon pixel shader pour qu'il passe correctement à travers RVB. –