DDS 的程式設計指南
Direct3D 會實作 DDS 檔案格式,以儲存未壓縮或壓縮的 (DXTn) 紋理。 檔案格式會實作數種稍微不同的類型,其設計目的是儲存不同類型的資料,並支援單一圖層紋理、具有 Mipmap、Cube 貼圖、磁片區貼圖和紋理陣列 (Direct3D 10/11) 。 本節描述 DDS 檔案的配置。
如需在 Direct3D 11 中建立紋理的說明,請參閱 如何:建立紋理。 如需 Direct3D 9 的說明,請參閱 D3DX 中的紋理支援 (Direct3D 9) 。
DDS 檔案配置
DDS 檔案是包含下列資訊的二進位檔案:
包含四個字元的代碼值 'DDS ' (0x20534444) 的 DWORD (魔術數字)。
檔案中的資料描述。
資料會使用 DDS_HEADER來描述標頭描述;像素格式是使用 DDS_PIXELFORMAT來定義。 請注意, DDS_HEADER 和 DDS_PIXELFORMAT 結構會取代已被取代的 DDSURFACEDESC2、DDSCAPS2 和 DDPIXELFORMAT DirectDraw 7 結構。 DDS_HEADER 是 DDSURFACEDESC2 和 DDSCAPS2 的二進位對等專案。 DDS_PIXELFORMAT 是 DDPIXELFORMAT 的二進位對等專案。
DWORD dwMagic; DDS_HEADER header;
如果DDS_PIXELFORMAT dwFlags 設定為 DDPF_FOURCC,而 dwFourCC 設定為 「DX10」,則會出現額外的 DDS_HEADER_DXT10 結構,以容納無法以 RGB 像素格式表示的紋理陣列或 DXGI 格式,例如浮點格式、sRGB 格式等。當 DDS_HEADER_DXT10 結構出現時,整個資料描述看起來會像這樣。
DWORD dwMagic; DDS_HEADER header; DDS_HEADER_DXT10 header10;
包含主要表面資料的位元組陣列指標。
BYTE bdata[]
包含其餘的表面 (如 Mipmap 層級、立方體貼圖中的面及容積紋理中的深度) 的位元組陣列指標。 請點選下列連結,以了解下列的 DDS 檔案配置相關資訊:紋理、立方體貼圖或容積紋理。
BYTE bdata2[]
如需廣泛的硬體支援,建議您使用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或DXGI_FORMAT_BC3_UNORM_SRGB格式。
如需壓縮紋理格式的詳細資訊,請參閱 Direct3D 11 中的紋理區塊壓縮 和 區塊壓縮 (Direct3D 10) 。
D3DX 程式庫 (例如,D3DX11.lib) 和其他類似的程式庫無法正確或不一致地提供DDS_HEADER結構的dwPitchOrLinearSize成員中的間距值。 因此,當您讀取和寫入 DDS 檔案時,建議您以下列其中一種方式計算指示格式的音調:
針對區塊壓縮格式,將音調計算為:
max ( 1, ( (width+3) /4) ) * 區塊大小
區塊大小是 DXT1、BC1 和 BC4 格式的 8 個位元組,而其他區塊壓縮格式則為 16 個位元組。
針對R8G8_B8G8,G8R8_G8B8、舊版 UYVY 套件和舊版 YUY2 套件格式,將音調計算為:
( (width+1) 1) >> * 4
針對其他格式,將音調計算為:
(寬度 * 每圖元位 + 7 ) / 8
您會將位元組對齊除以 8。
注意
您計算的音調值不一定等於執行時間所提供的音調,這在某些情況下會對齊 DWORD,在其他情況下會對齊位元組。 因此,建議您一次複製掃描行,而不是嘗試在一個複本中複製整個映射。
DDS Variants
有許多工具可建立及取用 DDS 檔案,但可能會因標頭中需要的詳細資料而有所不同。 寫入器應該盡可能完整地填入標頭,而讀取器應該檢查最小值以取得最大的相容性。 若要驗證 DDS 檔案,讀取器應該確保檔案長度至少為 128 位元組,以容納 magic 值和基本標頭,magic 值為 0x20534444 (「DDS 」) ,DDS_HEADER大小為 124,標頭大小的DDS_PIXELFORMAT為 32。 如果DDS_PIXELFORMAT dwFlags 設定為 DDPF_FOURCC,而 dwFourCC 設定為 「DX10」,則總檔案大小至少必須是 148 個位元組。
有一些常見的變體,其中像素格式設定為DDPF_FOURCC程式碼,其中 dwFourCC 設定為 D3DFORMAT 或DXGI_FORMAT列舉值。 無法判斷列舉值是否為 D3DFORMAT 或DXGI_FORMAT,因此強烈建議使用 「DX10」 延伸模組和DDS_HEADER_DXT10標頭來儲存基本DDS_PIXELFORMAT無法表示格式時的 dxgiFormat。
建議使用標準DDS_PIXELFORMAT,以達到最大相容性來儲存 RGB 未壓縮的資料和 DXT1-5 資料,因為並非所有 DDS 工具都支援 DX10 擴充功能。
在 Direct3D 10/11 中使用紋理陣列
Direct3D 10/11 中的新 DDS 結構 (DDS_HEADER 和 DDS_HEADER_DXT10) 延伸 DDS 檔案格式以支援紋理陣列,這是 Direct3D 10/11 中的新資源類型。 以下是一些範例程式碼,示範如何使用新的標頭,存取紋理陣列中的不同 Mipmap 層級。
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++)
{
...
}
}
常見的 DDS 檔資源格式和相關聯的標頭內容
資源格式 | 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 |
資源格式 | 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 |
任何 DXGI 格式 | DDS_FOURCC | 「DX10」 |
* = 強固的 DDS 讀取器必須能夠處理這些舊版格式代碼。 不過,這類 DDS 讀取器應該偏好在撰寫這些格式代碼時使用 「DX10」 標頭延伸,以避免模棱兩可。
** = 由於 DDS 讀取器和寫入器常見實作中的一些長期問題,所以寫出 10:10:10:2 類型資料的最強固方式是使用 「DX10」 標頭延伸模組搭配 DXGI_FORMAT 程式碼 「24」 (,也就是DXGI_FORMAT_R10G10B10A2_UNORM值) 。 D3DFMT_A2R10G10B10資料應該先轉換成 10:10:10:2 類型資料,再寫出成DXGI_FORMAT_R10G10B10A2_UNORM格式 DDS 檔案。