mirror of
https://github.com/scratchfoundation/bgfx.git
synced 2024-11-24 16:48:18 -05:00
texturec: Added BC4/5 compression.
This commit is contained in:
parent
1a96194429
commit
c82d3e86d9
5 changed files with 124 additions and 67 deletions
2
3rdparty/.editorconfig
vendored
2
3rdparty/.editorconfig
vendored
|
@ -11,3 +11,5 @@ indent_size = 4
|
||||||
[remotery/*]
|
[remotery/*]
|
||||||
indent_style = space
|
indent_style = space
|
||||||
indent_size = 4
|
indent_size = 4
|
||||||
|
|
||||||
|
[libsquish/*]
|
||||||
|
|
46
3rdparty/libsquish/squish.cpp
vendored
46
3rdparty/libsquish/squish.cpp
vendored
|
@ -37,13 +37,18 @@ namespace squish {
|
||||||
static int FixFlags( int flags )
|
static int FixFlags( int flags )
|
||||||
{
|
{
|
||||||
// grab the flag bits
|
// 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 fit = flags & ( kColourIterativeClusterFit | kColourClusterFit | kColourRangeFit );
|
||||||
int extra = flags & kWeightColourByAlpha;
|
int extra = flags & kWeightColourByAlpha;
|
||||||
|
|
||||||
// set defaults
|
// set defaults
|
||||||
if( method != kDxt3 && method != kDxt5 )
|
if ( method != kDxt3
|
||||||
|
&& method != kDxt5
|
||||||
|
&& method != kBc4
|
||||||
|
&& method != kBc5 )
|
||||||
|
{
|
||||||
method = kDxt1;
|
method = kDxt1;
|
||||||
|
}
|
||||||
if( fit != kColourRangeFit && fit != kColourIterativeClusterFit )
|
if( fit != kColourRangeFit && fit != kColourIterativeClusterFit )
|
||||||
fit = kColourClusterFit;
|
fit = kColourClusterFit;
|
||||||
|
|
||||||
|
@ -56,9 +61,34 @@ void CompressMasked( u8 const* rgba, int mask, void* block, int flags, float* me
|
||||||
// fix any bad flags
|
// fix any bad flags
|
||||||
flags = FixFlags( 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
|
// get the block locations
|
||||||
void* colourBlock = block;
|
void* colourBlock = block;
|
||||||
void* alphaBock = block;
|
void* alphaBlock = block;
|
||||||
if( ( flags & ( kDxt3 | kDxt5 ) ) != 0 )
|
if( ( flags & ( kDxt3 | kDxt5 ) ) != 0 )
|
||||||
colourBlock = reinterpret_cast< u8* >( block ) + 8;
|
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
|
// compress alpha separately if necessary
|
||||||
if( ( flags & kDxt3 ) != 0 )
|
if( ( flags & kDxt3 ) != 0 )
|
||||||
CompressAlphaDxt3( rgba, mask, alphaBock );
|
CompressAlphaDxt3( rgba, mask, alphaBlock );
|
||||||
else if( ( flags & kDxt5 ) != 0 )
|
else if( ( flags & kDxt5 ) != 0 )
|
||||||
CompressAlphaDxt5( rgba, mask, alphaBock );
|
CompressAlphaDxt5( rgba, mask, alphaBlock );
|
||||||
}
|
}
|
||||||
|
|
||||||
void Decompress( u8* rgba, void const* block, int flags )
|
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
|
// compute the storage requirements
|
||||||
int blockcount = ( ( width + 3 )/4 ) * ( ( height + 3 )/4 );
|
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;
|
return blockcount*blocksize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -131,7 +161,7 @@ void CompressImage( u8 const* rgba, int width, int height, void* blocks, int fla
|
||||||
|
|
||||||
// initialise the block output
|
// initialise the block output
|
||||||
u8* targetBlock = reinterpret_cast< u8* >( blocks );
|
u8* targetBlock = reinterpret_cast< u8* >( blocks );
|
||||||
int bytesPerBlock = ( ( flags & kDxt1 ) != 0 ) ? 8 : 16;
|
int bytesPerBlock = ( ( flags & ( kDxt1 | kBc4 ) ) != 0 ) ? 8 : 16;
|
||||||
|
|
||||||
// loop over blocks
|
// loop over blocks
|
||||||
for( int y = 0; y < height; y += 4 )
|
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
|
// initialise the block input
|
||||||
u8 const* sourceBlock = reinterpret_cast< u8 const* >( blocks );
|
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
|
// loop over blocks
|
||||||
for( int y = 0; y < height; y += 4 )
|
for( int y = 0; y < height; y += 4 )
|
||||||
|
|
24
3rdparty/libsquish/squish.h
vendored
24
3rdparty/libsquish/squish.h
vendored
|
@ -39,23 +39,29 @@ typedef unsigned char u8;
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
//! Use DXT1 compression.
|
//! Use DXT1 compression.
|
||||||
kDxt1 = ( 1 << 0 ),
|
kDxt1 = ( 1 << 0 ),
|
||||||
|
|
||||||
//! Use DXT3 compression.
|
//! Use DXT3 compression.
|
||||||
kDxt3 = ( 1 << 1 ),
|
kDxt3 = ( 1 << 1 ),
|
||||||
|
|
||||||
//! Use DXT5 compression.
|
//! 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.
|
//! Use a very slow but very high quality colour compressor.
|
||||||
kColourIterativeClusterFit = ( 1 << 8 ),
|
kColourIterativeClusterFit = ( 1 << 8 ),
|
||||||
|
|
||||||
//! Use a slow but high quality colour compressor (the default).
|
//! Use a slow but high quality colour compressor (the default).
|
||||||
kColourClusterFit = ( 1 << 3 ),
|
kColourClusterFit = ( 1 << 3 ),
|
||||||
|
|
||||||
//! Use a fast but low quality colour compressor.
|
//! Use a fast but low quality colour compressor.
|
||||||
kColourRangeFit = ( 1 << 4 ),
|
kColourRangeFit = ( 1 << 4 ),
|
||||||
|
|
||||||
//! Weight the colour by alpha during cluster fit (disabled by default).
|
//! Weight the colour by alpha during cluster fit (disabled by default).
|
||||||
kWeightColourByAlpha = ( 1 << 7 )
|
kWeightColourByAlpha = ( 1 << 7 )
|
||||||
};
|
};
|
||||||
|
|
|
@ -1609,18 +1609,19 @@ namespace bgfx
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_imageContainer.m_data = NULL;
|
_imageContainer.m_data = NULL;
|
||||||
_imageContainer.m_size = 0;
|
_imageContainer.m_size = 0;
|
||||||
_imageContainer.m_offset = (uint32_t)bx::seek(_reader);
|
_imageContainer.m_offset = (uint32_t)bx::seek(_reader);
|
||||||
_imageContainer.m_width = width;
|
_imageContainer.m_width = width;
|
||||||
_imageContainer.m_height = height;
|
_imageContainer.m_height = height;
|
||||||
_imageContainer.m_depth = depth;
|
_imageContainer.m_depth = depth;
|
||||||
_imageContainer.m_format = uint8_t(format);
|
_imageContainer.m_format = uint8_t(format);
|
||||||
_imageContainer.m_numMips = uint8_t( (caps[0] & DDSCAPS_MIPMAP) ? mips : 1);
|
_imageContainer.m_numMips = uint8_t( (caps[0] & DDSCAPS_MIPMAP) ? mips : 1);
|
||||||
_imageContainer.m_hasAlpha = hasAlpha;
|
_imageContainer.m_hasAlpha = hasAlpha;
|
||||||
_imageContainer.m_cubeMap = cubeMap;
|
_imageContainer.m_cubeMap = cubeMap;
|
||||||
_imageContainer.m_ktx = false;
|
_imageContainer.m_ktx = false;
|
||||||
_imageContainer.m_srgb = srgb;
|
_imageContainer.m_ktxLE = false;
|
||||||
|
_imageContainer.m_srgb = srgb;
|
||||||
|
|
||||||
return TextureFormat::Unknown != format;
|
return TextureFormat::Unknown != format;
|
||||||
}
|
}
|
||||||
|
@ -1896,6 +1897,7 @@ namespace bgfx
|
||||||
_imageContainer.m_cubeMap = numFaces > 1;
|
_imageContainer.m_cubeMap = numFaces > 1;
|
||||||
_imageContainer.m_ktx = true;
|
_imageContainer.m_ktx = true;
|
||||||
_imageContainer.m_ktxLE = fromLittleEndian;
|
_imageContainer.m_ktxLE = fromLittleEndian;
|
||||||
|
_imageContainer.m_srgb = false;
|
||||||
|
|
||||||
return TextureFormat::Unknown != format;
|
return TextureFormat::Unknown != format;
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,6 +40,54 @@ namespace bgfx
|
||||||
::free(mem);
|
::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
|
} // namespace bgfx
|
||||||
|
|
||||||
void help(const char* _error = NULL)
|
void help(const char* _error = NULL)
|
||||||
|
@ -110,6 +158,14 @@ int main(int _argc, const char* _argv[])
|
||||||
{
|
{
|
||||||
format = TextureFormat::BC3;
|
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") )
|
else if (0 == bx::stricmp(type, "etc1") )
|
||||||
{
|
{
|
||||||
format = TextureFormat::ETC1;
|
format = TextureFormat::ETC1;
|
||||||
|
@ -134,6 +190,7 @@ int main(int _argc, const char* _argv[])
|
||||||
bool loaded = imageParse(imageContainer, mem->data, mem->size);
|
bool loaded = imageParse(imageContainer, mem->data, mem->size);
|
||||||
if (!loaded)
|
if (!loaded)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
BX_UNUSED(mips);
|
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) );
|
output = (uint8_t*)BX_ALLOC(&allocator, imageGetSize(format, mip.m_width, mip.m_height) );
|
||||||
|
|
||||||
switch (format)
|
imageContainer.m_format = format;
|
||||||
{
|
imageEncodeFromRgba8(output, rgba, mip.m_width, mip.m_height, 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
BX_FREE(&allocator, rgba);
|
BX_FREE(&allocator, rgba);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue