Przewodnik programowania dla usługi DDS

Direct3D implementuje format pliku DDS do przechowywania nieskompresowanych lub skompresowanych tekstur (DXTn). Format pliku implementuje kilka nieco różnych typów przeznaczonych do przechowywania różnych typów danych i obsługuje tekstury pojedynczej warstwy, tekstury z mapami mip, mapami modułów, mapami woluminów i tablicami tekstur (w trybie Direct3D 10/11). W tej sekcji opisano układ pliku DDS.

Aby uzyskać pomoc dotyczącą tworzenia tekstury w wersji Direct3D 11, zobacz Instrukcje: tworzenie tekstury. Aby uzyskać pomoc w programie Direct3D 9, zobacz obsługa tekstur w D3DX (Direct3D 9).

Układ pliku DDS

Plik DDS jest plikiem binarnym zawierającym następujące informacje:

  • DWORD (liczba magiczna) zawierająca czteroznaczną wartość kodu "DDS" (0x20534444).

  • Opis danych w pliku.

    Dane są opisane za pomocą opisu nagłówka przy użyciu DDS_HEADER; format pikseli jest definiowany przy użyciu DDS_PIXELFORMAT. Należy pamiętać, że struktury DDS_HEADER i DDS_PIXELFORMAT zastępują przestarzałe struktury DDSURFACEDESC2, DDSCAPS2 i DDPIXELFORMAT DirectDraw 7. DDS_HEADER jest binarnym odpowiednikiem DDSURFACEDESC2 i DDSCAPS2. DDS_PIXELFORMAT jest binarnym odpowiednikiem formatu DDPIXELFORMAT.

    DWORD               dwMagic;
    DDS_HEADER          header;
    
    

    Jeśli DDS_PIXELFORMAT dwFlags jest ustawiona na DDPF_FOURCC i dwFourCC jest ustawiona na "DX10" dodatkowa struktura DDS_HEADER_DXT10 będzie obecna, aby pomieścić tablice tekstur lub formaty DXGI, których nie można wyrazić jako format pikseli RGB, takich jak formaty zmiennoprzecinkowe, formaty SRGB itp. Gdy struktura DDS_HEADER_DXT10 jest obecna, cały opis danych będzie wyglądać następująco.

    DWORD               dwMagic;
    DDS_HEADER          header;
    DDS_HEADER_DXT10    header10;
    
  • Wskaźnik do tablicy bajtów, która zawiera dane główne powierzchni.

    BYTE bdata[]
    
  • Wskaźnik do tablicy bajtów, która zawiera pozostałe powierzchnie, takie jak; poziomy mipmap, twarze na mapie modułu, głębokości w teksturze woluminu. Skorzystaj z poniższych linków, aby uzyskać więcej informacji na temat układu pliku DDS dla tekstury , mapy modułu lub tekstury woluminu .

    BYTE bdata2[]
    

W przypadku szerokiej obsługi sprzętu zalecamy użycie 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, format 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_UNORMlub DXGI_FORMAT_BC3_UNORM_SRGB.

Aby uzyskać więcej informacji na temat skompresowanych formatów tekstur, zobacz Texture Block Compression in Direct3D 11 and Block Compression (Direct3D 10).

Biblioteka D3DX (na przykład D3DX11.lib) i inne podobne biblioteki niewiarygodnie lub konsekwentnie zapewniają wartość skoku w dwPitchOrLinearSize składowej struktury DDS_HEADER. W związku z tym podczas odczytywania i zapisywania w plikach DDS zalecamy obliczenie skoku w jeden z następujących sposobów dla wskazanych formatów:

  • W przypadku formatów skompresowanych blokowo oblicz rzut w następujący sposób:

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

    Rozmiar bloku to 8 bajtów dla formatów DXT1, BC1 i BC4 oraz 16 bajtów dla innych formatów skompresowanych blokowo.

  • W przypadku R8G8_B8G8, G8R8_G8B8, starszych formatów UYVY i starszych formatów YUY2, oblicz boisko jako:

    ((szerokość+1) >> 1) * 4

  • W przypadku innych formatów oblicz rzut w następujący sposób:

    ( szerokość * bity na piksel + 7 ) / 8

    Dzielisz przez 8 dla wyrównania bajtów.

