共用方式為


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_HEADERDDS_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 檔案設定的詳細資訊:紋理Cube 地圖,或 磁碟區紋理

    BYTE bdata2[]
    

如需廣泛的硬體支援,建議您使用 DXGI_FORMAT_R8G8B8A8_UNORMDXGI_FORMAT_R8G8B8A8_UNORM_SRGBDXGI_FORMAT_R8G8B8A8_SNORMDXGI_FORMAT_B8G8R8A8_UNORMDXGI_FORMAT_R16G16_SNORMDXGI_FORMAT_R8G8_SNORMDXGI_FORMAT_R8_UNORMDXGI_FORMAT_BC1_UNORMDXGI_FORMAT_BC1_UNORM_SRGBDXGI_FORMAT_BC2_UNORMDXGI_FORMAT_BC2_UNORM_SRGBDXGI_FORMAT_BC3_UNORMDXGI_FORMAT_BC3_UNORM_SRGB 格式。

如需壓縮紋理格式的詳細資訊,請參閱 Direct3D 11 中的紋理區塊壓縮和 區塊壓縮 (Direct3D 10)

D3DX 連結庫(例如 D3DX11.lib)和其他類似連結庫無法正確或不一致地提供 dwPitchOrLinearSize 中DDS_HEADER 結構的成員。 因此,當您讀取和寫入 DDS 檔案時,建議您使用下列其中一種方式來計算指定的格式:

  • 針對區塊壓縮格式,將音調計算為:

    max( 1, (width+3)/4) ) * 區塊大小

    區塊大小是 DXT1、BC1 和 BC4 格式的 8 個字節,而其他區塊壓縮格式則為 16 個字節。

  • 針對R8G8_B8G8、G8R8_G8B8、舊版 UYVY 封裝和舊版 YUY2 包裝格式,將音調計算為:

    (寬度+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_HEADERDDS_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:10:2 型別數據的最強固方式是使用 “DX10” 標頭延伸模組搭配 DXGI_FORMAT 代碼 “24” (也就是DXGI_FORMAT_R10G10B10A2_UNORM值)。 D3DFMT_A2R10G10B10數據應該先轉換成 10:10:10:2 類型的數據,再寫成DXGI_FORMAT_R10G10B10A2_UNORM格式 DDS 檔案。

DDS