Programmeerhandleiding voor DDS
Direct3D implementeert de DDS-bestandsindeling voor het opslaan van niet-gecomprimeerde of gecomprimeerde (DXTn)-patronen. De bestandsindeling implementeert verschillende enigszins verschillende typen die zijn ontworpen voor het opslaan van verschillende typen gegevens en ondersteunt patronen met één laag, patronen met mipmaps, kubuskaarten, volumetoewijzingen en bitmapmatrices (in Direct3D 10/11). In deze sectie wordt de indeling van een DDS-bestand beschreven.
Zie How to: Create a Texturevoor hulp bij het maken van een bitmappatroon in Direct3D 11. Zie Texture Support in D3DX (Direct3D 9)voor hulp bij Direct3D 9.
- DDS-bestandsindeling
- DDS-varianten
- Patroonmatrices gebruiken in Direct3D 10/11
- algemene DDS-bestandsindelingen en bijbehorende headerinhoud
- Verwante onderwerpen
DDS-bestandsindeling
Een DDS-bestand is een binair bestand dat de volgende informatie bevat:
Een DWORD (magic number) met de vier tekencodewaarde 'DDS' (0x20534444).
Een beschrijving van de gegevens in het bestand.
De gegevens worden beschreven met een headerbeschrijving met behulp van DDS_HEADER; de pixelindeling wordt gedefinieerd met behulp van DDS_PIXELFORMAT. Houd er rekening mee dat de DDS_HEADER- en DDS_PIXELFORMAT structuren de afgeschafte DDSURFACEDESC2, DDSCAPS2 en DD PIXELFORMAT DirectDraw 7-structuren vervangen. DDS_HEADER is het binaire equivalent van DDSURFACEDESC2 en DDSCAPS2. DDS_PIXELFORMAT is het binaire equivalent van DD PIXELFORMAT.
DWORD dwMagic; DDS_HEADER header;
Als de DDS_PIXELFORMAT dwFlags is ingesteld op DDPF_FOURCC en dwFourCC is ingesteld op DX10, is er een extra DDS_HEADER_DXT10 structuur aanwezig om patronenmatrices of DXGI-indelingen aan te bieden die niet kunnen worden uitgedrukt als een RGB-pixelindeling, zoals drijvendekomma-indelingen, sRGB-indelingen, enzovoort. Wanneer de DDS_HEADER_DXT10 structuur aanwezig is, ziet de volledige gegevensbeschrijving er als volgt uit.
DWORD dwMagic; DDS_HEADER header; DDS_HEADER_DXT10 header10;
Een aanwijzer naar een matrix van bytes die de hoofdoppervlakgegevens bevat.
BYTE bdata[]
Een aanwijzer naar een matrix van bytes die de resterende oppervlakken bevat, zoals; mipmapniveaus, gezichten in een kubuskaart, diepten in een volumepatroon. Volg deze koppelingen voor meer informatie over de indeling van het DDS-bestand voor een: patroon, een kubuskaartof een volumepatroon.
BYTE bdata2[]
Voor brede hardwareondersteuning raden we u aan de DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, DXGI_FORMAT_R8G8B8A8_SNORM, DXGI_FORMAT_B8G8R8A8_UNORM, DXGI_FORMAT_R16G16_SNORM, DXGI_FORMAT_R8G8_SNORMte gebruiken , 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_UNORMof DXGI_FORMAT_BC3_UNORM_SRGB indeling.
Zie Bitmapblokcompressie in Direct3D 11 en Blokcompressie blokkeren (Direct3D 10)voor meer informatie over gecomprimeerde structuurindelingen.
De D3DX-bibliotheek (bijvoorbeeld D3DX11.lib) en andere vergelijkbare bibliotheken bieden de pitchwaarde in de dwPitchOrLinearSize lid van de DDS_HEADER structuur. Daarom raden we u aan de pitch te berekenen wanneer u DDS-bestanden leest en schrijft op een van de volgende manieren voor de aangegeven indelingen:
Voor blok-gecomprimeerde indelingen berekent u de pitch als:
max( 1, ((width+3)/4) * blokgrootte
De blokgrootte is 8 bytes voor DXT1-, BC1- en BC4-indelingen en 16 bytes voor andere blok-gecomprimeerde indelingen.
Voor R8G8_B8G8, G8R8_G8B8, verouderde UYVY-verpakte en verouderde YUY2-indelingen, berekent u de pitch als:
((breedte+1) >> 1) * 4
Voor andere indelingen berekent u de pitch als:
( breedte * bits per pixel + 7 ) / 8
U deelt door 8 voor byte-uitlijning.
Notitie
De pitchwaarde die u berekent, is niet altijd gelijk aan de pitch die door de runtime wordt geleverd. Dit is DWORD-uitgelijnd in sommige situaties en byte-uitgelijnd in andere situaties. Daarom raden we u aan om een scanregel tegelijk te kopiëren in plaats van de hele afbeelding in één kopie te kopiëren.
DDS-varianten
Er zijn veel hulpprogramma's die DDS-bestanden maken en gebruiken, maar ze kunnen variëren in de details van wat ze nodig hebben in de header. Schrijvers moeten de headers zo volledig mogelijk vullen en lezers moeten de minimale waarden voor maximale compatibiliteit controleren. Als u een DDS-bestand wilt valideren, moet een lezer ervoor zorgen dat het bestand ten minste 128 bytes lang is voor de magic-waarde en de basisheader. De magic-waarde is 0x20534444 ("DDS"), de DDS_HEADER grootte is 124 en de DDS_PIXELFORMAT in de koptekstgrootte is 32. Als de DDS_PIXELFORMAT dwFlags is ingesteld op DDPF_FOURCC en een dwFourCC is ingesteld op 'DX10', moet de totale bestandsgrootte ten minste 148 bytes zijn.
Er zijn enkele veelvoorkomende varianten in gebruik waarbij de pixelindeling is ingesteld op een DDPF_FOURCC code waarbij dwFourCC is ingesteld op een D3DFORMAT of DXGI_FORMAT opsommingswaarde. Er is geen manier om te zien of een opsommingswaarde een D3DFORMAT of een DXGI_FORMAT is, dus het wordt ten zeerste aanbevolen dat de extensie DX10 en DDS_HEADER_DXT10 header worden gebruikt om de dxgiFormat op te slaan wanneer de basis-DDS_PIXELFORMAT de indeling niet kan uitdrukken.
De standaard DDS_PIXELFORMAT moet de voorkeur hebben voor maximale compatibiliteit om RGB-niet-gecomprimeerde gegevens en DXT1-5-gegevens op te slaan, omdat niet alle DDS-hulpprogramma's de DX10-extensie ondersteunen.
Bitmapmatrices gebruiken in Direct3D 10/11
De nieuwe DDS-structuren (DDS_HEADER en DDS_HEADER_DXT10) in Direct3D 10/11 breiden de DDS-bestandsindeling uit om een matrix van patronen te ondersteunen. Dit is een nieuw resourcetype in Direct3D 10/11. Hier volgt een voorbeeldcode die laat zien hoe u toegang krijgt tot de verschillende mipmapniveaus in een matrix met patronen, met behulp van de nieuwe headers.
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++)
{
...
}
}
Algemene DDS-bestandsindelingen en bijbehorende headerinhoud
Resource-indeling | 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 |
Resource-indeling | 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 |
Elke DXGI-indeling | DDS_FOURCC | "DX10" |
* = Een robuuste DDS-lezer moet deze verouderde notatiecodes kunnen verwerken. Een dergelijke DDS-lezer moet echter liever de headerextensie DX10 gebruiken wanneer deze notatiecodes worden geschreven om dubbelzinnigheid te voorkomen.
** = Vanwege een aantal langdurige problemen in veelvoorkomende implementaties van DDS-lezers en schrijvers is de meest robuuste manier om 10:10:10:2-type gegevens te schrijven de headerextensie DX10 te gebruiken met de DXGI_FORMAT code '24' (dat wil gezegd de DXGI_FORMAT_R10G10B10A2_UNORM waarde). D3DFMT_A2R10G10B10 gegevens moeten worden geconverteerd naar 10:10:10:2-type gegevens voordat ze worden weggeschreven als een DDS-bestand met DXGI_FORMAT_R10G10B10A2_UNORM-indeling.