Programmierhandbuch für DDS

Direct3D implementiert das DDS-Dateiformat zum Speichern von nicht komprimierten oder komprimierten (DXTn)-Texturen. Das Dateiformat implementiert mehrere leicht unterschiedliche Typen, die zum Speichern unterschiedlicher Datentypen entwickelt wurden, und unterstützt Texturen mit einzelnen Ebenen, Texturen mit Mipmaps, Cubezuordnungen, Volumenzuordnungen und Texturarrays (in Direct3D 10/11). In diesem Abschnitt wird das Layout einer DDS-Datei beschrieben.

Hilfe zum Erstellen einer Textur in Direct3D 11 finden Sie unter Vorgehensweise: Erstellen einer Textur. Hilfe zu Direct3D 9 finden Sie unter Texturunterstützung in D3DX (Direct3D 9).

DDS-Dateilayout

Eine DDS-Datei ist eine Binärdatei mit den folgenden Informationen:

  • DWORD ("Magic Number") mit dem vierstelligen Codewert "DDS" (0x20534444)

  • Beschreibung der Daten in der Datei

    Die Daten werden mit einer Headerbeschreibung mit DDS_HEADER beschrieben. Das Pixelformat wird mithilfe von DDS_PIXELFORMAT definiert. Beachten Sie, dass die DDS_HEADER - und DDS_PIXELFORMAT strukturen die veralteten DirectDraw 7-Strukturen DDSURFACEDESC2, DDSCAPS2 und DDPIXELFORMAT ersetzen. DDS_HEADER ist das binäre Äquivalent von DDSURFACEDESC2 und DDSCAPS2. DDS_PIXELFORMAT ist die binäre Entsprechung von DDPIXELFORMAT.

    DWORD               dwMagic;
    DDS_HEADER          header;
    
    

    Wenn die DDS_PIXELFORMAT dwFlags auf DDPF_FOURCC und dwFourCC auf "DX10" festgelegt ist, wird eine zusätzliche DDS_HEADER_DXT10-Struktur vorhanden sein, um Texturarrays oder DXGI-Formate aufzunehmen, die nicht als RGB-Pixelformat wie Gleitkommaformate, sRGB-Formate usw. ausgedrückt werden können. Wenn die DDS_HEADER_DXT10-Struktur vorhanden ist, sieht die gesamte Datenbeschreibung wie folgt aus.

    DWORD               dwMagic;
    DDS_HEADER          header;
    DDS_HEADER_DXT10    header10;
    
  • Ein Zeiger auf ein Bytearray, in dem die Hauptoberflächendaten enthalten sind.

    BYTE bdata[]
    
  • Ein Zeiger auf ein Bytearray, in dem die verbleibenden Oberflächen enthalten sind, z. B. Mipmap-Ebenen, Seiten einer Würfelmap, Tiefen in einer Volumentextur. Weitere Informationen zum Layout der DDS-Datei finden Sie unter den folgenden Links: textureCubemap oder Volumentextur.

    BYTE bdata2[]
    

Für eine umfassende Hardwareunterstützung wird empfohlen, dass Sie die 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 oder DXGI_FORMAT_BC3_UNORM_SRGB Format.

Weitere Informationen zu komprimierten Texturformaten finden Sie unter Texturblockkomprimierung in Direct3D 11 und Blockkomprimierung (Direct3D 10).

Die D3DX-Bibliothek (z. B. D3DX11.lib) und andere ähnliche Bibliotheken stellen unzulässig oder inkonsistent den Tonhöhenwert im dwPitchOrLinearSize-Element der DDS_HEADER-Struktur bereit. Wenn Sie DDS-Dateien lesen und in diese schreiben, empfiehlt es sich daher, die Tonhöhe für die angegebenen Formate auf eine der folgenden Arten zu berechnen:

  • Berechnen Sie für blockkomprimierte Formate den Pitch wie:

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

    Die Blockgröße beträgt 8 Bytes für DXT1-, BC1- und BC4-Formate und 16 Bytes für andere blockkomprimierte Formate.

  • Für R8G8_B8G8, G8R8_G8B8, UYVY-gepackte Legacyformate und ältere YUY2-gepackte Formate berechnen Sie den Pitch wie:

    ((Breite+1) >> 1) * 4

  • Bei anderen Formaten berechnen Sie die Tonhöhe wie:

    ( Breite * Bits pro Pixel + 7 ) / 8

    Sie dividieren durch 8 für die Byteausrichtung.

Hinweis

Der von Ihnen berechnete Tonhöhenwert entspricht nicht immer der Von der Laufzeit bereitgestellten Tonhöhe, die in einigen Situationen DWORD-ausgerichtet und in anderen Situationen byte ausgerichtet ist. Daher wird empfohlen, eine Scanzeile gleichzeitig zu kopieren, anstatt zu versuchen, das gesamte Bild in einer Kopie zu kopieren.

DDS-Varianten

Es gibt viele Tools, die DDS-Dateien erstellen und nutzen, aber sie können in den Details der Anforderungen im Header variieren. Writer sollten die Header so vollständig wie möglich auffüllen, und Leser sollten die Minimalwerte auf maximale Kompatibilität überprüfen. Um eine DDS-Datei zu überprüfen, sollte ein Leser sicherstellen, dass die Datei mindestens 128 Bytes lang ist, um den Magic-Wert und den basic-Header aufzunehmen, der Magic-Wert ist 0x20534444 ("DDS"), die DDS_HEADER Größe 124 und die DDS_PIXELFORMAT in der Headergröße 32. Wenn die DDS_PIXELFORMAT dwFlags auf DDPF_FOURCC und dwFourCC auf "DX10" festgelegt ist, muss die Gesamtdateigröße mindestens 148 Byte betragen.

Es gibt einige gängige Varianten, bei denen das Pixelformat auf einen DDPF_FOURCC Code festgelegt ist, wobei dwFourCC auf einen D3DFORMAT- oder DXGI_FORMAT-Enumerationswert festgelegt ist. Es gibt keine Möglichkeit, zu ermitteln, ob ein Enumerationswert ein D3DFORMAT oder ein DXGI_FORMAT ist. Daher wird dringend empfohlen, stattdessen die Erweiterung "DX10" und DDS_HEADER_DXT10 Header zum Speichern des dxgiFormat zu verwenden, wenn das Format vom grundlegenden DDS_PIXELFORMAT nicht ausgedrückt werden kann.

Die Standard-DDS_PIXELFORMAT sollte für maximale Kompatibilität bevorzugt werden, um RGB-unkomprimierte Daten und DXT1-5-Daten zu speichern, da nicht alle DDS-Tools die DX10-Erweiterung unterstützen.

Verwenden von Texturarrays in Direct3D 10/11

Die neuen DDS-Strukturen (DDS_HEADER und DDS_HEADER_DXT10) in Direct3D 10/11 erweitern das DDS-Dateiformat, um ein Array von Texturen zu unterstützen, bei dem es sich um einen neuen Ressourcentyp in Direct3D 10/11 handelt. Im Folgenden finden Sie einen Beispielcode, der zeigt, wie Sie mithilfe der neuen Header auf die verschiedenen Mipmap-Ebenen in einem Array von Texturen zugreifen.

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++)
   {
     ...
   }
}       

Allgemeine DDS-Dateiressourcenformate und zugehörige Headerinhalte

Ressourcenformat 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
Ressourcenformat 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
Beliebiges DXGI-Format DDS_FOURCC "DX10"

* = Ein robuster DDS-Reader muss in der Lage sein, diese Legacyformatcodes zu verarbeiten. Ein solcher DDS-Reader sollte jedoch lieber die Headererweiterung "DX10" verwenden, wenn er diese Formatcodes schreibt, um Mehrdeutigkeiten zu vermeiden.

** = Aufgrund einiger langjähriger Probleme in gängigen Implementierungen von DDS-Readern und Writern besteht die robusteste Möglichkeit zum Schreiben von Daten vom Typ 10:10:10:2 darin, die Headererweiterung "DX10" mit dem DXGI_FORMAT Code "24" (d. a. den DXGI_FORMAT_R10G10B10A2_UNORM-Wert) zu verwenden. D3DFMT_A2R10G10B10 Daten sollten in Daten vom Typ 10:10:10:2 konvertiert werden, bevor sie als DDS-Datei im DXGI_FORMAT_R10G10B10A2_UNORM Format geschrieben werden.

DDS