- 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)
- 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
if present.
- 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);
void MakeTexture ();
void ReadRGB (FWadLump &lump);
void DecompressDXT1 (FWadLump &lump);
void DecompressDXT3 (FWadLump &lump, bool premultiplied);
void DecompressDXT5 (FWadLump &lump, bool premultiplied);
void ReadRGB (FWadLump &lump, BYTE *tcbuf = NULL);
void DecompressDXT1 (FWadLump &lump, BYTE *tcbuf = NULL);
void DecompressDXT3 (FWadLump &lump, bool premultiplied, BYTE *tcbuf = NULL);
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;
};

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 amask = AMask == 0 ? 0 : 0x80000000 >> AShiftL;
@ -399,7 +399,7 @@ void FDDSTexture::ReadRGB (FWadLump &lump)
for (y = Height; y > 0; --y)
{
BYTE *buffp = linebuff;
BYTE *pixelp = Pixels + y;
BYTE *pixelp = tcbuf? tcbuf + 4*y*Height : Pixels + y;
lump.Read (linebuff, Pitch);
for (x = Width; x > 0; --x)
{
@ -420,25 +420,40 @@ void FDDSTexture::ReadRGB (FWadLump &lump)
{
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 g = (c & GMask) << GShiftL; g |= g >> GShiftR;
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;
}
void FDDSTexture::DecompressDXT1 (FWadLump &lump)
void FDDSTexture::DecompressDXT1 (FWadLump &lump, BYTE *tcbuf)
{
const long blocklinelen = ((Width + 3) >> 2) << 3;
BYTE *blockbuff = new BYTE[blocklinelen];
@ -490,7 +505,7 @@ void FDDSTexture::DecompressDXT1 (FWadLump &lump)
bMasked = true;
}
// 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;
}
@ -508,7 +523,19 @@ void FDDSTexture::DecompressDXT1 (FWadLump &lump)
{
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;
@ -520,7 +547,7 @@ void FDDSTexture::DecompressDXT1 (FWadLump &lump)
// DXT3: Decompression is identical to DXT1, except every 64-bit block is
// 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;
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;
// 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];
}
@ -573,8 +600,20 @@ void FDDSTexture::DecompressDXT3 (FWadLump &lump, bool premultiplied)
{
break;
}
Pixels[oy + y + (ox + x) * Height] = ((yalphaslice >> (x*4)) & 15) < 8 ?
(bMasked = true, 0) : palcol[(yslice >> (x + x)) & 3];
if (!tcbuf)
{
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;
@ -586,7 +625,7 @@ void FDDSTexture::DecompressDXT3 (FWadLump &lump, bool premultiplied)
// DXT5: Decompression is identical to DXT3, except every 64-bit alpha 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;
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;
// 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];
}
@ -670,8 +709,20 @@ void FDDSTexture::DecompressDXT5 (FWadLump &lump, bool premultiplied)
{
break;
}
Pixels[oy + y + (ox + x) * Height] = alpha[((yalphaslice >> (x*3)) & 7)] < 128 ?
(bMasked = true, 0) : palcol[(yslice >> (x + x)) & 3];
if (!tcbuf)
{
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;
@ -679,3 +730,50 @@ void FDDSTexture::DecompressDXT5 (FWadLump &lump, bool premultiplied)
}
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;
}