mirror of https://github.com/bkaradzic/bgfx
texturec: Added BC4/5 compression.
This commit is contained in:
parent
1a96194429
commit
c82d3e86d9
|
@ -11,3 +11,5 @@ indent_size = 4
|
|||
[remotery/*]
|
||||
indent_style = space
|
||||
indent_size = 4
|
||||
|
||||
[libsquish/*]
|
||||
|
|
|
@ -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 )
|
||||
|
|
|
@ -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 )
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue