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ładu plików DDS
- warianty DDS
- używanie tablic tekstur w Direct3D 10/11
- typowe formaty zasobów plików DDS i skojarzona zawartość nagłówka
- Tematy pokrewne
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.