DDS のプログラミング ガイド
Direct3D は、非圧縮または圧縮 (DXTn) テクスチャを格納するための DDS ファイル形式を実装します。 ファイル形式は、さまざまな種類のデータを格納するために設計されたいくつかの少し異なる種類を実装し、(Direct3D 10/11 の) シングル レイヤー テクスチャ、ミップマップ、キューブ マップ、ボリューム マップ、テクスチャ配列を含むテクスチャをサポートします。 このセクションでは、DDS ファイルのレイアウトについて説明します。
Direct3D 11 でテクスチャを作成する方法については、「 方法: テクスチャを作成する」を参照してください。 Direct3D 9 のヘルプについては、「 D3DX でのテクスチャのサポート (Direct3D 9)」を参照してください。
DDS ファイル レイアウト
DDS ファイルは、次の情報が含まれるバイナリ ファイルです。
4 文字コード値 "DDS " (0x20534444) が含まれる DWORD (マジック ナンバー)。
ファイル内のデータの説明。
データは、DDS_HEADER を使ってヘッダーの説明と一緒に説明されます。ピクセル形式は、DDS_PIXELFORMAT を使って定義されます。 DDS_HEADER 構造体と DDS_PIXELFORMAT 構造体は、推奨されなくなった DirectDraw 7 の DDSURFACEDESC2 構造体、DDSCAPS2 構造体、および DDPIXELFORMAT 構造体の代わりに使います。 DDS_HEADER は、DDSURFACEDESC2 と DDSCAPS2 の機能をバイナリで実現します。 DDS_PIXELFORMAT は、DDPIXELFORMAT の機能をバイナリで実現します。
DWORD dwMagic; DDS_HEADER header;
DDS_PIXELFORMAT dwFlags が DDPF_FOURCC に設定され、dwFourCC が "DX10" に設定されている場合は、テクスチャ配列や、浮動小数点形式、sRGB 形式などの RGB ピクセル形式として表現できない DXGI 形式に対応するために 、追加の DDS_HEADER_DXT10構造体が存在します。 DDS_HEADER_DXT10 構造が存在する場合、データの説明全体は次のようになります。
DWORD dwMagic; DDS_HEADER header; DDS_HEADER_DXT10 header10;
メイン サーフェス データを含むバイトの配列へのポインター。
BYTE bdata[]
残りのサーフェス (ミップマップ レベル、キューブ マップの面、ボリューム テクスチャの深度など) を含むバイトの配列へのポインター。 テクスチャ、キューブ マップ、またはボリューム テクスチャの 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) ) * block-size
ブロック サイズは、DXT1、BC1、BC4 形式の場合は 8 バイト、その他のブロック圧縮形式の場合は 16 バイトです。
R8G8_B8G8、G8R8_G8B8、従来の UYVY パック形式、および従来の YUY2 パック形式の場合は、ピッチを次のように計算します。
((width+1) >> 1) * 4
その他の形式の場合は、ピッチを次のように計算します。
( width * bits-per-pixel + 7 ) / 8
バイトアラインメントの場合は、8 で除算します。
Note
計算するピッチ値は、ランタイムが提供するピッチと必ずしも等しいとは限りません。これは、状況によっては DWORD にアラインされ、他の状況ではバイトアラインされます。 そのため、1 回のコピーでイメージ全体をコピーするのではなく、一度にスキャン行をコピーすることをお勧めします。
DDS バリアント
DDS ファイルを作成して使用するツールは多数ありますが、ヘッダーに必要なものの詳細は異なる場合があります。 ライターは可能な限りヘッダーを設定する必要があり、読者は互換性を最大限に高める最小の値をチェックする必要があります。 DDS ファイルを検証するには、マジック値と基本ヘッダーを格納するためにファイルの長さが 128 バイト以上であることを確認する必要があります。マジック値は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かを確認する方法がないため、基本的なDDS_PIXELFORMATで形式を表すことができない場合は、dxgiFormat を格納するために、代わりに "DX10" 拡張機能と DDS_HEADER_DXT10 ヘッダーを使用することを強くお勧めします。
すべての DDS ツールが DX10 拡張機能をサポートしているわけではないので、RGB 非圧縮データと DXT1-5 データを格納するための互換性を最大限に高めるために、標準のDDS_PIXELFORMATを推奨する必要があります。
Direct3D 10/11 でのテクスチャ配列の使用
Direct3D 10/11 の新しい DDS 構造体 (DDS_HEADER と DDS_HEADER_DXT10) は、Direct3D 10/11 の新しいリソースの種類であるテクスチャの配列をサポートするように DDS ファイル形式を拡張します。 新しいヘッダーを使用して、テクスチャの配列内のさまざまなミップマップ レベルにアクセスする方法を示すサンプル コードを次に示します。
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 | 0 xff | 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 | 0 xff | |||
D3DFMT_A8R8G8B8 |
DDS_RGBA | 32 | 0xff0000 | 0xff00 | 0 xff | 0xff000000 |
D3DFMT_X8R8G8B8 |
DDS_RGB | 32 | 0xff0000 | 0xff00 | 0 xff | |
D3DFMT_X8B8G8R8 |
DDS_RGB | 32 | 0 xff | 0xff00 | 0xff0000 | |
** D3DFMT_A2R10G10B10 |
DDS_RGBA | 32 | 0x3ff00000 | 0xffc00 | 0x3ff | 0xc0000000 |
D3DFMT_R8G8B8 |
DDS_RGB | 24 | 0xff0000 | 0xff00 | 0 xff | |
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 | 0 xff | 0xff00 | ||
D3DFMT_L16 |
DDS_LUMINANCE | 16 | 0xffff | |||
D3DFMT_L8 |
DDS_LUMINANCE | 8 | 0 xff | |||
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 型データを書き出す最も堅牢な方法は、 DXGI_FORMAT コード "24" (つまり、DXGI_FORMAT_R10G10B10A2_UNORM値) で "DX10" ヘッダー拡張機能を使用することです。 D3DFMT_A2R10G10B10データは、DXGI_FORMAT_R10G10B10A2_UNORM形式の DDS ファイルとして書き込まれる前に、10:10:10:2 型のデータに変換する必要があります。