ddsformat
差分
このページの2つのバージョン間の差分を表示します。
両方とも前のリビジョン前のリビジョン次のリビジョン | 前のリビジョン | ||
ddsformat [2015/05/26 12:05] – [DDS のヘッダ構造] oga | ddsformat [2015/05/26 16:45] (現在) – [DDS のヘッダ構造] oga | ||
---|---|---|---|
行 27: | 行 27: | ||
// 基本ヘッダ構造体 Little-endian | // 基本ヘッダ構造体 Little-endian | ||
struct T_DDSHEADER { | struct T_DDSHEADER { | ||
- | public: | ||
DWORD | DWORD | ||
DWORD | DWORD | ||
行 63: | 行 62: | ||
unsigned int ArraySize; | unsigned int ArraySize; | ||
unsigned int MiscFlag2; | unsigned int MiscFlag2; | ||
+ | }; | ||
+ | enum { | ||
+ | DDS10_DIMENSION_1D = 2, | ||
+ | DDS10_DIMENSION_2D = 3, | ||
+ | DDS10_DIMENSION_3D = 4, | ||
}; | }; | ||
</ | </ | ||
+ | |||
+ | DWORD は unsigned int (4byte)。ヘッダ情報はすべて little endian です。 | ||
行 84: | 行 90: | ||
ヘッダの情報が有効かどうかを判定します。 | ヘッダの情報が有効かどうかを判定します。 | ||
例えば dwFlags に DDSD_MIPMAPCOUNT flag が立っていなければ、dwMipMapCount の値は無効なものとなります。 | 例えば dwFlags に DDSD_MIPMAPCOUNT flag が立っていなければ、dwMipMapCount の値は無効なものとなります。 | ||
- | ただしすべてのツールが厳密にこのフラグに従っているとは限らないので、このフラグを設定しなかったとしても誤動作しないようにヘッダを設定することをおすすめします。 | + | ただしすべてのツールが厳密にこのフラグに従っているとは限らないので、このフラグを設定しなかったとしても誤動作しないようにヘッダのフィールドには常に有効な値を設定することをおすすめします。 |
行 94: | 行 100: | ||
==== dwPitchOrLinearSize ==== | ==== dwPitchOrLinearSize ==== | ||
- | dwFlags に DDSD_PITCH または DDSD_LINEARSIZE が含まれている場合に有効になります。 | + | dwFlags に DDSD_PITCH または DDSD_LINEARSIZE が含まれている場合に有効になります。あまり重要なフィールドではありません。 |
- | あまり重要なフィールドではありません。 | + | |
- | 無くてもおそらく問題ありませんが、一部ツールでは参照している可能性があります。 | + | |
- | + | ||
- | | DDSD_LINEARSIZE | + | |
- | | DDSD_PITCH | + | |
+ | | DDSD_LINEARSIZE | ||
+ | | DDSD_PITCH | ||
+ | |||
+ | 圧縮テクスチャの場合は pitch には 1列分の block サイズが入ります。 | ||
+ | 例えば 256x256 の DXT1 なら、横は 256/4 = 64 block となります。 | ||
+ | DXT は 1block = 64bit なので pitch = 64block x 64bit / 8bit = 512byte です。 | ||
+ | 同様に 250x250 のような半端なサイズのテクスチャも、block 単位に切り上げて計算する必要があります。 | ||
+ | ( ( 250 + 3) >> 2) block x 64bit / 8bit = 504byte | ||
+ | |||
+ | ただし、圧縮テクスチャの場合も結局 MipmapLevel 毎に同様の block 単位のアライメントサイズの再計算を行う必要があるので、実際の実装ではこのフィールドの値が必要になることがありません。 | ||
==== dwMipMapCount ==== | ==== dwMipMapCount ==== | ||
行 110: | 行 121: | ||
ただし dwFlags DDSD_MIPMAPCOUNT を正しく判定していないツールやライブラリが存在する可能性があるため、安全のために常に 1 以上の有効な値を入れて置くことをおすすめします。 | ただし dwFlags DDSD_MIPMAPCOUNT を正しく判定していないツールやライブラリが存在する可能性があるため、安全のために常に 1 以上の有効な値を入れて置くことをおすすめします。 | ||
- | また読み出す場合あ、DDSD_MIPMAPCOUNT が立っていたとしてもこのフィールドが 0 である可能性を考慮した方が良いでしょう。 | + | また読み出す場合、DDSD_MIPMAPCOUNT が立っていたとしてもこのフィールドが 0 である可能性を考慮した方が良いでしょう。 |
<code cpp> | <code cpp> | ||
行 140: | 行 151: | ||
^ シンボル | ^ シンボル | ||
| DDSCAPS_ALPHA | | DDSCAPS_ALPHA | ||
- | | DDSCAPS_COMPLEX | + | | DDSCAPS_COMPLEX |
- | | DDSCAPS_TEXTURE | + | | DDSCAPS_TEXTURE |
- | | DDSCAPS_MIPMAP | + | | DDSCAPS_MIPMAP |
+ | |||
+ | dwCaps フラグは実際に含まれる機能を定義します。 | ||
+ | |||
+ | |||
行 286: | 行 302: | ||
<code cpp> | <code cpp> | ||
- | # | + | #define MAKE_FOURCC( x, y, z, w ) (((w)<< |
void* memory= malloc( file_size ); | void* memory= malloc( file_size ); | ||
ReadFile( file, memory, file_size, & | ReadFile( file, memory, file_size, & | ||
~ | ~ | ||
+ | assert( file_size >= sizeof(T_DDSHEADER) ); | ||
+ | |||
const T_DDSHEADER* | const T_DDSHEADER* | ||
const unsigned char* data_ptr= reinterpret_cast< | const unsigned char* data_ptr= reinterpret_cast< | ||
+ | if( header-> | ||
+ | // error | ||
+ | return | ||
+ | } | ||
+ | |||
+ | unsigned int width= header-> | ||
+ | unsigned int height= max( header-> | ||
+ | unsigned int depth= (header-> | ||
+ | unsigned int mip_map_count= (header-> | ||
unsigned int array_count= 1; | unsigned int array_count= 1; | ||
- | unsigned int | + | unsigned int |
if( header-> | if( header-> | ||
行 304: | 行 331: | ||
// 追加ヘッダの読み込み | // 追加ヘッダの読み込み | ||
const T_DDSHEADER_DX10* header10= reinterpret_cast< | const T_DDSHEADER_DX10* header10= reinterpret_cast< | ||
- | // ピクセルデータ先頭位置の再計算 | + | // ピクセルデータ位置の再計算 |
data_ptr+= sizeof(T_DDSHEADER_DX10); | data_ptr+= sizeof(T_DDSHEADER_DX10); | ||
行 311: | 行 338: | ||
}else{ | }else{ | ||
- | // FourCC による定義 | + | // FourCC による定義 D3DFORMAT や MAKE_FOURCC(' |
switch( fourCC ){ | switch( fourCC ){ | ||
case MAKE_FOURCC(' | case MAKE_FOURCC(' | ||
行 319: | 行 346: | ||
}else if( header-> | }else if( header-> | ||
// Bitmask による定義 | // Bitmask による定義 | ||
+ | unsigned int bit_count= header-> | ||
+ | unsigned int r_mask= header-> | ||
+ | unsigned int g_mask= header-> | ||
+ | unsigned int b_mask= header-> | ||
+ | unsigned int a_mask= header-> | ||
}else{ | }else{ | ||
// error | // error | ||
+ | } | ||
+ | |||
+ | if( !(header-> | ||
+ | mip_map_count= 1; | ||
+ | } | ||
+ | if( !(header-> | ||
+ | depth= 1; | ||
+ | } | ||
+ | |||
+ | if( header-> | ||
+ | face_count= 6; // 厳密には DDSCAPS2_CUBEMAP_POSITIVEX ~ の判定が必要 | ||
} | } | ||
</ | </ | ||
+ | |||
+ | |||
+ | ==== ヘッダ設定コードの例 ==== | ||
+ | |||
+ | <code cpp> | ||
+ | T_DDSHEADER | ||
+ | T_DDSHEADER_DX10 | ||
+ | memset( & | ||
+ | memset( & | ||
+ | bool isdx10= false; | ||
+ | |||
+ | header.dwMagic= 0x20534444; | ||
+ | header.dwSize= 124; | ||
+ | header.dwFlags= DDSD_WIDTH|DDSD_HEIGHT|DDSD_CAPS|DDSD_PIXELFORMAT; | ||
+ | |||
+ | header.dwWidth= width; | ||
+ | header.dwHeight= height; | ||
+ | header.dwDepth= 1; | ||
+ | header.dwMipMapCount= 1; | ||
+ | header10.ArraySize= 1; | ||
+ | header10.Dimension= DDS10_DIIMENSION_2D; | ||
+ | |||
+ | if( 非圧縮時 ){ | ||
+ | header.dwFlags|= DDSD_PITCH; | ||
+ | header.dwPitchOrLinearSize= (width * bit_count) >> 3; | ||
+ | }else{ | ||
+ | header.dwFlags|= DDSD_LINEARSIZE; | ||
+ | header.dwPitchOrLinearSize= (block_width * block_height * block_bit_count) >> 3; | ||
+ | } | ||
+ | |||
+ | if( mipmap_count > 1 ){ | ||
+ | header.dwFlags|= DDSD_MIPMAPCOUNT; | ||
+ | header.dwCaps|= DDSCAPS_COMPLEX|DDSCAPS_MIPMAP; | ||
+ | header.dwMipMapCount= mipmap_count; | ||
+ | } | ||
+ | |||
+ | if( face_count > 1 ){ | ||
+ | header.dwCaps|= DDSCAPS_COMPLEX; | ||
+ | header.dwCaps2|= DDSCAPS2_CUBEMAP | ||
+ | |DDSCAPS2_CUBEMAP_POSITIVEX | ||
+ | |DDSCAPS2_CUBEMAP_NEGATIVEX | ||
+ | |DDSCAPS2_CUBEMAP_POSITIVEY | ||
+ | |DDSCAPS2_CUBEMAP_NEGATIVEY | ||
+ | |DDSCAPS2_CUBEMAP_POSITIVEZ | ||
+ | |DDSCAPS2_CUBEMAP_NEGATIVEZ; | ||
+ | } | ||
+ | |||
+ | if( depth > 1 ){ | ||
+ | header.dwCaps|= DDSCAPS_COMPLEX; | ||
+ | header.dwCaps2|= DDSCAPS2_VOLUME; | ||
+ | header.dwDepth= depth; | ||
+ | header10.Dimension= DDS10_DIMENSION_3D; | ||
+ | } | ||
+ | |||
+ | if( array_count > 1 ){ | ||
+ | header10.ArraySize= array_count; | ||
+ | isdx10= true; // Array なら DX10 ヘッダが必須 | ||
+ | } | ||
+ | |||
+ | header.dwPfSize= 32; | ||
+ | |||
+ | if( !isdx10 && | ||
+ | header.dwPfFlags|= DDPF_RGB|DDPF_ALPHAPIXELS; | ||
+ | header.dwRGBBitCount= bit_count; | ||
+ | header.dwRBitMask= .. | ||
+ | header.dwGBitMask= .. | ||
+ | header.dwBBitMask= .. | ||
+ | header.dwRGBAlphaBitMask= .. | ||
+ | }else if( !isdx10 && | ||
+ | header.dwPfFlags|= DDPF_FOURCC; | ||
+ | header.dwFourCC= .. | ||
+ | }else{ | ||
+ | isdx10= true; | ||
+ | header.dwPfFlags|= DDPF_FOURCC; | ||
+ | header.dwFourCC= 0x30315844; | ||
+ | |||
+ | // DXGI_FORMAT に変換 | ||
+ | header10.Format= dxgi_format; | ||
+ | } | ||
+ | |||
+ | Write( & | ||
+ | if( isdx10 ){ | ||
+ | Write( & | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | |||
ddsformat.1432609536.txt.gz · 最終更新: 2015/05/26 12:05 by oga