ユーザ用ツール

サイト用ツール


ddsformat

差分

このページの2つのバージョン間の差分を表示します。

この比較画面へのリンク

両方とも前のリビジョン前のリビジョン
次のリビジョン
前のリビジョン
ddsformat [2015/05/26 12:05] – [DDS のヘッダ構造] ogaddsformat [2015/05/26 16:45] (現在) – [DDS のヘッダ構造] oga
行 27: 行 27:
 // 基本ヘッダ構造体 Little-endian // 基本ヘッダ構造体 Little-endian
 struct T_DDSHEADER { struct T_DDSHEADER {
-public: 
     DWORD   dwMagic;        // == 常に 0x20534444  ' SDD'     DWORD   dwMagic;        // == 常に 0x20534444  ' SDD'
     DWORD   dwSize;         // == 常に 124     DWORD   dwSize;         // == 常に 124
行 63: 行 62:
     unsigned int    ArraySize;      // Texture Array を格納する場合に必要     unsigned int    ArraySize;      // Texture Array を格納する場合に必要
     unsigned int    MiscFlag2;      // 0     unsigned int    MiscFlag2;      // 0
 +};
 +enum {
 +    DDS10_DIMENSION_1D = 2,
 +    DDS10_DIMENSION_2D = 3,
 +    DDS10_DIMENSION_3D = 4,
 }; };
 </code> </code>
 +
 +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  | 最初の face の最初の miplevel 0 の画像の byte 数。圧縮テクスチャの場合こちら。 +
-| DDSD_PITCH       | 最初の miplevel 0 の画像の横 1列の byte 数。(dwWidth * dwRGBBitCount) >> 3 相当。非圧縮で BitMask を使った画像の場合はこちらが入る。    |+
  
 +| DDSD_LINEARSIZE  | 最初の face の最初の miplevel 0 の画像の byte 数。  |
 +| DDSD_PITCH       | 最初の miplevel 0 の画像の横 1列の byte 数。圧縮テクスチャの場合、block 単位の 1列分の byte サイズ。    |
  
 +
 +圧縮テクスチャの場合は 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    | 0x00000002 | Alpha が含まれている場合 (あまり参照されない)    | | DDSCAPS_ALPHA    | 0x00000002 | Alpha が含まれている場合 (あまり参照されない)    |
-| DDSCAPS_COMPLEX  | 0x00000008 | 複数のデータが含まれている場合 Palette/Mipmap/Cube/Volume 等では にする。 +| DDSCAPS_COMPLEX  | 0x00000008 | 複数のデータが含まれている場合Palette/Mipmap/Cubemap/VolumeTexture では On にする。 
-| DDSCAPS_TEXTURE  | 0x00001000 | 常に    | +| DDSCAPS_TEXTURE  | 0x00001000 | 常に On    | 
-| DDSCAPS_MIPMAP   | 0x00400000 | MipMap が存在する場合  |+| DDSCAPS_MIPMAP   | 0x00400000 | MipMap が存在する場合。(dwFlags の DDSD_MIPMAPCOUNT が On でかつ dwMipMapCount が 2以上の場合に On)  | 
 + 
 +dwCaps フラグは実際に含まれる機能を定義します。 
 + 
 + 
  
  
行 286: 行 302:
  
 <code cpp> <code cpp>
-#define MAKE_FOURCC( x, y, z, w )  (((w)<<24)|((z)<<16)|((y)<<8)|(x))+#define MAKE_FOURCC( x, y, z, w )  (((w)<<24)|((z)<<16)|((y)<<8)|(x))
  
 void* memory= malloc( file_size ); void* memory= malloc( file_size );
 ReadFile( file, memory, file_size, &read_size, NULL ); ReadFile( file, memory, file_size, &read_size, NULL );
  
 +assert( file_size >= sizeof(T_DDSHEADER) );
 +
  
 const T_DDSHEADER*      header= reinterpret_cast<const T_DDSHEADER*>( memory ); const T_DDSHEADER*      header= reinterpret_cast<const T_DDSHEADER*>( memory );
 const unsigned char*    data_ptr= reinterpret_cast<const unsigned char*>( memory ) + sizeof(T_DDSHEADER); const unsigned char*    data_ptr= reinterpret_cast<const unsigned char*>( memory ) + sizeof(T_DDSHEADER);
  
 +if( header->dwMagic != 0x20534444 || header->dwSize != 124 ){
 +    // error
 +    return  false;
 +}
 +
 +unsigned int  width= header->dwWidth;
 +unsigned int  height= max( header->dwWidth, 1 );
 +unsigned int  depth= (header->dwFlags & DDSD_DEPTH) ? max( header->dwDepth, 1 ) : 1;
 +unsigned int  mip_map_count= (header->dwFlags & DDSD_MIPMAPCOUNT) ? max( header->dwMipMapCount, 1 ) : 1;
 unsigned int  array_count= 1; unsigned int  array_count= 1;
