- Added true color processing to FDDSTexture. This is untested so far

because I don't have any DDS textures to check it with.


SVN r609 (trunk)
This commit is contained in:
Christoph Oelckers 2007-12-20 20:00:05 +00:00
parent 28db2d9f15
commit b88f46736b
3 changed files with 128 additions and 25 deletions

View file

@ -1,4 +1,6 @@
December 20, 2007 (Changes by Graf Zahl) December 20, 2007 (Changes by Graf Zahl)
- Added true color processing to FDDSTexture. This is untested so far
because I don't have any DDS textures to check it with.
- Fixed: FTexture::~FTexture() must destroy the associated native texture - Fixed: FTexture::~FTexture() must destroy the associated native texture
if present. if present.
- Modified GZDoom's true color texture copy functions and added them - Modified GZDoom's true color texture copy functions and added them

View file

@ -299,10 +299,13 @@ protected:
static void CalcBitShift (DWORD mask, BYTE *lshift, BYTE *rshift); static void CalcBitShift (DWORD mask, BYTE *lshift, BYTE *rshift);
void MakeTexture (); void MakeTexture ();
void ReadRGB (FWadLump &lump); void ReadRGB (FWadLump &lump, BYTE *tcbuf = NULL);
void DecompressDXT1 (FWadLump &lump); void DecompressDXT1 (FWadLump &lump, BYTE *tcbuf = NULL);
void DecompressDXT3 (FWadLump &lump, bool premultiplied); void DecompressDXT3 (FWadLump &lump, bool premultiplied, BYTE *tcbuf = NULL);
void DecompressDXT5 (FWadLump &lump, bool premultiplied); void DecompressDXT5 (FWadLump &lump, bool premultiplied, BYTE *tcbuf = NULL);
int CopyTrueColorPixels(BYTE * buffer, int buf_width, int buf_height, int x, int y);
bool UseBasePalette();
friend class FTexture; friend class FTexture;
}; };

View file

@ -390,7 +390,7 @@ void FDDSTexture::MakeTexture ()
} }
} }
void FDDSTexture::ReadRGB (FWadLump &lump) void FDDSTexture::ReadRGB (FWadLump &lump, BYTE *tcbuf)
{ {
DWORD x, y; DWORD x, y;
DWORD amask = AMask == 0 ? 0 : 0x80000000 >> AShiftL; DWORD amask = AMask == 0 ? 0 : 0x80000000 >> AShiftL;
@ -399,7 +399,7 @@ void FDDSTexture::ReadRGB (FWadLump &lump)
for (y = Height; y > 0; --y) for (y = Height; y > 0; --y)
{ {
BYTE *buffp = linebuff; BYTE *buffp = linebuff;
BYTE *pixelp = Pixels + y; BYTE *pixelp = tcbuf? tcbuf + 4*y*Height : Pixels + y;
lump.Read (linebuff, Pitch); lump.Read (linebuff, Pitch);
for (x = Width; x > 0; --x) for (x = Width; x > 0; --x)
{ {
@ -420,25 +420,40 @@ void FDDSTexture::ReadRGB (FWadLump &lump)
{ {
c = *buffp++; c = *buffp++;
} }
if (amask == 0 || (c & amask)) if (!tcbuf)
{
if (amask == 0 || (c & amask))
{
DWORD r = (c & RMask) << RShiftL; r |= r >> RShiftR;
DWORD g = (c & GMask) << GShiftL; g |= g >> GShiftR;
DWORD b = (c & BMask) << BShiftL; b |= b >> BShiftR;
*pixelp = RGB32k[r >> 27][g >> 27][b >> 27];
}
else
{
*pixelp = 0;
bMasked = true;
}
pixelp += Height;
}
else
{ {
DWORD r = (c & RMask) << RShiftL; r |= r >> RShiftR; DWORD r = (c & RMask) << RShiftL; r |= r >> RShiftR;
DWORD g = (c & GMask) << GShiftL; g |= g >> GShiftR; DWORD g = (c & GMask) << GShiftL; g |= g >> GShiftR;
DWORD b = (c & BMask) << BShiftL; b |= b >> BShiftR; DWORD b = (c & BMask) << BShiftL; b |= b >> BShiftR;
*pixelp = RGB32k[r >> 27][g >> 27][b >> 27]; DWORD a = (c & AMask) << AShiftL; a |= a >> AShiftR;
pixelp[0] = (BYTE)(r>>24);
pixelp[1] = (BYTE)(g>>24);
pixelp[2] = (BYTE)(b>>24);
pixelp[3] = (BYTE)(a>>24);
pixelp+=4;
} }
else
{
*pixelp = 0;
bMasked = true;
}
pixelp += Height;
} }
} }
delete[] linebuff; delete[] linebuff;
} }
void FDDSTexture::DecompressDXT1 (FWadLump &lump) void FDDSTexture::DecompressDXT1 (FWadLump &lump, BYTE *tcbuf)
{ {
const long blocklinelen = ((Width + 3) >> 2) << 3; const long blocklinelen = ((Width + 3) >> 2) << 3;
BYTE *blockbuff = new BYTE[blocklinelen]; BYTE *blockbuff = new BYTE[blocklinelen];
@ -490,7 +505,7 @@ void FDDSTexture::DecompressDXT1 (FWadLump &lump)
bMasked = true; bMasked = true;
} }
// Pick colors from the palette for each of the four colors. // Pick colors from the palette for each of the four colors.
for (i = 3; i >= 0; --i) if (!tcbuf) for (i = 3; i >= 0; --i)
{ {
palcol[i] = color[i].a ? RGB32k[color[i].r >> 3][color[i].g >> 3][color[i].b >> 3] : 0; palcol[i] = color[i].a ? RGB32k[color[i].r >> 3][color[i].g >> 3][color[i].b >> 3] : 0;
} }
@ -508,7 +523,19 @@ void FDDSTexture::DecompressDXT1 (FWadLump &lump)
{ {
break; break;
} }
Pixels[oy + y + (ox + x) * Height] = palcol[(yslice >> (x + x)) & 3]; if (!tcbuf)
{
Pixels[oy + y + (ox + x) * Height] = palcol[(yslice >> (x + x)) & 3];
}
else
{
BYTE * tcp = &tcbuf[ox + x + (oy + y) * Width*4];
int c = (yslice >> (x + x)) & 3;
tcp[0] = color[c].r;
tcp[1] = color[c].g;
tcp[2] = color[c].b;
tcp[3] = color[c].a;
}
} }
} }
block += 8; block += 8;
@ -520,7 +547,7 @@ void FDDSTexture::DecompressDXT1 (FWadLump &lump)
// DXT3: Decompression is identical to DXT1, except every 64-bit block is // DXT3: Decompression is identical to DXT1, except every 64-bit block is
// preceded by another 64-bit block with explicit alpha values. // preceded by another 64-bit block with explicit alpha values.
void FDDSTexture::DecompressDXT3 (FWadLump &lump, bool premultiplied) void FDDSTexture::DecompressDXT3 (FWadLump &lump, bool premultiplied, BYTE *tcbuf)
{ {
const long blocklinelen = ((Width + 3) >> 2) << 4; const long blocklinelen = ((Width + 3) >> 2) << 4;
BYTE *blockbuff = new BYTE[blocklinelen]; BYTE *blockbuff = new BYTE[blocklinelen];
@ -554,7 +581,7 @@ void FDDSTexture::DecompressDXT3 (FWadLump &lump, bool premultiplied)
color[3].b = (color[0].b + color[1].b + color[1].b + 1) / 3; color[3].b = (color[0].b + color[1].b + color[1].b + 1) / 3;
// Pick colors from the palette for each of the four colors. // Pick colors from the palette for each of the four colors.
for (i = 3; i >= 0; --i) if (!tcbuf) for (i = 3; i >= 0; --i)
{ {
palcol[i] = RGB32k[color[i].r >> 3][color[i].g >> 3][color[i].b >> 3]; palcol[i] = RGB32k[color[i].r >> 3][color[i].g >> 3][color[i].b >> 3];
} }
@ -573,8 +600,20 @@ void FDDSTexture::DecompressDXT3 (FWadLump &lump, bool premultiplied)
{ {
break; break;
} }
Pixels[oy + y + (ox + x) * Height] = ((yalphaslice >> (x*4)) & 15) < 8 ? if (!tcbuf)
(bMasked = true, 0) : palcol[(yslice >> (x + x)) & 3]; {
Pixels[oy + y + (ox + x) * Height] = ((yalphaslice >> (x*4)) & 15) < 8 ?
(bMasked = true, 0) : palcol[(yslice >> (x + x)) & 3];
}
else
{
BYTE * tcp = &tcbuf[ox + x + (oy + y) * Width*4];
int c = (yslice >> (x + x)) & 3;
tcp[0] = color[c].r;
tcp[1] = color[c].g;
tcp[2] = color[c].b;
tcp[3] = color[c].a;
}
} }
} }
block += 16; block += 16;
@ -586,7 +625,7 @@ void FDDSTexture::DecompressDXT3 (FWadLump &lump, bool premultiplied)
// DXT5: Decompression is identical to DXT3, except every 64-bit alpha block // DXT5: Decompression is identical to DXT3, except every 64-bit alpha block
// contains interpolated alpha values, similar to the 64-bit color block. // contains interpolated alpha values, similar to the 64-bit color block.
void FDDSTexture::DecompressDXT5 (FWadLump &lump, bool premultiplied) void FDDSTexture::DecompressDXT5 (FWadLump &lump, bool premultiplied, BYTE *tcbuf)
{ {
const long blocklinelen = ((Width + 3) >> 2) << 4; const long blocklinelen = ((Width + 3) >> 2) << 4;
BYTE *blockbuff = new BYTE[blocklinelen]; BYTE *blockbuff = new BYTE[blocklinelen];
@ -643,7 +682,7 @@ void FDDSTexture::DecompressDXT5 (FWadLump &lump, bool premultiplied)
color[3].b = (color[0].b + color[1].b + color[1].b + 1) / 3; color[3].b = (color[0].b + color[1].b + color[1].b + 1) / 3;
// Pick colors from the palette for each of the four colors. // Pick colors from the palette for each of the four colors.
for (i = 3; i >= 0; --i) if (!tcbuf) for (i = 3; i >= 0; --i)
{ {
palcol[i] = RGB32k[color[i].r >> 3][color[i].g >> 3][color[i].b >> 3]; palcol[i] = RGB32k[color[i].r >> 3][color[i].g >> 3][color[i].b >> 3];
} }
@ -670,8 +709,20 @@ void FDDSTexture::DecompressDXT5 (FWadLump &lump, bool premultiplied)
{ {
break; break;
} }
Pixels[oy + y + (ox + x) * Height] = alpha[((yalphaslice >> (x*3)) & 7)] < 128 ? if (!tcbuf)
(bMasked = true, 0) : palcol[(yslice >> (x + x)) & 3]; {
Pixels[oy + y + (ox + x) * Height] = alpha[((yalphaslice >> (x*3)) & 7)] < 128 ?
(bMasked = true, 0) : palcol[(yslice >> (x + x)) & 3];
}
else
{
BYTE * tcp = &tcbuf[ox + x + (oy + y) * Width*4];
int c = (yslice >> (x + x)) & 3;
tcp[0] = color[c].r;
tcp[1] = color[c].g;
tcp[2] = color[c].b;
tcp[3] = alpha[((yalphaslice >> (x*3)) & 7)];
}
} }
} }
block += 16; block += 16;
@ -679,3 +730,50 @@ void FDDSTexture::DecompressDXT5 (FWadLump &lump, bool premultiplied)
} }
delete[] blockbuff; delete[] blockbuff;
} }
//===========================================================================
//
// FDDSTexture::CopyTrueColorPixels
//
//===========================================================================
int FDDSTexture::CopyTrueColorPixels(BYTE * buffer, int buf_width, int buf_height, int x, int y)
{
FWadLump lump = Wads.OpenLumpNum (SourceLump);
BYTE *TexBuffer = new BYTE[4*Width*Height];
lump.Seek (sizeof(DDSURFACEDESC2) + 4, SEEK_SET);
if (Format >= 1 && Format <= 4) // RGB: Format is # of bytes per pixel
{
ReadRGB (lump, TexBuffer);
}
else if (Format == ID_DXT1)
{
DecompressDXT1 (lump, TexBuffer);
}
else if (Format == ID_DXT3 || Format == ID_DXT2)
{
DecompressDXT3 (lump, Format == ID_DXT2, TexBuffer);
}
else if (Format == ID_DXT5 || Format == ID_DXT4)
{
DecompressDXT5 (lump, Format == ID_DXT4, TexBuffer);
}
// All formats decompress to RGBA.
screen->CopyPixelDataRGB(buffer, buf_width, buf_height, x, y, TexBuffer, Width, Height, 4, Width*4, CF_RGBA);
delete [] TexBuffer;
return -1;
}
//===========================================================================
//
//
//===========================================================================
bool FDDSTexture::UseBasePalette()
{
return false;
}