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
// 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 {

View file

@ -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) {

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(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);