-unsigned int  mip_map_count(header->dwFlags & DDSD_MIPMAPCOUNT) ? max( header->dwMipMapCount, 1 ) : 1 ;+unsigned int  face_count= 1;
  
 if( header->dwPfFlags & DDPF_FOURCC ){ if( header->dwPfFlags & DDPF_FOURCC ){
行 304: 行 331:
         // 追加ヘッダの読み込み         // 追加ヘッダの読み込み
         const T_DDSHEADER_DX10* header10= reinterpret_cast<const T_DDSHEADER_DX10*>( data_ptr );         const T_DDSHEADER_DX10* header10= reinterpret_cast<const T_DDSHEADER_DX10*>( data_ptr );
-        // ピクセルデータ先頭位置の再計算+        // ピクセルデータ位置の再計算
         data_ptr+= sizeof(T_DDSHEADER_DX10);         data_ptr+= sizeof(T_DDSHEADER_DX10);
  
行 311: 行 338:
  
     }else{     }else{
-        // FourCC による定義 D3D9 D3DFORMAT や MAKE_FOURCC('D','X','T','1') など+        // FourCC による定義 D3DFORMAT や MAKE_FOURCC('D','X','T','1') など
         switch( fourCC ){         switch( fourCC ){
         case MAKE_FOURCC('D','X','T','1'):         case MAKE_FOURCC('D','X','T','1'):
行 319: 行 346:
 }else if( header->dwPfFlags & (DDPF_RGB|DDPF_ALPHAPIXELS|DDPF_ALPHA|DDPF_BUMPDUDV|DDPF_LUMINANCE) ){ }else if( header->dwPfFlags & (DDPF_RGB|DDPF_ALPHAPIXELS|DDPF_ALPHA|DDPF_BUMPDUDV|DDPF_LUMINANCE) ){
     // Bitmask による定義     // Bitmask による定義
 +    unsigned int  bit_count= header->dwRGBBitCount;
 +    unsigned int  r_mask= header->dwRBitMask;
 +    unsigned int  g_mask= header->dwGBitMask;
 +    unsigned int  b_mask= header->dwBBitMask;
 +    unsigned int  a_mask= header->dwRGBAlphaBitMask;
 }else{ }else{
     // error     // error
 +}
 +
 +if( !(header->dwCaps & DDSCAPS_MIPMAP) ){
 +    mip_map_count= 1;
 +}
 +if( !(header->dwCaps2 & DDSCAPS2_VOLUME) ){
 +    depth= 1;
 +}
 +
 +if( header->dwCaps2 & DDSCAPS2_CUBEMAP ){
 +    face_count= 6; // 厳密には DDSCAPS2_CUBEMAP_POSITIVEX ~ の判定が必要
 } }
 </code> </code>
 +
 +
 +==== ヘッダ設定コードの例 ====
 +
 +<code cpp>
 +T_DDSHEADER         header;
 +T_DDSHEADER_DX10    header10;
 +memset( &header, 0, sizeof(T_DDSHEADER) );
 +memset( &header10, 0, sizeof(T_DDSHEADER_DX10) );
 +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 &&  BitMask 表現可能  ){
 +    header.dwPfFlags|= DDPF_RGB|DDPF_ALPHAPIXELS;
 +    header.dwRGBBitCount= bit_count;
 +    header.dwRBitMask= ..
 +    header.dwGBitMask= ..
 +    header.dwBBitMask= ..
 +    header.dwRGBAlphaBitMask= ..
 +}else if( !isdx10 &&  FourCC 表現が可能  ){
 +    header.dwPfFlags|= DDPF_FOURCC;
 +    header.dwFourCC= ..
 +}else{
 +    isdx10= true;
 +    header.dwPfFlags|= DDPF_FOURCC;
 +    header.dwFourCC= 0x30315844;    // 'DX10'
 +
 +    // DXGI_FORMAT に変換
 +    header10.Format= dxgi_format;
 +}
 +
 +Write( &header, sizeof(T_DDSHEADER) );
 +if( isdx10 ){
 +    Write( &header10, sizeof(T_DDSHEADER_DX10) );
 +}
 +</code>
 +
 +
  
  
ddsformat.1432609536.txt.gz · 最終更新: 2015/05/26 12:05 by oga

Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki