ユーザ用ツール

サイト用ツール


ddsformat

差分

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

この比較画面へのリンク

両方とも前のリビジョン前のリビジョン
次のリビジョン
前のリビジョン
ddsformat [2015/05/26 11:55] – [dwMipMapCount] 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 +    DWORD   dwFlags;        // ヘッダ内の有効な情報 DDSD_* の組み合わせ 
- DWORD dwFlags; // ヘッダ内の有効な情報 DDSD_* の組み合わせ +    DWORD   dwHeight;       // 画像の高さ x size 
- DWORD dwHeight; // 画像の高さ x size +    DWORD   dwWidth;        // 画像の幅   y size 
- DWORD dwWidth; // 画像の幅   y size +    DWORD   dwPitchOrLinearSize;    // 横1 line の byte 数 (pitch) 
- DWORD dwPitchOrLinearSize; // 横1 line の byte 数 (pitch) +                                    // または 1面分の byte 数 (linearsize) 
- // または 1面分の byte 数 (linearsize) +    DWORD   dwDepth;        // 画像の奥行き z size (Volume Texture 用) 
- DWORD dwDepth; // 画像の奥行き z size (Volume Texture 用) +    DWORD   dwMipMapCount;  // 含まれている mipmap レベル数 
- DWORD dwMipMapCount; // 含まれている mipmap レベル数 +    DWORD   dwReserved1[11]; 
- DWORD dwReserved1[11]; +    DWORD   dwPfSize;       // == 常に 32 
- DWORD dwPfSize; // == 常に 32 +    DWORD   dwPfFlags;      // pixel フォーマットを表す DDPF_* の組み合わせ 
- DWORD dwPfFlags; // pixel フォーマットを表す DDPF_* の組み合わせ +    DWORD   dwFourCC;       // フォーマットが FourCC で表現される場合に使用する。 
- DWORD dwFourCC; // フォーマットが FourCC であらわされる場合のみ +                            // DX10 拡張ヘッダが存在する場合は 'DX10' (0x30315844) が入る。 
- DWORD dwRGBBitCount; // 1 pixel の bit 数 +    DWORD   dwRGBBitCount;  // 1 pixel の bit 数 
- DWORD dwRBitMask; // RGB format 時の mask +    DWORD   dwRBitMask;     // RGB format 時の mask 
- DWORD dwGBitMask; // RGB format 時の mask +    DWORD   dwGBitMask;     // RGB format 時の mask 
- DWORD dwBBitMask; // RGB format 時の mask +    DWORD   dwBBitMask;     // RGB format 時の mask 
- DWORD dwRGBAlphaBitMask; // RGB format 時の mask +    DWORD   dwRGBAlphaBitMask;      // RGB format 時の mask 
- DWORD dwCaps; // mipmap 等のフラグ指定用 +    DWORD   dwCaps;         // mipmap 等のフラグ指定用 
- DWORD dwCaps2; // cube/volume texture 等のフラグ指定用 +    DWORD   dwCaps2;        // cube/volume texture 等のフラグ指定用 
- DWORD dwReservedCaps[2]; +    DWORD   dwReservedCaps[2]; 
- DWORD dwReserved2;+    DWORD   dwReserved2;
 }; };
 </code> </code>
  
-DX10 拡張ヘッダ。20byte 。dwFourCC が 'DX10' (0x30315844) の場合に T_DDSHEADER の直後に入ります。+DX10 (DXT10) 拡張ヘッダ。20byte 。dwFourCC が 'DX10' (0x30315844) の場合に T_DDSHEADER の直後に入ります。
  
 <code cpp> <code cpp>
 struct T_DDSHEADER_DX10 { struct T_DDSHEADER_DX10 {
- unsigned int Format; // DXGI_FORMAT (dxgiformat.h 参照) +    unsigned int    Format;         // DXGI_FORMAT (dxgiformat.h 参照) 
- unsigned int Dimension; // D3D10_RESOURCE_DIMENSION  (1D=2, 2D=3, 3D=4) +    unsigned int    Dimension;      // D3D10_RESOURCE_DIMENSION が入る。(1D=2, 2D=3, 3D=4) 
- unsigned int MiscFlag;       // 0 +    unsigned int    MiscFlag;       // 0 
- 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 です。
  
  
行 83: 行 90:
 ヘッダの情報が有効かどうかを判定します。 ヘッダの情報が有効かどうかを判定します。
 例えば dwFlags に DDSD_MIPMAPCOUNT flag が立っていなければ、dwMipMapCount の値は無効なものとなります。 例えば dwFlags に DDSD_MIPMAPCOUNT flag が立っていなければ、dwMipMapCount の値は無効なものとなります。
-ただしすべてのツールが厳密にこのフラグに従っているとは限らないので、このフラグを設定しなかったとしても誤動作しないようにヘッダを設定することをおすすめします。+ただしすべてのツールが厳密にこのフラグに従っているとは限らないので、このフラグを設定しなかったとしても誤動作しないようにヘッダのフィールドには常に有効な値を設定することをおすすめします。
  
  
行 93: 行 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 ====
行 109: 行 121:
  
 ただし dwFlags DDSD_MIPMAPCOUNT を正しく判定していないツールやライブラリが存在する可能性があるため、安全のために常に 1 以上の有効な値を入れて置くことをおすすめします。 ただし dwFlags DDSD_MIPMAPCOUNT を正しく判定していないツールやライブラリが存在する可能性があるため、安全のために常に 1 以上の有効な値を入れて置くことをおすすめします。
-また読み出す場合、DDSD_MIPMAPCOUNT が立っていたとしてもこのフィールドが 0 である可能性を考慮した方が良いでしょう。+また読み出す場合、DDSD_MIPMAPCOUNT が立っていたとしてもこのフィールドが 0 である可能性を考慮した方が良いでしょう。
  
 <code cpp> <code cpp>
行 129: 行 141:
 | DDPF_BUMPDUDV        | 0x00080000  | * pixel が符号付であることを示す (本来は bump 用)  DX10以降は使用しない  | | DDPF_BUMPDUDV        | 0x00080000  | * pixel が符号付であることを示す (本来は bump 用)  DX10以降は使用しない  |
  
-上記 '*' が付いた項目はレガシーで DX10 以降は使用しません。ただし古いデータを読み込む場合に必要になる場合があります。+上記 '*' が付いた項目はレガシーで DX10 以降の API では使用しません。ただし古いデータを読み込む場合に必要になる場合があります。 
 + 
 +本来 dwFlags に DDSD_PIXELFORAMT が設定されている場合に有効なフィールドですが、このフラグが常に有効と思って間違いありません。 
  
  
行 136: 行 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 フラグは実際に含まれる機能を定義します。 
 + 
 + 
  
  
行 282: 行 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 ){
行 300: 行 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);
  
行 307: 行 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'):
行 315: 行 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.1432608934.txt.gz · 最終更新: 2015/05/26 11:55 by oga

Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki