Udostępnij za pośrednictwem


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