====== 009 DDSテクスチャの読み込み ====== ===== 概要 ===== DXT1,3、5に対応しています。テクスチャはミップマップを含む様にして下さい。 ==== ソースコード ==== typedef struct { uint32 uSize; uint32 uFlags; uint32 uFourCC; uint32 uRgbBitCount; uint32 uRbitMask; uint32 uGbitMask; uint32 uBbitMask; uint32 uAbitMask; } DDSPixelFormat; typedef struct { uint8 uMagic[4]; uint32 uSize; uint32 uFlags; uint32 uHeight; uint32 uWidth; uint32 uPitchOrLinearSize; uint32 uDepth; uint32 uMipMapCount; uint32 uReserved1[11]; DDSPixelFormat Ddspf; uint32 uCaps1; uint32 uCaps2; uint32 uReserved2[3]; } DDSHeader; class DDSUtil { public: static bool IsDDS( const uint8* _pData ) { const DDSHeader* pHeader = reinterpret_cast( _pData ); if( (uint32)pHeader->uMagic != (uint32)DDS_MAGIC ) { return false; } return true; } static bool Load( const uint8* _pData, GLuint* _textureID, sint32* _width, sint32* _height ) { const uint8* pImage = _pData + sizeof( DDSHeader ); const DDSHeader* pHeader = reinterpret_cast( _pData ); GLuint textureName; glGenTextures( 1, &textureName ); glBindTexture( GL_TEXTURE_2D, textureName ); uint32 uWidth = pHeader->uWidth; uint32 uHeight = pHeader->uHeight; uint32 uFormat; switch( pHeader->Ddspf.uFourCC ) { case DDS_DXT1: { uFormat = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT; } break; case DDS_DXT3: { uFormat = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT; } break; case DDS_DXT5: { uFormat = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; } break; }; sint32 blockSize; sint32 offset = 0; sint32 uSize = 0; // DXT1 if( uFormat == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT ) { blockSize = 8; } // DXT3 or DXT5 else { blockSize = 16; } for( uint32 i = 0; i < pHeader->uMipMapCount; i++ ) { uSize = ( ( uWidth + 3 ) / 4 ) * ( ( uHeight + 3 ) / 4 ) * blockSize; glCompressedTexImage2D( GL_TEXTURE_2D, i, uFormat, uWidth, uHeight, 0, uSize, pImage + offset ); if( uWidth >> 1 ) { uWidth = (uWidth >> 1); } else { uWidth = 1; } if( uHeight >> 1 ) { uHeight = (uHeight >> 1); } else { uHeight = 1; } offset += uSize; } *_width = pHeader->uWidth; *_height = pHeader->uHeight; *_textureID = textureName; return true; } };