mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-28 23:12:24 +00:00
- adjustments and fixes for alphatextures:
* Instead of using the red channel it now uses the grayscale value. While slower in a few situations, it is also more precise and makes the feature more useful. * For paletted textures do not use the index as alpha anymore but the actual grayscaled color. This is again to make the feature more consistent and useful. * To compensate for the above there is now a list of hashes for known alpha textures in patch format, so that they don't get broken. * IMGZ is now considered a grayscale format. There's only two known textures that use IMGZ for something else than crosshairs and those are explicitly handled. * several smaller fixes. * the actual color conversion functions for paletted output are now consolidated in a small number of inlines so that future changes are easier to do. Note: This hasn't been tested yet and will need further changes in the hardware rendering code. As it is it is not production-ready.
This commit is contained in:
parent
b0c96ac43d
commit
b473838627
18 changed files with 220 additions and 104 deletions
|
@ -1097,6 +1097,7 @@ set (PCH_SOURCES
|
|||
textures/flattexture.cpp
|
||||
textures/imgztexture.cpp
|
||||
textures/jpegtexture.cpp
|
||||
textures/md5check.cpp
|
||||
textures/multipatchtexture.cpp
|
||||
textures/patchtexture.cpp
|
||||
textures/pcxtexture.cpp
|
||||
|
|
|
@ -128,6 +128,11 @@ struct PalEntry
|
|||
return other;
|
||||
}
|
||||
}
|
||||
int Luminance() const
|
||||
{
|
||||
return (r * 77 + g * 143 + b * 37) >> 8;
|
||||
}
|
||||
|
||||
void Decolorize() // this for 'nocoloredspritelighting' and not the same as desaturation. The normal formula results in a value that's too dark.
|
||||
{
|
||||
int v = (r + g + b);
|
||||
|
@ -168,6 +173,12 @@ struct PalEntry
|
|||
#endif
|
||||
};
|
||||
|
||||
inline int Luminance(int r, int g, int b)
|
||||
{
|
||||
return (r * 77 + g * 143 + b * 37) >> 8;
|
||||
}
|
||||
|
||||
|
||||
class FTextureID
|
||||
{
|
||||
friend class FTextureManager;
|
||||
|
|
|
@ -997,7 +997,7 @@ void R_InitTranslationTables ()
|
|||
{
|
||||
IcePaletteRemap[i] = ColorMatcher.Pick (IcePalette[i][0], IcePalette[i][1], IcePalette[i][2]);
|
||||
}
|
||||
FRemapTable *remap = translationtables[TRANSLATION_Standard][7];
|
||||
FRemapTable *remap = translationtables[TRANSLATION_Standard][STD_Ice];
|
||||
remap->Remap[0] = 0;
|
||||
remap->Palette[0] = 0;
|
||||
for (i = 1; i < 256; ++i)
|
||||
|
@ -1010,9 +1010,9 @@ void R_InitTranslationTables ()
|
|||
remap->Palette[i] = PalEntry(255, IcePalette[v][0], IcePalette[v][1], IcePalette[v][2]);
|
||||
}
|
||||
|
||||
// The alphatexture translation. Since alphatextures use the red channel this is just a standard grayscale mapping.
|
||||
// The alphatexture translation. This is just a standard index as gray mapping.
|
||||
PushIdentityTable(TRANSLATION_Standard);
|
||||
remap = translationtables[TRANSLATION_Standard][8];
|
||||
remap = translationtables[TRANSLATION_Standard][STD_Gray];
|
||||
remap->Remap[0] = 0;
|
||||
remap->Palette[0] = 0;
|
||||
for (i = 1; i < 256; i++)
|
||||
|
@ -1020,6 +1020,23 @@ void R_InitTranslationTables ()
|
|||
remap->Remap[i] = i;
|
||||
remap->Palette[i] = PalEntry(255, i, i, i);
|
||||
}
|
||||
|
||||
// Palette to grayscale ramp. For internal use only, because the remap does not map to the palette.
|
||||
PushIdentityTable(TRANSLATION_Standard);
|
||||
remap = translationtables[TRANSLATION_Standard][STD_Grayscale];
|
||||
remap->Remap[0] = 0;
|
||||
remap->Palette[0] = 0;
|
||||
for (i = 1; i < 256; i++)
|
||||
{
|
||||
int r = GPalette.BaseColors[i].r;
|
||||
int g = GPalette.BaseColors[i].g;
|
||||
int b = GPalette.BaseColors[i].b;
|
||||
int v = (r * 77 + g * 143 + b * 37) >> 8;
|
||||
|
||||
remap->Remap[i] = v;
|
||||
remap->Palette[i] = PalEntry(255, v, v, v);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
|
|
@ -24,6 +24,13 @@ enum
|
|||
NUM_TRANSLATION_TABLES
|
||||
};
|
||||
|
||||
enum EStandardTranslations
|
||||
{
|
||||
STD_Ice = 7,
|
||||
STD_Gray = 8, // a 0-255 gray ramp
|
||||
STD_Grayscale = 9, // desaturated version of the palette.
|
||||
};
|
||||
|
||||
struct FRemapTable
|
||||
{
|
||||
FRemapTable(int count=256);
|
||||
|
|
|
@ -98,12 +98,13 @@ uint8_t *FAutomapTexture::MakeTexture (FRenderStyle style)
|
|||
|
||||
auto Pixels = new uint8_t[Width * Height];
|
||||
|
||||
const uint8_t *remap = GetRemap(style);
|
||||
for (x = 0; x < Width; ++x)
|
||||
{
|
||||
for (y = 0; y < Height; ++y)
|
||||
{
|
||||
auto p = indata[x + 320 * y];
|
||||
Pixels[x*Height + y] = (style.Flags & STYLEF_RedIsAlpha) ? p : GPalette.Remap[p];
|
||||
Pixels[x*Height + y] = remap[p];
|
||||
}
|
||||
}
|
||||
return Pixels;
|
||||
|
|
|
@ -95,7 +95,7 @@ uint8_t *FBuildTexture::MakeTexture(FRenderStyle style)
|
|||
for (int i = 0; i < Width*Height; i++)
|
||||
{
|
||||
auto c = RawPixels[i];
|
||||
Pixels[i] = (style.Flags & STYLEF_RedIsAlpha) ? Remap->Palette[c].r : Remap->Remap[c];
|
||||
Pixels[i] = (style.Flags & STYLEF_RedIsAlpha) ? Remap->Palette[c].Luminance() : Remap->Remap[c];
|
||||
}
|
||||
return (uint8_t*)RawPixels;
|
||||
}
|
||||
|
|
|
@ -472,16 +472,9 @@ void FDDSTexture::ReadRGB (FileReader &lump, uint8_t *buffer, int pixelmode)
|
|||
if (amask == 0 || (c & amask))
|
||||
{
|
||||
uint32_t r = (c & RMask) << RShiftL; r |= r >> RShiftR;
|
||||
if (pixelmode == PIX_Palette)
|
||||
{
|
||||
uint32_t g = (c & GMask) << GShiftL; g |= g >> GShiftR;
|
||||
uint32_t b = (c & BMask) << BShiftL; b |= b >> BShiftR;
|
||||
*pixelp = RGB256k.RGB[r >> 26][g >> 26][b >> 26];
|
||||
}
|
||||
else
|
||||
{
|
||||
*pixelp = uint8_t(r >> 24);
|
||||
}
|
||||
uint32_t g = (c & GMask) << GShiftL; g |= g >> GShiftR;
|
||||
uint32_t b = (c & BMask) << BShiftL; b |= b >> BShiftR;
|
||||
*pixelp = RGBToPalette(pixelmode == PIX_Palette, r >> 24, g >> 24, b >> 24);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -567,10 +560,7 @@ void FDDSTexture::DecompressDXT1 (FileReader &lump, uint8_t *buffer, int pixelmo
|
|||
// Pick colors from the palette for each of the four colors.
|
||||
if (pixelmode != PIX_ARGB) for (i = 3; i >= 0; --i)
|
||||
{
|
||||
if (pixelmode == PIX_Palette)
|
||||
palcol[i] = color[i].a ? RGB256k.RGB[color[i].r >> 2][color[i].g >> 2][color[i].b >> 2] : 0;
|
||||
else
|
||||
palcol[i] = (color[i].a * color[i].r) / 255; // use the same logic as the hardware renderer.
|
||||
palcol[i] = RGBToPalette(pixelmode == PIX_Palette, color[i]);
|
||||
}
|
||||
// Now decode this 4x4 block to the pixel buffer.
|
||||
for (y = 0; y < 4; ++y)
|
||||
|
@ -650,10 +640,7 @@ void FDDSTexture::DecompressDXT3 (FileReader &lump, bool premultiplied, uint8_t
|
|||
// Pick colors from the palette for each of the four colors.
|
||||
if (pixelmode != PIX_ARGB) for (i = 3; i >= 0; --i)
|
||||
{
|
||||
if (pixelmode == PIX_Palette)
|
||||
palcol[i] = color[i].a ? RGB256k.RGB[color[i].r >> 2][color[i].g >> 2][color[i].b >> 2] : 0;
|
||||
else
|
||||
palcol[i] = (color[i].a * color[i].r) / 255; // use the same logic as the hardware renderer.
|
||||
palcol[i] = RGBToPalette(pixelmode == PIX_Palette, color[i], false);
|
||||
}
|
||||
|
||||
// Now decode this 4x4 block to the pixel buffer.
|
||||
|
@ -759,10 +746,7 @@ void FDDSTexture::DecompressDXT5 (FileReader &lump, bool premultiplied, uint8_t
|
|||
// Pick colors from the palette for each of the four colors.
|
||||
if (pixelmode != PIX_ARGB) for (i = 3; i >= 0; --i)
|
||||
{
|
||||
if (pixelmode == PIX_Palette)
|
||||
palcol[i] = color[i].a ? RGB256k.RGB[color[i].r >> 2][color[i].g >> 2][color[i].b >> 2] : 0;
|
||||
else
|
||||
palcol[i] = (color[i].a * color[i].r) / 255; // use the same logic as the hardware renderer.
|
||||
palcol[i] = RGBToPalette(pixelmode == PIX_Palette, color[i], false);
|
||||
}
|
||||
// Now decode this 4x4 block to the pixel buffer.
|
||||
for (y = 0; y < 4; ++y)
|
||||
|
@ -787,11 +771,17 @@ void FDDSTexture::DecompressDXT5 (FileReader &lump, bool premultiplied, uint8_t
|
|||
{
|
||||
break;
|
||||
}
|
||||
if (pixelmode == 8)
|
||||
if (pixelmode == PIX_Palette)
|
||||
{
|
||||
buffer[oy + y + (ox + x) * Height] = alpha[((yalphaslice >> (x*3)) & 7)] < 128 ?
|
||||
(bMasked = true, 0) : palcol[(yslice >> (x + x)) & 3];
|
||||
}
|
||||
else if (pixelmode == PIX_Alphatex)
|
||||
{
|
||||
int alphaval = alpha[((yalphaslice >> (x * 3)) & 7)];
|
||||
int palval = palcol[(yslice >> (x + x)) & 3];
|
||||
buffer[oy + y + (ox + x) * Height] = palval * alphaval / 255;
|
||||
}
|
||||
else
|
||||
{
|
||||
uint8_t * tcp = &buffer[(ox + x)*4 + (oy + y) * Width*4];
|
||||
|
|
|
@ -112,8 +112,7 @@ uint8_t *FFlatTexture::MakeTexture (FRenderStyle style)
|
|||
{
|
||||
memset (Pixels + numread, 0xBB, Width*Height - numread);
|
||||
}
|
||||
if (!(style.Flags & STYLEF_RedIsAlpha)) FTexture::FlipSquareBlockRemap (Pixels, Width, Height, GPalette.Remap);
|
||||
else FTexture::FlipSquareBlock(Pixels, Width, Height);
|
||||
FTexture::FlipSquareBlockRemap(Pixels, Width, Height, GetRemap(style));
|
||||
return Pixels;
|
||||
}
|
||||
|
||||
|
|
|
@ -37,8 +37,12 @@
|
|||
#include "files.h"
|
||||
#include "w_wad.h"
|
||||
#include "v_palette.h"
|
||||
#include "v_video.h"
|
||||
#include "bitmap.h"
|
||||
#include "textures/textures.h"
|
||||
#include "r_data/r_translate.h"
|
||||
|
||||
bool checkIMGZPalette(FileReader &file);
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
|
@ -61,9 +65,15 @@ class FIMGZTexture : public FWorldTexture
|
|||
uint8_t Reserved[11];
|
||||
};
|
||||
|
||||
bool isalpha = true;
|
||||
|
||||
public:
|
||||
FIMGZTexture (int lumpnum, uint16_t w, uint16_t h, int16_t l, int16_t t);
|
||||
FIMGZTexture (int lumpnum, uint16_t w, uint16_t h, int16_t l, int16_t t, bool isalpha);
|
||||
uint8_t *MakeTexture (FRenderStyle style) override;
|
||||
int CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FCopyInfo *inf) override;
|
||||
|
||||
bool UseBasePalette() override { return !isalpha; }
|
||||
FTextureFormat GetFormat() override { return isalpha ? TEX_RGB : TEX_Pal; } // should be TEX_Gray instead of TEX_RGB. Maybe later when all is working.
|
||||
};
|
||||
|
||||
|
||||
|
@ -78,6 +88,7 @@ FTexture *IMGZTexture_TryCreate(FileReader & file, int lumpnum)
|
|||
uint32_t magic = 0;
|
||||
uint16_t w, h;
|
||||
int16_t l, t;
|
||||
bool ispalette;
|
||||
|
||||
file.Seek(0, FileReader::SeekSet);
|
||||
if (file.Read(&magic, 4) != 4) return NULL;
|
||||
|
@ -86,7 +97,8 @@ FTexture *IMGZTexture_TryCreate(FileReader & file, int lumpnum)
|
|||
h = file.ReadUInt16();
|
||||
l = file.ReadInt16();
|
||||
t = file.ReadInt16();
|
||||
return new FIMGZTexture(lumpnum, w, h, l, t);
|
||||
ispalette = checkIMGZPalette(file);
|
||||
return new FIMGZTexture(lumpnum, w, h, l, t, !ispalette);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -95,7 +107,7 @@ FTexture *IMGZTexture_TryCreate(FileReader & file, int lumpnum)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
FIMGZTexture::FIMGZTexture (int lumpnum, uint16_t w, uint16_t h, int16_t l, int16_t t)
|
||||
FIMGZTexture::FIMGZTexture (int lumpnum, uint16_t w, uint16_t h, int16_t l, int16_t t, bool _isalpha)
|
||||
: FWorldTexture(NULL, lumpnum)
|
||||
{
|
||||
Wads.GetLumpName (Name, lumpnum);
|
||||
|
@ -103,6 +115,7 @@ FIMGZTexture::FIMGZTexture (int lumpnum, uint16_t w, uint16_t h, int16_t l, int1
|
|||
Height = h;
|
||||
LeftOffset = l;
|
||||
TopOffset = t;
|
||||
isalpha = _isalpha;
|
||||
CalcBitSize ();
|
||||
}
|
||||
|
||||
|
@ -134,15 +147,16 @@ uint8_t *FIMGZTexture::MakeTexture (FRenderStyle style)
|
|||
auto Pixels = new uint8_t[Width*Height];
|
||||
dest_p = Pixels;
|
||||
|
||||
// Convert the source image from row-major to column-major format
|
||||
const uint8_t *remap = GetRemap(style, isalpha);
|
||||
|
||||
// Convert the source image from row-major to column-major format and remap it
|
||||
if (!imgz->Compression)
|
||||
{
|
||||
for (int y = Height; y != 0; --y)
|
||||
{
|
||||
for (int x = Width; x != 0; --x)
|
||||
{
|
||||
auto p = *data;
|
||||
*dest_p = (style.Flags & STYLEF_RedIsAlpha) ? p : GPalette.Remap[p];
|
||||
*dest_p = remap[*data];
|
||||
dest_p += dest_adv;
|
||||
data++;
|
||||
}
|
||||
|
@ -161,8 +175,7 @@ uint8_t *FIMGZTexture::MakeTexture (FRenderStyle style)
|
|||
{
|
||||
if (runlen != 0)
|
||||
{
|
||||
auto p = *data;
|
||||
*dest_p = (style.Flags & STYLEF_RedIsAlpha) ? p : GPalette.Remap[p];
|
||||
*dest_p = remap[*data];
|
||||
dest_p += dest_adv;
|
||||
data++;
|
||||
x--;
|
||||
|
@ -185,7 +198,7 @@ uint8_t *FIMGZTexture::MakeTexture (FRenderStyle style)
|
|||
else if (code != -128)
|
||||
{
|
||||
setlen = (-code) + 1;
|
||||
setval = *data++;
|
||||
setval = remap[*data++];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -195,3 +208,15 @@ uint8_t *FIMGZTexture::MakeTexture (FRenderStyle style)
|
|||
return Pixels;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
int FIMGZTexture::CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FCopyInfo *inf)
|
||||
{
|
||||
if (!isalpha) return FTexture::CopyTrueColorPixels(bmp, x, y, rotate, inf);
|
||||
else return CopyTrueColorTranslated(bmp, x, y, rotate, translationtables[TRANSLATION_Standard][isalpha ? STD_Gray : STD_Grayscale]->Palette, inf);
|
||||
}
|
||||
|
||||
|
|
|
@ -321,21 +321,23 @@ uint8_t *FJPEGTexture::MakeTexture (FRenderStyle style)
|
|||
case JCS_RGB:
|
||||
for (int x = Width; x > 0; --x)
|
||||
{
|
||||
*out = !doalpha? RGB256k.RGB[in[0] >> 2][in[1] >> 2][in[2] >> 2] : in[0];
|
||||
*out = RGBToPalette(doalpha, in[0], in[1], in[2]);
|
||||
out += Height;
|
||||
in += 3;
|
||||
}
|
||||
break;
|
||||
|
||||
case JCS_GRAYSCALE:
|
||||
{
|
||||
auto remap = GetRemap(style, true);
|
||||
for (int x = Width; x > 0; --x)
|
||||
{
|
||||
*out = !doalpha ? FTexture::GrayMap[in[0]] : in[0];
|
||||
*out = remap[in[0]];
|
||||
out += Height;
|
||||
in += 1;
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
case JCS_CMYK:
|
||||
// What are you doing using a CMYK image? :)
|
||||
for (int x = Width; x > 0; --x)
|
||||
|
@ -343,13 +345,9 @@ uint8_t *FJPEGTexture::MakeTexture (FRenderStyle style)
|
|||
// To be precise, these calculations should use 255, but
|
||||
// 256 is much faster and virtually indistinguishable.
|
||||
int r = in[3] - (((256 - in[0])*in[3]) >> 8);
|
||||
if (!doalpha)
|
||||
{
|
||||
int g = in[3] - (((256 - in[1])*in[3]) >> 8);
|
||||
int b = in[3] - (((256 - in[2])*in[3]) >> 8);
|
||||
*out = RGB256k.RGB[r >> 2][g >> 2][b >> 2];
|
||||
}
|
||||
else *out = (uint8_t)r;
|
||||
int g = in[3] - (((256 - in[1])*in[3]) >> 8);
|
||||
int b = in[3] - (((256 - in[2])*in[3]) >> 8);
|
||||
*out = RGBToPalette(doalpha, r, g, b);
|
||||
out += Height;
|
||||
in += 4;
|
||||
}
|
||||
|
@ -361,13 +359,9 @@ uint8_t *FJPEGTexture::MakeTexture (FRenderStyle style)
|
|||
{
|
||||
double Y = in[0], Cb = in[1], Cr = in[2];
|
||||
int r = clamp((int)(Y + 1.40200 * (Cr - 0x80)), 0, 255);
|
||||
if (!doalpha)
|
||||
{
|
||||
int g = clamp((int)(Y - 0.34414 * (Cb - 0x80) - 0.71414 * (Cr - 0x80)), 0, 255);
|
||||
int b = clamp((int)(Y + 1.77200 * (Cb - 0x80)), 0, 255);
|
||||
*out = RGB256k.RGB[r >> 2][g >> 2][b >> 2];
|
||||
}
|
||||
else *out = (uint8_t)r;
|
||||
int g = clamp((int)(Y - 0.34414 * (Cb - 0x80) - 0.71414 * (Cr - 0x80)), 0, 255);
|
||||
int b = clamp((int)(Y + 1.77200 * (Cb - 0x80)), 0, 255);
|
||||
*out = RGBToPalette(doalpha, r, g, b);
|
||||
out += Height;
|
||||
in += 4;
|
||||
}
|
||||
|
|
|
@ -416,13 +416,6 @@ uint8_t *FMultiPatchTexture::MakeTexture (FRenderStyle style)
|
|||
|
||||
if (style.Flags & STYLEF_RedIsAlpha)
|
||||
{
|
||||
// The rules here are as follows:
|
||||
// A texture uses its palette index as alpha only if it reports to use the base palette.
|
||||
// In summary this means:
|
||||
// If a texture is marked 'complex', it will use the red channel.
|
||||
// If a texture uses non-base-palette patches, it will use the red channel for all pixels, even those coming from a base palette patch.
|
||||
// If a texture only uses base-palette patches and no compositing effects it will use the palette index.
|
||||
//
|
||||
buildrgb = !UseBasePalette();
|
||||
}
|
||||
else
|
||||
|
@ -449,8 +442,7 @@ uint8_t *FMultiPatchTexture::MakeTexture (FRenderStyle style)
|
|||
{
|
||||
trans = GetBlendMap(Parts[i].Blend, blendwork);
|
||||
}
|
||||
Parts[i].Texture->CopyToBlock (Pixels, Width, Height,
|
||||
Parts[i].OriginX, Parts[i].OriginY, Parts[i].Rotate, trans, style);
|
||||
Parts[i].Texture->CopyToBlock (Pixels, Width, Height, Parts[i].OriginX, Parts[i].OriginY, Parts[i].Rotate, trans, style);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -469,7 +461,7 @@ uint8_t *FMultiPatchTexture::MakeTexture (FRenderStyle style)
|
|||
{
|
||||
if (*out == 0 && in[3] != 0)
|
||||
{
|
||||
*out = (style.Flags & STYLEF_RedIsAlpha)? in[2]*in[3] : RGB256k.RGB[in[2]>>2][in[1]>>2][in[0]>>2];
|
||||
*out = RGBToPalette(style, in[2], in[1], in[0]);
|
||||
}
|
||||
out += Height;
|
||||
in += 4;
|
||||
|
|
|
@ -38,6 +38,8 @@
|
|||
#include "w_wad.h"
|
||||
#include "templates.h"
|
||||
#include "v_palette.h"
|
||||
#include "v_video.h"
|
||||
#include "bitmap.h"
|
||||
#include "textures/textures.h"
|
||||
#include "r_data/r_translate.h"
|
||||
|
||||
|
@ -49,6 +51,7 @@ struct column_t
|
|||
uint8_t length; // length data bytes follows
|
||||
};
|
||||
|
||||
bool checkPatchForAlpha(const void *buffer, uint32_t length);
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
|
@ -59,10 +62,15 @@ struct column_t
|
|||
class FPatchTexture : public FWorldTexture
|
||||
{
|
||||
bool badflag = false;
|
||||
bool isalpha = false;
|
||||
public:
|
||||
FPatchTexture (int lumpnum, patch_t *header);
|
||||
FPatchTexture (int lumpnum, patch_t *header, bool isalphatex);
|
||||
uint8_t *MakeTexture (FRenderStyle style) override;
|
||||
int CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FCopyInfo *inf) override;
|
||||
void DetectBadPatches();
|
||||
|
||||
bool UseBasePalette() override { return !isalpha; }
|
||||
FTextureFormat GetFormat() override { return isalpha ? TEX_RGB : TEX_Pal; } // should be TEX_Gray instead of TEX_RGB. Maybe later when all is working.
|
||||
};
|
||||
|
||||
//==========================================================================
|
||||
|
@ -71,7 +79,7 @@ public:
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
static bool CheckIfPatch(FileReader & file)
|
||||
static bool CheckIfPatch(FileReader & file, bool &isalpha)
|
||||
{
|
||||
if (file.GetLength() < 13) return false; // minimum length of a valid Doom patch
|
||||
|
||||
|
@ -107,6 +115,12 @@ static bool CheckIfPatch(FileReader & file)
|
|||
}
|
||||
}
|
||||
delete [] data;
|
||||
if (!gapAtStart)
|
||||
{
|
||||
// only check this if the texture passed validation.
|
||||
// Here is a good point because we already have a valid buffer of the lump's data.
|
||||
isalpha = checkPatchForAlpha(data, file.GetLength());
|
||||
}
|
||||
return !gapAtStart;
|
||||
}
|
||||
delete [] data;
|
||||
|
@ -122,14 +136,15 @@ static bool CheckIfPatch(FileReader & file)
|
|||
FTexture *PatchTexture_TryCreate(FileReader & file, int lumpnum)
|
||||
{
|
||||
patch_t header;
|
||||
bool isalpha;
|
||||
|
||||
if (!CheckIfPatch(file)) return NULL;
|
||||
if (!CheckIfPatch(file, isalpha)) return NULL;
|
||||
file.Seek(0, FileReader::SeekSet);
|
||||
header.width = file.ReadUInt16();
|
||||
header.height = file.ReadUInt16();
|
||||
header.leftoffset = file.ReadInt16();
|
||||
header.topoffset = file.ReadInt16();
|
||||
return new FPatchTexture(lumpnum, &header);
|
||||
return new FPatchTexture(lumpnum, &header, isalpha);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -138,9 +153,10 @@ FTexture *PatchTexture_TryCreate(FileReader & file, int lumpnum)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
FPatchTexture::FPatchTexture (int lumpnum, patch_t * header)
|
||||
FPatchTexture::FPatchTexture (int lumpnum, patch_t * header, bool isalphatex)
|
||||
: FWorldTexture(NULL, lumpnum)
|
||||
{
|
||||
isalpha = isalphatex;
|
||||
Width = header->width;
|
||||
Height = header->height;
|
||||
LeftOffset = header->leftoffset;
|
||||
|
@ -169,20 +185,19 @@ uint8_t *FPatchTexture::MakeTexture (FRenderStyle style)
|
|||
|
||||
if (style.Flags & STYLEF_RedIsAlpha)
|
||||
{
|
||||
remap = translationtables[TRANSLATION_Standard][8]->Remap;
|
||||
remap = translationtables[TRANSLATION_Standard][isalpha? STD_Gray : STD_Grayscale]->Remap;
|
||||
}
|
||||
else if (bNoRemap0)
|
||||
{
|
||||
memcpy (remaptable, GPalette.Remap, 256);
|
||||
memcpy(remaptable, GPalette.Remap, 256);
|
||||
remaptable[0] = 0;
|
||||
remap = remaptable;
|
||||
}
|
||||
else
|
||||
{
|
||||
remap = GPalette.Remap;
|
||||
remap = isalpha? GrayMap : GPalette.Remap;
|
||||
}
|
||||
|
||||
|
||||
if (badflag)
|
||||
{
|
||||
auto Pixels = new uint8_t[Width * Height];
|
||||
|
@ -255,6 +270,17 @@ uint8_t *FPatchTexture::MakeTexture (FRenderStyle style)
|
|||
return Pixels;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
int FPatchTexture::CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FCopyInfo *inf)
|
||||
{
|
||||
if (!isalpha) return FTexture::CopyTrueColorPixels(bmp, x, y, rotate, inf);
|
||||
else return CopyTrueColorTranslated(bmp, x, y, rotate, translationtables[TRANSLATION_Standard][isalpha ? STD_Gray : STD_Grayscale]->Palette, inf);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
|
|
|
@ -389,10 +389,9 @@ uint8_t *FPCXTexture::MakeTexture(FRenderStyle style)
|
|||
{
|
||||
if (bitcount < 8)
|
||||
{
|
||||
for (int i=0;i<16;i++)
|
||||
for (int i = 0; i < 16; i++)
|
||||
{
|
||||
if (!alphatex) PaletteMap[i] = ColorMatcher.Pick(header.palette[i * 3], header.palette[i * 3 + 1], header.palette[i * 3 + 2]);
|
||||
else PaletteMap[i] = header.palette[i * 3];
|
||||
PaletteMap[i] = RGBToPalettePrecise(alphatex, header.palette[i * 3], header.palette[i * 3 + 1], header.palette[i * 3 + 2]);
|
||||
}
|
||||
|
||||
switch (bitcount)
|
||||
|
@ -418,7 +417,7 @@ uint8_t *FPCXTexture::MakeTexture(FRenderStyle style)
|
|||
uint8_t r = lump.ReadUInt8();
|
||||
uint8_t g = lump.ReadUInt8();
|
||||
uint8_t b = lump.ReadUInt8();
|
||||
PaletteMap[i] = !alphatex? ColorMatcher.Pick(r,g,b) : r;
|
||||
PaletteMap[i] = RGBToPalettePrecise(alphatex, r, g, b);
|
||||
}
|
||||
lump.Seek(sizeof(header), FileReader::SeekSet);
|
||||
ReadPCX8bits (Pixels, lump, &header);
|
||||
|
@ -445,7 +444,7 @@ uint8_t *FPCXTexture::MakeTexture(FRenderStyle style)
|
|||
{
|
||||
for(int x=0; x < Width; x++)
|
||||
{
|
||||
Pixels[y + Height * x] = !alphatex? RGB256k.RGB[row[0] >> 2][row[1] >> 2][row[2] >> 2] : row[0];
|
||||
Pixels[y + Height * x] = RGBToPalette(alphatex, row[0], row[1], row[2]);
|
||||
row+=3;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -381,9 +381,9 @@ void FPNGTexture::ReadAlphaRemap(FileReader *lump, uint8_t *alpharemap)
|
|||
for (int i = 0; i < PaletteSize; i++)
|
||||
{
|
||||
uint8_t r = lump->ReadUInt8();
|
||||
lump->ReadUInt8(); // Skip g and b.
|
||||
lump->ReadUInt8();
|
||||
alpharemap[i] = PaletteMap[i] == 0? 0 : r;
|
||||
uint8_t g = lump->ReadUInt8();
|
||||
uint8_t b = lump->ReadUInt8();
|
||||
alpharemap[i] = PaletteMap[i] == 0 ? 0 : Luminance(r, g, b);
|
||||
}
|
||||
lump->Seek(p, FileReader::SeekSet);
|
||||
}
|
||||
|
@ -493,7 +493,7 @@ uint8_t *FPNGTexture::MakeTexture (FRenderStyle style)
|
|||
}
|
||||
else
|
||||
{
|
||||
*out++ = alphatex? in[0] : RGB256k.RGB[in[0]>>2][in[1]>>2][in[2]>>2];
|
||||
*out++ = RGBToPalette(alphatex, in[0], in[1], in[2]);
|
||||
}
|
||||
in += pitch;
|
||||
}
|
||||
|
@ -508,7 +508,7 @@ uint8_t *FPNGTexture::MakeTexture (FRenderStyle style)
|
|||
{
|
||||
for (y = Height; y > 0; --y)
|
||||
{
|
||||
*out++ = alphatex? ((in[0] * in[1]) >> 8) : in[1] < 128 ? 0 : PaletteMap[in[0]];
|
||||
*out++ = alphatex? ((in[0] * in[1]) / 255) : in[1] < 128 ? 0 : PaletteMap[in[0]];
|
||||
in += pitch;
|
||||
}
|
||||
in -= backstep;
|
||||
|
@ -522,7 +522,7 @@ uint8_t *FPNGTexture::MakeTexture (FRenderStyle style)
|
|||
{
|
||||
for (y = Height; y > 0; --y)
|
||||
{
|
||||
*out++ = alphatex? ((in[0] * in[3]) >> 8) : in[3] < 128 ? 0 : RGB256k.RGB[in[0]>>2][in[1]>>2][in[2]>>2];
|
||||
*out++ = RGBToPalette(alphatex, in[0], in[1], in[2], in[3]);
|
||||
in += pitch;
|
||||
}
|
||||
in -= backstep;
|
||||
|
|
|
@ -177,12 +177,14 @@ uint8_t *FRawPageTexture::MakeTexture (FRenderStyle style)
|
|||
auto Pixels = new uint8_t[Width*Height];
|
||||
dest_p = Pixels;
|
||||
|
||||
const uint8_t *remap = GetRemap(style);
|
||||
|
||||
// Convert the source image from row-major to column-major format
|
||||
for (int y = 200; y != 0; --y)
|
||||
{
|
||||
for (int x = 320; x != 0; --x)
|
||||
{
|
||||
*dest_p = (style.Flags & STYLEF_RedIsAlpha)? *source_p : GPalette.Remap[*source_p];
|
||||
*dest_p = remap[*source_p];
|
||||
dest_p += 200;
|
||||
source_p++;
|
||||
}
|
||||
|
|
|
@ -754,7 +754,7 @@ void FTexture::FillBuffer(uint8_t *buff, int pitch, int height, FTextureFormat f
|
|||
{
|
||||
case TEX_Pal:
|
||||
case TEX_Gray:
|
||||
pix = GetPixels(DefaultRenderStyle());
|
||||
pix = GetPixels(fmt == TEX_Pal? DefaultRenderStyle() : LegacyRenderStyles[STYLE_Shaded]);
|
||||
stride = pitch - w;
|
||||
for (y = 0; y < h; ++y)
|
||||
{
|
||||
|
|
|
@ -37,7 +37,11 @@
|
|||
|
||||
#include "doomtype.h"
|
||||
#include "vectors.h"
|
||||
#include "v_palette.h"
|
||||
#include "v_video.h"
|
||||
#include "colormatcher.h"
|
||||
#include "r_data/renderstyle.h"
|
||||
#include "r_data/r_translate.h"
|
||||
#include <vector>
|
||||
|
||||
struct FloatRect
|
||||
|
@ -308,6 +312,52 @@ protected:
|
|||
uint16_t Width, Height, WidthMask;
|
||||
static uint8_t GrayMap[256];
|
||||
FNativeTexture *Native;
|
||||
uint8_t *GetRemap(FRenderStyle style, bool srcisgrayscale = false)
|
||||
{
|
||||
if (style.Flags & STYLEF_RedIsAlpha)
|
||||
{
|
||||
return translationtables[TRANSLATION_Standard][srcisgrayscale ? STD_Gray : STD_Grayscale]->Remap;
|
||||
}
|
||||
else
|
||||
{
|
||||
return srcisgrayscale ? GrayMap : GPalette.Remap;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t RGBToPalettePrecise(bool wantluminance, int r, int g, int b, int a = 255)
|
||||
{
|
||||
if (wantluminance)
|
||||
{
|
||||
return (uint8_t)Luminance(r, g, b) * a / 255;
|
||||
}
|
||||
else
|
||||
{
|
||||
return ColorMatcher.Pick(r, g, b);
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t RGBToPalette(bool wantluminance, int r, int g, int b, int a = 255)
|
||||
{
|
||||
if (wantluminance)
|
||||
{
|
||||
// This is the same formula the OpenGL renderer uses for grayscale textures with an alpha channel.
|
||||
return (uint8_t)(Luminance(r, g, b) * a / 255);
|
||||
}
|
||||
else
|
||||
{
|
||||
return a < 128? 0 : RGB256k.RGB[r >> 2][g >> 2][b >> 2];
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t RGBToPalette(bool wantluminance, PalEntry pe, bool hasalpha = true)
|
||||
{
|
||||
return RGBToPalette(wantluminance, pe.r, pe.g, pe.b, hasalpha? pe.a : 255);
|
||||
}
|
||||
|
||||
uint8_t RGBToPalette(FRenderStyle style, int r, int g, int b, int a = 255)
|
||||
{
|
||||
return RGBToPalette(!!(style.Flags & STYLEF_RedIsAlpha), r, g, b, a);
|
||||
}
|
||||
|
||||
FTexture (const char *name = NULL, int lumpnum = -1);
|
||||
|
||||
|
|
|
@ -248,7 +248,7 @@ uint8_t *FTGATexture::MakeTexture (FRenderStyle style)
|
|||
r=g=b=a=0;
|
||||
break;
|
||||
}
|
||||
PaletteMap[i] = !alphatex? (a>=128? ColorMatcher.Pick(r, g, b) : 0) : (r * a) >> 8;
|
||||
PaletteMap[i] = RGBToPalettePrecise(r, g, b, a);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -307,7 +307,7 @@ uint8_t *FTGATexture::MakeTexture (FRenderStyle style)
|
|||
for(int x=0;x<Width;x++)
|
||||
{
|
||||
int v = LittleShort(*p);
|
||||
Pixels[x*Height + y] = !alphatex ? RGB256k.RGB[((v >> 10) & 0x1f) * 2][((v >> 5) & 0x1f) * 2][(v & 0x1f) * 2] : ((v >> 10) & 0x1f) * 8;
|
||||
Pixels[x*Height + y] = RGBToPalette(((v >> 10) & 0x1f) * 8, ((v >> 5) & 0x1f) * 8, (v & 0x1f) * 8);
|
||||
p+=step_x;
|
||||
}
|
||||
}
|
||||
|
@ -319,7 +319,7 @@ uint8_t *FTGATexture::MakeTexture (FRenderStyle style)
|
|||
uint8_t * p = ptr + y * Pitch;
|
||||
for(int x=0;x<Width;x++)
|
||||
{
|
||||
Pixels[x*Height + y] = !alphatex ? RGB256k.RGB[p[2] >> 2][p[1] >> 2][p[0] >> 2] : p[2];
|
||||
Pixels[x*Height + y] = RGBToPalette(p[2], p[1], p[0]);
|
||||
p+=step_x;
|
||||
}
|
||||
}
|
||||
|
@ -333,7 +333,7 @@ uint8_t *FTGATexture::MakeTexture (FRenderStyle style)
|
|||
uint8_t * p = ptr + y * Pitch;
|
||||
for(int x=0;x<Width;x++)
|
||||
{
|
||||
Pixels[x*Height + y] = !alphatex ? RGB256k.RGB[p[2] >> 2][p[1] >> 2][p[0] >> 2] : p[2];
|
||||
Pixels[x*Height + y] = RGBToPalette(p[2], p[1], p[0]);
|
||||
p+=step_x;
|
||||
}
|
||||
}
|
||||
|
@ -345,7 +345,7 @@ uint8_t *FTGATexture::MakeTexture (FRenderStyle style)
|
|||
uint8_t * p = ptr + y * Pitch;
|
||||
for(int x=0;x<Width;x++)
|
||||
{
|
||||
Pixels[x*Height + y] = !alphatex ? (p[3] >= 128 ? RGB256k.RGB[p[2] >> 2][p[1] >> 2][p[0] >> 2] : 0) : (p[2] * p[3]) >> 8;
|
||||
Pixels[x*Height + y] = RGBToPalette(p[2], p[1], p[0], p[3]);
|
||||
p+=step_x;
|
||||
}
|
||||
}
|
||||
|
@ -358,37 +358,39 @@ uint8_t *FTGATexture::MakeTexture (FRenderStyle style)
|
|||
break;
|
||||
|
||||
case 3: // Grayscale
|
||||
{
|
||||
auto remap = GetRemap(style, true);
|
||||
switch (hdr.bpp)
|
||||
{
|
||||
case 8:
|
||||
for(int y=0;y<Height;y++)
|
||||
for (int y = 0; y < Height; y++)
|
||||
{
|
||||
uint8_t * p = ptr + y * Pitch;
|
||||
for(int x=0;x<Width;x++)
|
||||
for (int x = 0; x < Width; x++)
|
||||
{
|
||||
Pixels[x*Height+y] = !alphatex? FTexture::GrayMap[*p] : *p;
|
||||
p+=step_x;
|
||||
Pixels[x*Height + y] = remap[*p];
|
||||
p += step_x;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case 16:
|
||||
for(int y=0;y<Height;y++)
|
||||
for (int y = 0; y < Height; y++)
|
||||
{
|
||||
uint8_t * p = ptr + y * Pitch;
|
||||
for(int x=0;x<Width;x++)
|
||||
for (int x = 0; x < Width; x++)
|
||||
{
|
||||
Pixels[x*Height+y] = !alphatex ? FTexture::GrayMap[p[1]] : p[1]; // only use the high byte
|
||||
p+=step_x;
|
||||
Pixels[x*Height + y] = remap[p[1]]; // only use the high byte
|
||||
p += step_x;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue