private void UnpackDXTColour(PixelFormat pf, DXTColorBlock block, ColorEx[] pCol)
{
// Note - we assume all values have already been endian swapped
// Colour lookup table
ColorEx[] derivedColours = new ColorEx[4];
IntPtr color0 = Memory.PinObject( block.Color0 );
IntPtr color1 = Memory.PinObject( block.Color1 );
if ( pf == PixelFormat.DXT1 && block.Color0 <= block.Color1 )
{
// 1-bit alpha
derivedColours[ 0 ] = PixelConverter.UnpackColor( PixelFormat.R5G6B5, color0 );
derivedColours[ 1 ] = PixelConverter.UnpackColor( PixelFormat.R5G6B5, color1 );
// one intermediate colour, half way between the other two
derivedColours[ 2 ] = ( derivedColours[ 0 ] + derivedColours[ 1 ] ) / 2;
// transparent colour
derivedColours[ 3 ] = ColorEx.Black;
}
else
{
derivedColours[ 0 ] = PixelConverter.UnpackColor( PixelFormat.R5G6B5, color0 );
derivedColours[ 1 ] = PixelConverter.UnpackColor( PixelFormat.R5G6B5, color1 );
// first interpolated colour, 1/3 of the way along
derivedColours[ 2 ] = ( derivedColours[ 0 ] * 2f + derivedColours[ 1 ] ) / 3;
// second interpolated colour, 2/3 of the way along
derivedColours[ 3 ] = ( derivedColours[ 0 ] + derivedColours[ 1 ] * 2f ) / 3;
}
Memory.UnpinObject( block.Color0 );
Memory.UnpinObject( block.Color1 );
// Process 4x4 block of texels
for ( int row = 0; row < 4; ++row )
{
for ( int x = 0; x < 4; ++x )
{
// LSB come first
int colIdx = ( block.IndexRow[ row ] >> ( x * 2 ) & 0x3 );
if ( pf == PixelFormat.DXT1 )
{
// Overwrite entire colour
pCol[ ( row * 4 ) + x ] = derivedColours[ colIdx ];
}
else
{
// alpha has already been read (alpha precedes color)
ColorEx col = pCol[ ( row * 4 ) + x ];
col.r = derivedColours[ colIdx ].r;
col.g = derivedColours[ colIdx ].g;
col.b = derivedColours[ colIdx ].b;
}
}
}
}