Guide de programmation pour DDS

Direct3D implémente le format de fichier DDS pour stocker des textures non compressées ou compressées (DXTn). Le format de fichier implémente plusieurs types légèrement différents conçus pour stocker différents types de données et prend en charge les textures à couche unique, les textures avec mipmaps, les mappages de cube, les mappages de volumes et les tableaux de textures (dans Direct3D 10/11). Cette section décrit la disposition d’un fichier DDS.

Pour obtenir de l’aide sur la création d’une texture dans Direct3D 11, consultez Guide pratique pour créer une texture. Pour obtenir de l’aide sur Direct3D 9, consultez Prise en charge des textures dans D3DX (Direct3D 9).

Disposition du fichier DDS

Un fichier DDS est un fichier binaire qui contient les informations suivantes :

  • Un DWORD (nombre magique) contenant la valeur codée des quatre caractères "DDS " (0x20534444).

  • Une description des données du fichier.

    Les données sont décrites avec une description d’en-tête à l’aide de DDS_HEADER ; le format de pixel est défini à l’aide de DDS_PIXELFORMAT. Notez que les structures DDS_HEADER et DDS_PIXELFORMAT remplacent les structures DDSURFACEDESC2, DDSCAPS2 et DDPIXELFORMAT DirectDraw 7 dépréciées. DDS_HEADER est l’équivalent binaire de DDSURFACEDESC2 et DDSCAPS2. DDS_PIXELFORMAT est l’équivalent binaire de DDPIXELFORMAT.

    DWORD               dwMagic;
    DDS_HEADER          header;
    
    

    Si le DDS_PIXELFORMAT dwFlags est défini sur DDPF_FOURCC et que dwFourCC est défini sur « DX10 », une structure de DDS_HEADER_DXT10 supplémentaire est présente pour prendre en charge les tableaux de textures ou les formats DXGI qui ne peuvent pas être exprimés sous la forme d’un format de pixel RVB tel que des formats à virgule flottante, des formats sRGB, etc. Lorsque la structure DDS_HEADER_DXT10 est présente, la description complète des données ressemble à ceci.

    DWORD               dwMagic;
    DDS_HEADER          header;
    DDS_HEADER_DXT10    header10;
    
  • Pointeur vers un tableau d’octets qui contient les principales données de surface.

    BYTE bdata[]
    
  • Pointeur vers un tableau d’octets qui contient les surfaces restantes telles que niveaux de mipmap, faces dans un plan de cube, profondeurs dans une texture de volume. Suivez ces liens pour plus d’informations sur le schéma du fichier DDS pour une texture, un mappage de cube ou une texture de volume.

    BYTE bdata2[]
    

Pour une prise en charge matérielle étendue, nous vous recommandons d’utiliser les DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, DXGI_FORMAT_R8G8B8A8_SNORM, DXGI_FORMAT_B8G8R8A8_UNORM, DXGI_FORMAT_R16G16_SNORM, DXGI_FORMAT_R8G8_SNORM, DXGI_FORMAT_R8_UNORM, DXGI_FORMAT_BC1_UNORM, DXGI_FORMAT_BC1_UNORM_SRGB, DXGI_FORMAT_BC2_UNORM, DXGI_FORMAT_BC2_UNORM_SRGB, DXGI_FORMAT_BC3_UNORM ou format DXGI_FORMAT_BC3_UNORM_SRGB.

Pour plus d’informations sur les formats de texture compressés, consultez Compression de blocs de texture dans Direct3D 11 et Compression de blocs (Direct3D 10).

La bibliothèque D3DX (par exemple, D3DX11.lib) et d’autres bibliothèques similaires fournissent de manière non ou incohérente la valeur pitch dans le membre dwPitchOrLinearSize de la structure DDS_HEADER . Par conséquent, lorsque vous lisez et écrivez dans des fichiers DDS, nous vous recommandons de calculer le pitch de l’une des manières suivantes pour les formats indiqués :

  • Pour les formats compressés par bloc, calculez le pitch comme suit :

    max( 1, ((width+3)/4) ) * block-size

    La taille du bloc est de 8 octets pour les formats DXT1, BC1 et BC4, et de 16 octets pour les autres formats compressés par bloc.

  • Pour R8G8_B8G8, G8R8_G8B8, les formats uYVY hérités et les formats yuY2-pack hérités, calculez le pitch comme suit :

    ((width+1) >> 1) * 4

  • Pour les autres formats, calculez le pitch comme suit :

    ( width * bits-per-pixel + 7 ) / 8

    Vous divisez par 8 pour l’alignement d’octets.

