diff --git a/3rdparty/.editorconfig b/3rdparty/.editorconfig index 3a32420d..3b1e1533 100644 --- a/3rdparty/.editorconfig +++ b/3rdparty/.editorconfig @@ -11,3 +11,5 @@ indent_size = 4 [remotery/*] indent_style = space indent_size = 4 + +[libsquish/*] diff --git a/3rdparty/libsquish/squish.cpp b/3rdparty/libsquish/squish.cpp index ab8f2e3f..916f604d 100644 --- a/3rdparty/libsquish/squish.cpp +++ b/3rdparty/libsquish/squish.cpp @@ -37,13 +37,18 @@ namespace squish { static int FixFlags( int flags ) { // grab the flag bits - int method = flags & ( kDxt1 | kDxt3 | kDxt5 ); + int method = flags & ( kDxt1 | kDxt3 | kDxt5 | kBc4 | kBc5 ); int fit = flags & ( kColourIterativeClusterFit | kColourClusterFit | kColourRangeFit ); int extra = flags & kWeightColourByAlpha; // set defaults - if( method != kDxt3 && method != kDxt5 ) + if ( method != kDxt3 + && method != kDxt5 + && method != kBc4 + && method != kBc5 ) + { method = kDxt1; + } if( fit != kColourRangeFit && fit != kColourIterativeClusterFit ) fit = kColourClusterFit; @@ -56,9 +61,34 @@ void CompressMasked( u8 const* rgba, int mask, void* block, int flags, float* me // fix any bad flags flags = FixFlags( flags ); + if ( ( flags & ( kBc4 | kBc5 ) ) != 0 ) + { + u8 alpha[16*4]; + for( int i = 0; i < 16; ++i ) + { + alpha[i*4 + 3] = rgba[i*4 + 0]; // copy R to A + } + + u8* rBlock = reinterpret_cast< u8* >( block ); + CompressAlphaDxt5( alpha, mask, rBlock ); + + if ( ( flags & ( kBc5 ) ) != 0 ) + { + for( int i = 0; i < 16; ++i ) + { + alpha[i*4 + 3] = rgba[i*4 + 1]; // copy G to A + } + + u8* gBlock = reinterpret_cast< u8* >( block ) + 8; + CompressAlphaDxt5( alpha, mask, gBlock ); + } + + return; + } + // get the block locations void* colourBlock = block; - void* alphaBock = block; + void* alphaBlock = block; if( ( flags & ( kDxt3 | kDxt5 ) ) != 0 ) colourBlock = reinterpret_cast< u8* >( block ) + 8; @@ -87,9 +117,9 @@ void CompressMasked( u8 const* rgba, int mask, void* block, int flags, float* me // compress alpha separately if necessary if( ( flags & kDxt3 ) != 0 ) - CompressAlphaDxt3( rgba, mask, alphaBock ); + CompressAlphaDxt3( rgba, mask, alphaBlock ); else if( ( flags & kDxt5 ) != 0 ) - CompressAlphaDxt5( rgba, mask, alphaBock ); + CompressAlphaDxt5( rgba, mask, alphaBlock ); } void Decompress( u8* rgba, void const* block, int flags ) @@ -120,7 +150,7 @@ int GetStorageRequirements( int width, int height, int flags ) // compute the storage requirements int blockcount = ( ( width + 3 )/4 ) * ( ( height + 3 )/4 ); - int blocksize = ( ( flags & kDxt1 ) != 0 ) ? 8 : 16; + int blocksize = ( ( flags & ( kDxt1 | kBc4 ) ) != 0 ) ? 8 : 16; return blockcount*blocksize; } @@ -131,7 +161,7 @@ void CompressImage( u8 const* rgba, int width, int height, void* blocks, int fla // initialise the block output u8* targetBlock = reinterpret_cast< u8* >( blocks ); - int bytesPerBlock = ( ( flags & kDxt1 ) != 0 ) ? 8 : 16; + int bytesPerBlock = ( ( flags & ( kDxt1 | kBc4 ) ) != 0 ) ? 8 : 16; // loop over blocks for( int y = 0; y < height; y += 4 ) @@ -185,7 +215,7 @@ void DecompressImage( u8* rgba, int width, int height, void const* blocks, int f // initialise the block input u8 const* sourceBlock = reinterpret_cast< u8 const* >( blocks ); - int bytesPerBlock = ( ( flags & kDxt1 ) != 0 ) ? 8 : 16; + int bytesPerBlock = ( ( flags & ( kDxt1 | kBc4 ) ) != 0 ) ? 8 : 16; // loop over blocks for( int y = 0; y < height; y += 4 ) diff --git a/3rdparty/libsquish/squish.h b/3rdparty/libsquish/squish.h index 212b54c3..ad75138d 100644 --- a/3rdparty/libsquish/squish.h +++ b/3rdparty/libsquish/squish.h @@ -39,23 +39,29 @@ typedef unsigned char u8; enum { //! Use DXT1 compression. - kDxt1 = ( 1 << 0 ), - + kDxt1 = ( 1 << 0 ), + //! Use DXT3 compression. - kDxt3 = ( 1 << 1 ), - + kDxt3 = ( 1 << 1 ), + //! Use DXT5 compression. - kDxt5 = ( 1 << 2 ), - + kDxt5 = ( 1 << 2 ), + + //! Use BC4 compression. + kBc4 = ( 1 << 3 ), + + //! Use BC5 compression. + kBc5 = ( 1 << 4 ), + //! Use a very slow but very high quality colour compressor. kColourIterativeClusterFit = ( 1 << 8 ), - + //! Use a slow but high quality colour compressor (the default). kColourClusterFit = ( 1 << 3 ), - + //! Use a fast but low quality colour compressor. kColourRangeFit = ( 1 << 4 ), - + //! Weight the colour by alpha during cluster fit (disabled by default). kWeightColourByAlpha = ( 1 << 7 ) }; diff --git a/src/image.cpp b/src/image.cpp index 3f728450..737f482b 100644 --- a/src/image.cpp +++ b/src/image.cpp @@ -1609,18 +1609,19 @@ namespace bgfx } } - _imageContainer.m_data = NULL; - _imageContainer.m_size = 0; - _imageContainer.m_offset = (uint32_t)bx::seek(_reader); - _imageContainer.m_width = width; - _imageContainer.m_height = height; - _imageContainer.m_depth = depth; + _imageContainer.m_data = NULL; + _imageContainer.m_size = 0; + _imageContainer.m_offset = (uint32_t)bx::seek(_reader); + _imageContainer.m_width = width; + _imageContainer.m_height = height; + _imageContainer.m_depth = depth; _imageContainer.m_format = uint8_t(format); _imageContainer.m_numMips = uint8_t( (caps[0] & DDSCAPS_MIPMAP) ? mips : 1); _imageContainer.m_hasAlpha = hasAlpha; _imageContainer.m_cubeMap = cubeMap; - _imageContainer.m_ktx = false; - _imageContainer.m_srgb = srgb; + _imageContainer.m_ktx = false; + _imageContainer.m_ktxLE = false; + _imageContainer.m_srgb = srgb; return TextureFormat::Unknown != format; } @@ -1896,6 +1897,7 @@ namespace bgfx _imageContainer.m_cubeMap = numFaces > 1; _imageContainer.m_ktx = true; _imageContainer.m_ktxLE = fromLittleEndian; + _imageContainer.m_srgb = false; return TextureFormat::Unknown != format; } diff --git a/tools/texturec/texturec.cpp b/tools/texturec/texturec.cpp index dbb8d508..8502e30a 100644 --- a/tools/texturec/texturec.cpp +++ b/tools/texturec/texturec.cpp @@ -40,6 +40,54 @@ namespace bgfx ::free(mem); } + void imageEncodeFromRgba8(uint8_t* _dst, const uint8_t* _src, uint32_t _width, uint32_t _height, uint8_t _format) + { + TextureFormat::Enum format = TextureFormat::Enum(_format); + + switch (format) + { + case TextureFormat::BC1: + case TextureFormat::BC2: + case TextureFormat::BC3: + case TextureFormat::BC4: + case TextureFormat::BC5: + squish::CompressImage(_src, _width, _height, _dst + , format == TextureFormat::BC1 ? squish::kDxt1 + : format == TextureFormat::BC2 ? squish::kDxt3 + : format == TextureFormat::BC3 ? squish::kDxt5 + : format == TextureFormat::BC4 ? squish::kBc4 + : squish::kBc5 + ); + break; + + case TextureFormat::BC6H: + nvtt::compressBC6H(_src, _width, _height, 4, _dst); + break; + + case TextureFormat::BC7: + nvtt::compressBC7(_src, _width, _height, 4, _dst); + break; + + case TextureFormat::ETC1: + etc1_encode_image(_src, _width, _height, 4, _width*4, _dst); + break; + + case TextureFormat::ETC2: + case TextureFormat::ETC2A: + case TextureFormat::ETC2A1: + case TextureFormat::PTC12: + case TextureFormat::PTC14: + case TextureFormat::PTC12A: + case TextureFormat::PTC14A: + case TextureFormat::PTC22: + case TextureFormat::PTC24: + break; + + default: + break; + } + } + } // namespace bgfx void help(const char* _error = NULL) @@ -110,6 +158,14 @@ int main(int _argc, const char* _argv[]) { format = TextureFormat::BC3; } + else if (0 == bx::stricmp(type, "bc4") ) + { + format = TextureFormat::BC4; + } + else if (0 == bx::stricmp(type, "bc5") ) + { + format = TextureFormat::BC5; + } else if (0 == bx::stricmp(type, "etc1") ) { format = TextureFormat::ETC1; @@ -134,6 +190,7 @@ int main(int _argc, const char* _argv[]) bool loaded = imageParse(imageContainer, mem->data, mem->size); if (!loaded) { + } BX_UNUSED(mips); @@ -151,48 +208,8 @@ int main(int _argc, const char* _argv[]) output = (uint8_t*)BX_ALLOC(&allocator, imageGetSize(format, mip.m_width, mip.m_height) ); - switch (format) - { - case TextureFormat::BC1: - case TextureFormat::BC2: - case TextureFormat::BC3: - squish::CompressImage(rgba, mip.m_width, mip.m_height, output - , format == TextureFormat::BC1 ? squish::kDxt1 - : format == TextureFormat::BC2 ? squish::kDxt3 - : squish::kDxt5 - ); - break; - - case TextureFormat::BC4: - case TextureFormat::BC5: - break; - - case TextureFormat::BC6H: - nvtt::compressBC6H(rgba, mip.m_width, mip.m_height, 4, output); - break; - - case TextureFormat::BC7: - nvtt::compressBC7(rgba, mip.m_width, mip.m_height, 4, output); - break; - - case TextureFormat::ETC1: - etc1_encode_image(rgba, mip.m_width, mip.m_height, 4, mip.m_width*4, output); - break; - - case TextureFormat::ETC2: - case TextureFormat::ETC2A: - case TextureFormat::ETC2A1: - case TextureFormat::PTC12: - case TextureFormat::PTC14: - case TextureFormat::PTC12A: - case TextureFormat::PTC14A: - case TextureFormat::PTC22: - case TextureFormat::PTC24: - break; - - default: - break; - } + imageContainer.m_format = format; + imageEncodeFromRgba8(output, rgba, mip.m_width, mip.m_height, format); BX_FREE(&allocator, rgba); }