PDA

View Full Version : Flipping ATI2/3DC/BC5/RGTC/LATC DXT blocks



remdul
02-07-2017, 07:34 AM
Some people prefer to vertically flip DDS images (without decompressing) in their texture loaders. There's code around (nv_dds.cpp) that does this for DXT1/DXT3/DXT5 but not for ATI2/3DC/BC5/RGTC/LATC (which should all be one and the same format).

So does anyone have a code snippet, or could give someone a pointer/hint on how to do this? Plain DXT5 block flipping doesn't work for this format.

See: https://github.com/paroj/nv_dds/blob/master/nv_dds.cpp

remdul
02-07-2017, 08:02 AM
Well I realized shortly after posting that the answer was right under my nose. The ATI2 format of course uses the same compression format for both channels, so the code is already there to do the trick.

The relevant DXT5 flipping code (from the above linked source file):



void flip_blocks_dxtc5(DXTColBlock *line, unsigned int numBlocks)
{
DXTColBlock *curblock = line;
DXT5AlphaBlock *alphablock;

for (unsigned int i = 0; i < numBlocks; i++)
{
// this flips DXT5 alpha block
alphablock = (DXT5AlphaBlock*) curblock;
flip_dxt5_alpha(alphablock);
curblock++;

// this flips DXT5 color block
std::swap(curblock->row[0], curblock->row[3]);
std::swap(curblock->row[1], curblock->row[2]);
curblock++;
}
}


For ATI2 format, the added code becomes:



void flip_blocks_ati2(DXTColBlock *line, unsigned int numBlocks)
{
DXTColBlock *curblock = line;
DXT5AlphaBlock *colorblock;
DXT5AlphaBlock *alphablock;

for (unsigned int i = 0; i < numBlocks; i++)
{
// this flips ATI2 R block
alphablock = (DXT5AlphaBlock*) curblock;
flip_dxt5_alpha(alphablock);
curblock++;

// this flips ATI2 G block
colorblock = (DXT5AlphaBlock*) curblock;
flip_dxt5_alpha(colorblock);
curblock++;
}
}


So effectively both channel sub-blocks are treated as DXT5 alpha channel blocks to flip them, which works like a charm.

Of course you need to register the flip_blocks_ati2 callback based on the DDS FOURCC elsewhere in the code.

Cheers!