Notes

La valeur de pitch que vous calculez n’est pas toujours égale à celle que fournit le runtime, qui est alignée sur DWORD dans certaines situations et sur les octets dans d’autres situations. Par conséquent, nous vous recommandons de copier une ligne de balayage à la fois plutôt que d’essayer de copier l’image entière en une seule copie.

Variantes DDS

Il existe de nombreux outils qui créent et consomment des fichiers DDS, mais ils peuvent varier dans les détails de ce dont ils ont besoin dans l’en-tête. Les rédacteurs doivent remplir les en-têtes aussi complètement que possible, et les lecteurs doivent case activée les valeurs minimales pour une compatibilité maximale. Pour valider un fichier DDS, un lecteur doit s’assurer que le fichier est d’au moins 128 octets pour tenir compte de la valeur magique et de l’en-tête de base, que la valeur magique est 0x20534444 (« DDS »), que la taille du DDS_HEADER est 124 et que la DDS_PIXELFORMAT dans la taille d’en-tête est 32. Si le DDS_PIXELFORMAT dwFlags est défini sur DDPF_FOURCC et qu’un dwFourCC est défini sur « DX10 », la taille totale du fichier doit être d’au moins 148 octets.

Il existe quelques variantes courantes dans lesquelles le format de pixel est défini sur un code DDPF_FOURCC où dwFourCC est défini sur une valeur d’énumération D3DFORMAT ou DXGI_FORMAT. Il n’existe aucun moyen de savoir si une valeur d’énumération est un D3DFORMAT ou un DXGI_FORMAT. Il est donc fortement recommandé d’utiliser l’extension « DX10 » et l’en-tête DDS_HEADER_DXT10 pour stocker le dxgiFormat lorsque le DDS_PIXELFORMAT de base ne peut pas exprimer le format.

Le DDS_PIXELFORMAT standard doit être préféré pour une compatibilité maximale afin de stocker les données RVB non compressées et les données DXT1-5, car tous les outils DDS ne prennent pas en charge l’extension DX10.

Utilisation de tableaux de textures dans Direct3D 10/11

Les nouvelles structures DDS (DDS_HEADER et DDS_HEADER_DXT10) dans Direct3D 10/11 étendent le format de fichier DDS pour prendre en charge un tableau de textures, qui est un nouveau type de ressource dans Direct3D 10/11. Voici un exemple de code qui montre comment accéder aux différents niveaux mipmap dans un tableau de textures, à l’aide des nouveaux en-têtes.

DWORD               dwMagic;
DDS_HEADER          header;
DDS_HEADER_DXT10    header10;
   
for (int iArrayElement = 0; iArrayElement < header10.arraySize; iArrayElement++)
{
   for (int iMipLevel = 0; iMipLevel < header.dwMipMapCount; iMipLevel++)
   {
     ...
   }
}       

Formats de ressources de fichier DDS courants et contenu d’en-tête associé

