Fix a few issues that we had with dealing with alpha in the textures.

This commit is contained in:
Pavel Krajcevski 2012-10-21 16:34:19 -04:00
parent d51df5f9a2
commit 82e51a49cf
3 changed files with 55 additions and 30 deletions

View file

@ -111,8 +111,7 @@ private:
// If we handle alpha separately, then we will consider the alpha channel // If we handle alpha separately, then we will consider the alpha channel
// to be not used whenever we do any calculations... // to be not used whenever we do any calculations...
int GetAlphaChannelPrecision() const { int GetAlphaChannelPrecision() const {
if(m_Attributes->hasRotation) return 0; return m_Attributes->alphaChannelPrecision;
else return m_Attributes->alphaChannelPrecision;
} }
RGBAVector GetErrorMetric() const { RGBAVector GetErrorMetric() const {
@ -130,12 +129,23 @@ private:
unsigned int GetQuantizationMask() const { unsigned int GetQuantizationMask() const {
const int maskSeed = 0x80000000; const int maskSeed = 0x80000000;
return ( const uint32 alphaPrec = GetAlphaChannelPrecision();
(maskSeed >> (24 + m_Attributes->colorChannelPrecision - 1) & 0xFF) | if(alphaPrec > 0) {
(maskSeed >> (16 + m_Attributes->colorChannelPrecision - 1) & 0xFF00) | return (
(maskSeed >> (8 + m_Attributes->colorChannelPrecision - 1) & 0xFF0000) | (maskSeed >> (24 + m_Attributes->colorChannelPrecision - 1) & 0xFF) |
(maskSeed >> (GetAlphaChannelPrecision() - 1) & 0xFF000000) (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 { int GetNumPbitCombos() const {

View file

@ -1502,9 +1502,13 @@ namespace BC7C
DecompressBC7Block(block, unComp); DecompressBC7Block(block, unComp);
uint8* unCompData = (uint8 *)unComp; uint8* unCompData = (uint8 *)unComp;
int diffSum = 0; double diffSum = 0.0;
for(int i = 0; i < 64; i++) { for(int i = 0; i < 64; i+=4) {
diffSum += sad(unCompData[i], inBuf[i]); 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; double blockError = double(diffSum) / 64.0;
if(blockError > 50.0) { if(blockError > 50.0) {
@ -2320,9 +2324,16 @@ namespace BC7C
uint32 ap = attrs->alphaChannelPrecision; uint32 ap = attrs->alphaChannelPrecision;
const uint32 ash = 8 - ap; const uint32 ash = 8 - ap;
for(uint32 i = 0; i < nSubsets; i++) if(ap == 0) {
for(uint32 ep = 0; ep < 2; ep++) for(uint32 i = 0; i < nSubsets; i++)
eps[i][ep][3] = strm.ReadBits(ap) << ash; 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 // Handle pbits
switch(attrs->pbitType) { switch(attrs->pbitType) {
@ -2431,22 +2442,20 @@ namespace BC7C
pixel = 0; pixel = 0;
for(int ch = 0; ch < 4; ch++) { for(int ch = 0; ch < 4; ch++) {
uint32 i0 = kBC7InterpolationValues[nBitsPerColor - 1][colorIndices[i]][0]; if(ch == 3 && nBitsPerAlpha > 0) {
uint32 i1 = kBC7InterpolationValues[nBitsPerColor - 1][colorIndices[i]][1]; 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; const uint8 ip = (((uint32(eps[subset][0][3]) * i0) + (uint32(eps[subset][1][3]) * i1) + 32) >> 6) & 0xFF;
pixel |= ip << (8*ch); pixel |= ip << 24;
} }
else {
uint32 i0 = kBC7InterpolationValues[nBitsPerColor - 1][colorIndices[i]][0];
uint32 i1 = kBC7InterpolationValues[nBitsPerColor - 1][colorIndices[i]][1];
if(attrs->alphaChannelPrecision > 0) { const uint8 ip = (((uint32(eps[subset][0][ch]) * i0) + (uint32(eps[subset][1][ch]) * i1) + 32) >> 6) & 0xFF;
uint32 i0 = kBC7InterpolationValues[nBitsPerAlpha - 1][alphaIndices[i]][0]; pixel |= ip << (8*ch);
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... // Swap colors if necessary...

View file

@ -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 the mask is all the bits, then we can just return the value.
if(mask == 0xFF) { 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); uint32 prec = CountBitsInMask(mask);
const uint32 step = 1 << (8 - prec); const uint32 step = 1 << (8 - prec);