Nuta

Obliczona wartość skoku nie zawsze równa się wysokości, jaką dostarcza środowisko uruchomieniowe, co jest wyrównane DWORD w niektórych sytuacjach i wyrównane bajtowo w innych sytuacjach. W związku z tym zalecamy skopiowanie wiersza skanowania w danym momencie zamiast próby skopiowania całego obrazu w jednej kopii.

Warianty DDS

Istnieje wiele narzędzi, które tworzą i używają plików DDS, ale mogą się różnić w szczegółach tego, czego potrzebują w nagłówku. Autorzy powinni wypełnić nagłówki tak w pełni, jak to możliwe, a czytelnicy powinni sprawdzić minimalne wartości pod kątem maksymalnej zgodności. Aby zweryfikować plik DDS, czytelnik powinien upewnić się, że plik ma długość co najmniej 128 bajtów, aby pomieścić wartość magiczną i nagłówek podstawowy, wartość magiczna jest 0x20534444 ("DDS"), rozmiar DDS_HEADER wynosi 124, a DDS_PIXELFORMAT w rozmiarze nagłówka to 32. Jeśli DDS_PIXELFORMAT dwFlags jest ustawiona na DDPF_FOURCC, a dwFourCC ma wartość "DX10", łączny rozmiar pliku musi wynosić co najmniej 148 bajtów.

Istnieją pewne typowe warianty, w których format pikseli jest ustawiony na kod DDPF_FOURCC, w którym plik dwFourCC jest ustawiony na wartość D3DFORMAT lub DXGI_FORMAT wartość wyliczenia. Nie ma możliwości określania, czy wartość wyliczenia jest wartością D3DFORMAT lub DXGI_FORMAT, dlatego zdecydowanie zaleca się, aby rozszerzenie "DX10" i nagłówek DDS_HEADER_DXT10 był używany do przechowywania formatu dxgiFormat, gdy podstawowy DDS_PIXELFORMAT nie może wyrazić formatu.

Standardowe DDS_PIXELFORMAT powinny być preferowane w celu zapewnienia maksymalnej zgodności do przechowywania danych nieskompresowanych RGB i danych DXT1-5, ponieważ nie wszystkie narzędzia DDS obsługują rozszerzenie DX10.

Używanie tablic tekstur w trybie Direct3D 10/11

Nowe struktury DDS (DDS_HEADER i DDS_HEADER_DXT10) w trybie Direct3D 10/11 rozszerzają format pliku DDS w celu obsługi tablicy tekstur, która jest nowym typem zasobu w trybie Direct3D 10/11. Oto przykładowy kod, który pokazuje, jak uzyskać dostęp do różnych poziomów mipmap w tablicy tekstur przy użyciu nowych nagłówków.

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

Typowe formaty zasobów plików DDS i skojarzona zawartość nagłówka

Format zasobu 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 zasobu 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
Dowolny format DXGI DDS_FOURCC "DX10"

* = niezawodny czytnik DDS musi mieć możliwość obsługi tych starszych kodów formatu. Jednak taki czytnik DDS powinien preferować użycie rozszerzenia nagłówka "DX10", gdy zapisuje te kody formatu, aby uniknąć niejednoznaczności.

** = Ze względu na niektóre długotrwałe problemy w typowych implementacjach czytników i pisarzy DDS, najbardziej niezawodnym sposobem na zapisanie danych 10:10:10:2 jest użycie rozszerzenia nagłówka "DX10" z kodem DXGI_FORMAT "24" (czyli wartością DXGI_FORMAT_R10G10B10A2_UNORM). D3DFMT_A2R10G10B10 dane powinny zostać przekonwertowane na dane o formacie 10:10:10:2, zanim zostaną zapisane jako plik DDS w formacie DXGI_FORMAT_R10G10B10A2_UNORM.

DDS