Format de ressource dwFlags dwRGBBitCount dwRBitMask dwGBitMask dwBBitMask dwABitMask
DXGI_FORMAT_R8G8B8A8_UNORM
D3DFMT_A8B8G8R8
DDS_RGBA 32 0xff 0xff00 0xff0000 0xff000000
DXGI_FORMAT_R16G16_UNORM
D3DFMT_G16R16
DDS_RGBA 32 0xffff 0xffff0000
**
DXGI_FORMAT_R10G10B10A2_UNORM
D3DFMT_A2B10G10R10
DDS_RGBA 32 0x3ff 0xffc00 0x3ff00000
DXGI_FORMAT_R16G16_UNORM
D3DFMT_G16R16
DDS_RGB 32 0xffff 0xffff0000
DXGI_FORMAT_B5G5R5A1_UNORM
D3DFMT_A1R5G5B5
DDS_RGBA 16 0x7c00 0x3e0 0x1f 0x8000
DXGI_FORMAT_B5G6R5_UNORM
D3FMT_R5G6B5
DDS_RGB 16 0xf800 0x7e0 0x1f
DXGI_A8_UNORM
D3DFMT_A8
DDS_ALPHA 8 0xff
D3DFMT_A8R8G8B8
DDS_RGBA 32 0xff0000 0xff00 0xff 0xff000000
D3DFMT_X8R8G8B8
DDS_RGB 32 0xff0000 0xff00 0xff
D3DFMT_X8B8G8R8
DDS_RGB 32 0xff 0xff00 0xff0000
**
D3DFMT_A2R10G10B10
DDS_RGBA 32 0x3ff00000 0xffc00 0x3ff 0xc0000000
D3DFMT_R8G8B8
DDS_RGB 24 0xff0000 0xff00 0xff
D3DFMT_X1R5G5B5
DDS_RGB 16 0x7c00 0x3e0 0x1f
D3DFMT_A4R4G4B4
DDS_RGBA 16 0xf00 0xf0 0xf 0xf000
D3DFMT_X4R4G4B4
DDS_RGB 16 0xf00 0xf0 0xf
D3DFMT_A8R3G3B2
DDS_RGBA 16 0xe0 0x1c 0x3 0xff00
D3DFMT_A8L8
DDS_LUMINANCE 16 0xff 0xff00
D3DFMT_L16
DDS_LUMINANCE 16 0xffff
D3DFMT_L8
DDS_LUMINANCE 8 0xff
D3DFMT_A4L4
DDS_LUMINANCE 8 0xf 0xf0
Format de ressource dwFlags dwFourCC
DXGI_FORMAT_BC1_UNORM
D3DFMT_DXT1
DDS_FOURCC « DXT1 »
DXGI_FORMAT_BC2_UNORM
D3DFMT_DXT3
DDS_FOURCC « DXT3 »
DXGI_FORMAT_BC3_UNORM
D3DFMT_DXT5
DDS_FOURCC « DXT5 »
*
DXGI_FORMAT_BC4_UNORM
DDS_FOURCC « BC4U »
*
DXGI_FORMAT_BC4_SNORM
DDS_FOURCC « BC4S »
*
DXGI_FORMAT_BC5_UNORM
DDS_FOURCC « ATI2 »
*
DXGI_FORMAT_BC5_SNORM
DDS_FOURCC « BC5S »
DXGI_FORMAT_R8G8_B8G8_UNORM
D3DFMT_R8G8_B8G8
DDS_FOURCC « RGBG »
DXGI_FORMAT_G8R8_G8B8_UNORM
D3DFMT_G8R8_G8B8
DDS_FOURCC « GRGB »
*
DXGI_FORMAT_R16G16B16A16_UNORM
D3DFMT_A16B16G16R16
DDS_FOURCC 36
*
DXGI_FORMAT_R16G16B16A16_SNORM
D3DFMT_Q16W16V16U16
DDS_FOURCC 110
*
DXGI_FORMAT_R16_FLOAT
D3DFMT_R16F
DDS_FOURCC 111
*
DXGI_FORMAT_R16G16_FLOAT
D3DFMT_G16R16F
DDS_FOURCC 112
*
DXGI_FORMAT_R16G16B16A16_FLOAT
D3DFMT_A16B16G16R16F
DDS_FOURCC 113
*
DXGI_FORMAT_R32_FLOAT
D3DFMT_R32F
DDS_FOURCC 114
*
DXGI_FORMAT_R32G32_FLOAT
D3DFMT_G32R32F
DDS_FOURCC 115
*
DXGI_FORMAT_R32G32B32A32_FLOAT
D3DFMT_A32B32G32R32F
DDS_FOURCC 116
D3DFMT_DXT2
DDS_FOURCC « DXT2 »
D3DFMT_DXT4
DDS_FOURCC « DXT4 »
D3DFMT_UYVY
DDS_FOURCC « UYVY »
D3DFMT_YUY2
DDS_FOURCC « YUY2 »
D3DFMT_CxV8U8
DDS_FOURCC 117
Tout format DXGI DDS_FOURCC « DX10 »

* = Un lecteur DDS robuste doit être en mesure de gérer ces codes de format hérités. Toutefois, un tel lecteur DDS doit préférer utiliser l’extension d’en-tête « DX10 » lorsqu’il écrit ces codes de format pour éviter toute ambiguïté.

** = En raison de certains problèmes de longue date dans les implémentations courantes des lecteurs et des enregistreurs DDS, la méthode la plus robuste pour écrire des données de type 10:10:10:2 consiste à utiliser l’extension d’en-tête « DX10 » avec le code DXGI_FORMAT « 24 » (autrement dit, la valeur DXGI_FORMAT_R10G10B10A2_UNORM). D3DFMT_A2R10G10B10 données doivent être converties en données de type 10:10:10:2 avant d’être écrites en tant que fichier DDS au format DXGI_FORMAT_R10G10B10A2_UNORM.

DDS