From 82e51a49cf761d4db37c6f2a7ba4a27ac13f72d2 Mon Sep 17 00:00:00 2001 From: Pavel Krajcevski Date: Sun, 21 Oct 2012 16:34:19 -0400 Subject: [PATCH] Fix a few issues that we had with dealing with alpha in the textures. --- BPTCEncoder/src/BC7CompressionMode.h | 26 +++++++++----- BPTCEncoder/src/BC7Compressor.cpp | 51 ++++++++++++++++------------ BPTCEncoder/src/RGBAEndpoints.cpp | 8 ++++- 3 files changed, 55 insertions(+), 30 deletions(-) diff --git a/BPTCEncoder/src/BC7CompressionMode.h b/BPTCEncoder/src/BC7CompressionMode.h index 94c53e8..edf4aa4 100755 --- a/BPTCEncoder/src/BC7CompressionMode.h +++ b/BPTCEncoder/src/BC7CompressionMode.h @@ -111,8 +111,7 @@ private: // If we handle alpha separately, then we will consider the alpha channel // to be not used whenever we do any calculations... int GetAlphaChannelPrecision() const { - if(m_Attributes->hasRotation) return 0; - else return m_Attributes->alphaChannelPrecision; + return m_Attributes->alphaChannelPrecision; } RGBAVector GetErrorMetric() const { @@ -130,12 +129,23 @@ private: unsigned int GetQuantizationMask() const { const int maskSeed = 0x80000000; - return ( - (maskSeed >> (24 + m_Attributes->colorChannelPrecision - 1) & 0xFF) | - (maskSeed >> (16 + m_Attributes->colorChannelPrecision - 1) & 0xFF00) | - (maskSeed >> (8 + m_Attributes->colorChannelPrecision - 1) & 0xFF0000) | - (maskSeed >> (GetAlphaChannelPrecision() - 1) & 0xFF000000) - ); + const uint32 alphaPrec = GetAlphaChannelPrecision(); + if(alphaPrec > 0) { + return ( + (maskSeed >> (24 + m_Attributes->colorChannelPrecision - 1) & 0xFF) | + (maskSeed >> (16 + m_Attributes->colorChannelPrecision - 1) & 0xFF00) | + (maskSeed >> (8 + m_Attributes->colorChannelPrecision - 1) & 0xFF0000) | + (maskSeed >> (GetAlphaChannelPrecision() - 1) & 0xFF000000) + ); + } + else { + return ( + (maskSeed >> (24 + m_Attributes->colorChannelPrecision - 1) & 0xFF) | + (maskSeed >> (16 + m_Attributes->colorChannelPrecision - 1) & 0xFF00) | + (maskSeed >> (8 + m_Attributes->colorChannelPrecision - 1) & 0xFF0000) & + (0x00FFFFFF) + ); + } } int GetNumPbitCombos() const { diff --git a/BPTCEncoder/src/BC7Compressor.cpp b/BPTCEncoder/src/BC7Compressor.cpp index ca23a36..6105ac7 100755 --- a/BPTCEncoder/src/BC7Compressor.cpp +++ b/BPTCEncoder/src/BC7Compressor.cpp @@ -1502,9 +1502,13 @@ namespace BC7C DecompressBC7Block(block, unComp); uint8* unCompData = (uint8 *)unComp; - int diffSum = 0; - for(int i = 0; i < 64; i++) { - diffSum += sad(unCompData[i], inBuf[i]); + double diffSum = 0.0; + for(int i = 0; i < 64; i+=4) { + double rdiff = sad(unCompData[i], inBuf[i]); + double gdiff = sad(unCompData[i+1], inBuf[i+1]); + double bdiff = sad(unCompData[i+2], inBuf[i+2]); + double adiff = sad(unCompData[i+3], inBuf[i+3]); + diffSum += (rdiff + gdiff + bdiff + adiff) * ((unCompData[i+3] + inBuf[i+3])*0.5); } double blockError = double(diffSum) / 64.0; if(blockError > 50.0) { @@ -2320,9 +2324,16 @@ namespace BC7C uint32 ap = attrs->alphaChannelPrecision; const uint32 ash = 8 - ap; - for(uint32 i = 0; i < nSubsets; i++) - for(uint32 ep = 0; ep < 2; ep++) - eps[i][ep][3] = strm.ReadBits(ap) << ash; + if(ap == 0) { + for(uint32 i = 0; i < nSubsets; i++) + for(uint32 ep = 0; ep < 2; ep++) + eps[i][ep][3] = 0xFF; + } + else { + for(uint32 i = 0; i < nSubsets; i++) + for(uint32 ep = 0; ep < 2; ep++) + eps[i][ep][3] = strm.ReadBits(ap) << ash; + } // Handle pbits switch(attrs->pbitType) { @@ -2431,24 +2442,22 @@ namespace BC7C pixel = 0; for(int ch = 0; ch < 4; ch++) { - uint32 i0 = kBC7InterpolationValues[nBitsPerColor - 1][colorIndices[i]][0]; - uint32 i1 = kBC7InterpolationValues[nBitsPerColor - 1][colorIndices[i]][1]; + if(ch == 3 && nBitsPerAlpha > 0) { + uint32 i0 = kBC7InterpolationValues[nBitsPerAlpha - 1][alphaIndices[i]][0]; + uint32 i1 = kBC7InterpolationValues[nBitsPerAlpha - 1][alphaIndices[i]][1]; - const uint8 ip = (((uint32(eps[subset][0][ch]) * i0) + (uint32(eps[subset][1][ch]) * i1) + 32) >> 6) & 0xFF; - pixel |= ip << (8*ch); + const uint8 ip = (((uint32(eps[subset][0][3]) * i0) + (uint32(eps[subset][1][3]) * i1) + 32) >> 6) & 0xFF; + pixel |= ip << 24; + } + else { + uint32 i0 = kBC7InterpolationValues[nBitsPerColor - 1][colorIndices[i]][0]; + uint32 i1 = kBC7InterpolationValues[nBitsPerColor - 1][colorIndices[i]][1]; + + const uint8 ip = (((uint32(eps[subset][0][ch]) * i0) + (uint32(eps[subset][1][ch]) * i1) + 32) >> 6) & 0xFF; + pixel |= ip << (8*ch); + } } - if(attrs->alphaChannelPrecision > 0) { - uint32 i0 = kBC7InterpolationValues[nBitsPerAlpha - 1][alphaIndices[i]][0]; - uint32 i1 = kBC7InterpolationValues[nBitsPerAlpha - 1][alphaIndices[i]][1]; - - const uint8 ip = (((uint32(eps[subset][0][3]) * i0) + (uint32(eps[subset][1][3]) * i1) + 32) >> 6) & 0xFF; - pixel |= ip << 24; - } - else { - pixel |= 0xFF000000; - } - // Swap colors if necessary... uint8 *pb = (uint8 *)&pixel; switch(rotMode) { diff --git a/BPTCEncoder/src/RGBAEndpoints.cpp b/BPTCEncoder/src/RGBAEndpoints.cpp index 512af09..6a02713 100755 --- a/BPTCEncoder/src/RGBAEndpoints.cpp +++ b/BPTCEncoder/src/RGBAEndpoints.cpp @@ -140,9 +140,15 @@ uint8 QuantizeChannel(const uint8 val, const uint8 mask, const int pBit) { // If the mask is all the bits, then we can just return the value. if(mask == 0xFF) { - return val; + return val; } + // Otherwise if the mask is no bits then we'll assume that they want + // all the bits ... this is only really relevant for alpha... + if(mask == 0x0) { + return 0xFF; + } + uint32 prec = CountBitsInMask(mask); const uint32 step = 1 << (8 - prec);