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
- Variantes DDS
- Utilisation de tableaux de textures dans Direct3D 10/11
- Formats de ressources de fichier DDS courants et contenu d’en-tête associé
- Rubriques connexes
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.