- moved special color maps to utilities.

The default tables are needed by the texture compositor which should be universal, so this needs to be, too.
This commit is contained in:
Christoph Oelckers 2020-04-11 18:18:01 +02:00
parent db62aeb671
commit 7243495b16
10 changed files with 197 additions and 155 deletions

View file

@ -39,6 +39,7 @@
#include "files.h" #include "files.h"
#include "filesystem.h" #include "filesystem.h"
#include "printf.h" #include "printf.h"
#include "templates.h"
/****************************/ /****************************/
/* Palette management stuff */ /* Palette management stuff */
@ -694,3 +695,130 @@ int V_GetColor(const uint32_t* palette, FScanner& sc)
return V_GetColor(palette, sc.String, &scc); return V_GetColor(palette, sc.String, &scc);
} }
//==========================================================================
//
// Special colormaps
//
//==========================================================================
TArray<FSpecialColormap> SpecialColormaps;
// These default tables are needed for texture composition.
static FSpecialColormapParameters SpecialColormapParms[] =
{
// Doom invulnerability is an inverted grayscale.
// Strife uses it when firing the Sigil
{ { 1, 1, 1 }, { 0, 0, 0 } },
// Heretic invulnerability is a golden shade.
{ { 0, 0, 0 }, { 1.5, 0.75, 0 }, },
// [BC] Build the Doomsphere colormap. It is red!
{ { 0, 0, 0 }, { 1.5, 0, 0 } },
// [BC] Build the Guardsphere colormap. It's a greenish-white kind of thing.
{ { 0, 0, 0 }, { 1.25, 1.5, 1 } },
// Build a blue colormap.
{ { 0, 0, 0 }, { 0, 0, 1.5 } },
// Repeated to get around the overridability of the other one
{ { 1, 1, 1 }, { 0, 0, 0 } },
};
//==========================================================================
//
//
//
//==========================================================================
void UpdateSpecialColormap(PalEntry* BaseColors, unsigned int index, float r1, float g1, float b1, float r2, float g2, float b2)
{
assert(index < SpecialColormaps.Size());
FSpecialColormap* cm = &SpecialColormaps[index];
cm->ColorizeStart[0] = float(r1);
cm->ColorizeStart[1] = float(g1);
cm->ColorizeStart[2] = float(b1);
cm->ColorizeEnd[0] = float(r2);
cm->ColorizeEnd[1] = float(g2);
cm->ColorizeEnd[2] = float(b2);
r2 -= r1;
g2 -= g1;
b2 -= b1;
r1 *= 255;
g1 *= 255;
b1 *= 255;
if (BaseColors) // only create this table if needed
{
for (int c = 0; c < 256; c++)
{
double intensity = (BaseColors[c].r * 77 +
BaseColors[c].g * 143 +
BaseColors[c].b * 37) / 256.0;
PalEntry pe = PalEntry(std::min(255, int(r1 + intensity * r2)),
std::min(255, int(g1 + intensity * g2)),
std::min(255, int(b1 + intensity * b2)));
cm->Colormap[c] = BestColor((uint32_t*)BaseColors, pe.r, pe.g, pe.b);
}
}
// This table is used by the texture composition code
for (int i = 0; i < 256; i++)
{
cm->GrayscaleToColor[i] = PalEntry(std::min(255, int(r1 + i * r2)),
std::min(255, int(g1 + i * g2)),
std::min(255, int(b1 + i * b2)));
}
}
//==========================================================================
//
//
//
//==========================================================================
int AddSpecialColormap(PalEntry *BaseColors, float r1, float g1, float b1, float r2, float g2, float b2)
{
// Clamp these in range for the hardware shader.
r1 = clamp(r1, 0.0f, 2.0f);
g1 = clamp(g1, 0.0f, 2.0f);
b1 = clamp(b1, 0.0f, 2.0f);
r2 = clamp(r2, 0.0f, 2.0f);
g2 = clamp(g2, 0.0f, 2.0f);
b2 = clamp(b2, 0.0f, 2.0f);
for (unsigned i = 1; i < SpecialColormaps.Size(); i++)
{
// Avoid precision issues here when trying to find a proper match.
if (fabs(SpecialColormaps[i].ColorizeStart[0] - r1) < FLT_EPSILON &&
fabs(SpecialColormaps[i].ColorizeStart[1] - g1) < FLT_EPSILON &&
fabs(SpecialColormaps[i].ColorizeStart[2] - b1) < FLT_EPSILON &&
fabs(SpecialColormaps[i].ColorizeEnd[0] - r2) < FLT_EPSILON &&
fabs(SpecialColormaps[i].ColorizeEnd[1] - g2) < FLT_EPSILON &&
fabs(SpecialColormaps[i].ColorizeEnd[2] - b2) < FLT_EPSILON)
{
return i; // The map already exists
}
}
UpdateSpecialColormap(BaseColors, SpecialColormaps.Reserve(1), r1, g1, b1, r2, g2, b2);
return SpecialColormaps.Size() - 1;
}
void InitSpecialColormaps(PalEntry *pe)
{
for (unsigned i = 0; i < countof(SpecialColormapParms); ++i)
{
AddSpecialColormap(pe, SpecialColormapParms[i].Start[0], SpecialColormapParms[i].Start[1],
SpecialColormapParms[i].Start[2], SpecialColormapParms[i].End[0],
SpecialColormapParms[i].End[1], SpecialColormapParms[i].End[2]);
}
}

View file

@ -29,3 +29,33 @@ FString V_GetColorStringByName(const char* name, FScriptPosition* sc = nullptr);
// Tries to get color by name, then by string // Tries to get color by name, then by string
int V_GetColor(const uint32_t* palette, const char* str, FScriptPosition* sc = nullptr); int V_GetColor(const uint32_t* palette, const char* str, FScriptPosition* sc = nullptr);
int V_GetColor(const uint32_t* palette, FScanner& sc); int V_GetColor(const uint32_t* palette, FScanner& sc);
enum
{
NOFIXEDCOLORMAP = -1,
INVERSECOLORMAP, // the inverse map is used explicitly in a few places.
GOLDCOLORMAP,
REDCOLORMAP,
GREENCOLORMAP,
BLUECOLORMAP,
REALINVERSECOLORMAP,
};
struct FSpecialColormapParameters
{
float Start[3], End[3];
};
struct FSpecialColormap
{
float ColorizeStart[3];
float ColorizeEnd[3];
uint8_t Colormap[256];
PalEntry GrayscaleToColor[256];
};
extern TArray<FSpecialColormap> SpecialColormaps;
int AddSpecialColormap(PalEntry *pe, float r1, float g1, float b1, float r2, float g2, float b2);
void InitSpecialColormaps(PalEntry* pe);
void UpdateSpecialColormap(PalEntry* BaseColors, unsigned int index, float r1, float g1, float b1, float r2, float g2, float b2);

View file

@ -33,9 +33,27 @@
*/ */
#include "bitmap.h" #include "bitmap.h"
#include "r_data/r_translate.h" #include "palutil.h"
#include "r_data/colormaps.h"
uint8_t IcePalette[16][3] =
{
{ 10, 8, 18 },
{ 15, 15, 26 },
{ 20, 16, 36 },
{ 30, 26, 46 },
{ 40, 36, 57 },
{ 50, 46, 67 },
{ 59, 57, 78 },
{ 69, 67, 88 },
{ 79, 77, 99 },
{ 89, 87,109 },
{ 99, 97,120 },
{ 109,107,130 },
{ 118,118,141 },
{ 128,128,151 },
{ 138,138,162 },
{ 148,148,172 }
};
//=========================================================================== //===========================================================================
// //

View file

@ -474,13 +474,13 @@ void FMultipatchTextureBuilder::ParsePatch(FScanner &sc, BuildInfo &info, TexPar
if (part.Translation != NULL) delete part.Translation; if (part.Translation != NULL) delete part.Translation;
part.Translation = NULL; part.Translation = NULL;
part.Blend = 0; part.Blend = 0;
static const char *maps[] = { "inverse", "gold", "red", "green", "blue", NULL }; static const char *maps[] = { "gold", "red", "green", "blue", "inverse", NULL };
sc.MustGetString(); sc.MustGetString();
match = sc.MatchString(maps); match = sc.MatchString(maps);
if (match >= 0) if (match >= 0)
{ {
part.Blend = BLEND_SPECIALCOLORMAP1 + match; part.Blend = BLEND_SPECIALCOLORMAP1 + match + 1;
} }
else if (sc.Compare("ICE")) else if (sc.Compare("ICE"))
{ {
@ -528,7 +528,7 @@ void FMultipatchTextureBuilder::ParsePatch(FScanner &sc, BuildInfo &info, TexPar
b1 = (float)sc.Float; b1 = (float)sc.Float;
if (!sc.CheckString(",")) if (!sc.CheckString(","))
{ {
part.Blend = AddSpecialColormap(0, 0, 0, r1, g1, b1); part.Blend = AddSpecialColormap(GPalette.BaseColors, 0, 0, 0, r1, g1, b1);
} }
else else
{ {
@ -540,7 +540,7 @@ void FMultipatchTextureBuilder::ParsePatch(FScanner &sc, BuildInfo &info, TexPar
sc.MustGetStringName(","); sc.MustGetStringName(",");
sc.MustGetFloat(); sc.MustGetFloat();
b2 = (float)sc.Float; b2 = (float)sc.Float;
part.Blend = AddSpecialColormap(r1, g1, b1, r2, g2, b2); part.Blend = AddSpecialColormap(GPalette.BaseColors, r1, g1, b1, r2, g2, b2);
} }
} }
else if (sc.Compare("Blend")) else if (sc.Compare("Blend"))

View file

@ -62,114 +62,13 @@ CUSTOM_CVAR(Color, cl_custominvulmapcolor2, 0xa6a67a, CVAR_ARCHIVE|CVAR_NOINITCA
TArray<FakeCmap> fakecmaps; TArray<FakeCmap> fakecmaps;
TArray<FSpecialColormap> SpecialColormaps;
uint8_t DesaturateColormap[31][256]; uint8_t DesaturateColormap[31][256];
struct FSpecialColormapParameters
{
float Start[3], End[3];
};
static FSpecialColormapParameters SpecialColormapParms[] =
{
// Doom invulnerability is an inverted grayscale.
// Strife uses it when firing the Sigil
{ { 1, 1, 1 }, { 0, 0, 0 } },
// Heretic invulnerability is a golden shade.
{ { 0, 0, 0 }, { 1.5, 0.75, 0 }, },
// [BC] Build the Doomsphere colormap. It is red!
{ { 0, 0, 0 }, { 1.5, 0, 0 } },
// [BC] Build the Guardsphere colormap. It's a greenish-white kind of thing.
{ { 0, 0, 0 }, { 1.25, 1.5, 1 } },
// Build a blue colormap.
{ { 0, 0, 0 }, { 0, 0, 1.5 } },
};
static void FreeSpecialLights(); static void FreeSpecialLights();
//==========================================================================
//
//
//
//==========================================================================
static void UpdateSpecialColormap(unsigned int index, float r1, float g1, float b1, float r2, float g2, float b2);
int AddSpecialColormap(float r1, float g1, float b1, float r2, float g2, float b2)
{
// Clamp these in range for the hardware shader.
r1 = clamp(r1, 0.0f, 2.0f);
g1 = clamp(g1, 0.0f, 2.0f);
b1 = clamp(b1, 0.0f, 2.0f);
r2 = clamp(r2, 0.0f, 2.0f);
g2 = clamp(g2, 0.0f, 2.0f);
b2 = clamp(b2, 0.0f, 2.0f);
for(unsigned i=0; i<SpecialColormaps.Size(); i++)
{
// Avoid precision issues here when trying to find a proper match.
if (fabs(SpecialColormaps[i].ColorizeStart[0]- r1) < FLT_EPSILON &&
fabs(SpecialColormaps[i].ColorizeStart[1]- g1) < FLT_EPSILON &&
fabs(SpecialColormaps[i].ColorizeStart[2]- b1) < FLT_EPSILON &&
fabs(SpecialColormaps[i].ColorizeEnd[0]- r2) < FLT_EPSILON &&
fabs(SpecialColormaps[i].ColorizeEnd[1]- g2) < FLT_EPSILON &&
fabs(SpecialColormaps[i].ColorizeEnd[2]- b2) < FLT_EPSILON)
{
return i; // The map already exists
}
}
UpdateSpecialColormap(SpecialColormaps.Reserve(1), r1, g1, b1, r2, g2, b2);
return SpecialColormaps.Size() - 1;
}
static void UpdateSpecialColormap(unsigned int index, float r1, float g1, float b1, float r2, float g2, float b2)
{
assert(index < SpecialColormaps.Size());
FSpecialColormap *cm = &SpecialColormaps[index];
cm->ColorizeStart[0] = float(r1);
cm->ColorizeStart[1] = float(g1);
cm->ColorizeStart[2] = float(b1);
cm->ColorizeEnd[0] = float(r2);
cm->ColorizeEnd[1] = float(g2);
cm->ColorizeEnd[2] = float(b2);
r2 -= r1;
g2 -= g1;
b2 -= b1;
r1 *= 255;
g1 *= 255;
b1 *= 255;
for (int c = 0; c < 256; c++)
{
double intensity = (GPalette.BaseColors[c].r * 77 +
GPalette.BaseColors[c].g * 143 +
GPalette.BaseColors[c].b * 37) / 256.0;
PalEntry pe = PalEntry( MIN(255, int(r1 + intensity*r2)),
MIN(255, int(g1 + intensity*g2)),
MIN(255, int(b1 + intensity*b2)));
cm->Colormap[c] = ColorMatcher.Pick(pe);
}
// This table is used by the texture composition code
for(int i = 0;i < 256; i++)
{
cm->GrayscaleToColor[i] = PalEntry( MIN(255, int(r1 + i*r2)),
MIN(255, int(g1 + i*g2)),
MIN(255, int(b1 + i*b2)));
}
}
//========================================================================== //==========================================================================
// //
// R_DeinitColormaps // R_DeinitColormaps
@ -267,13 +166,9 @@ void R_InitColormaps (bool allowCustomColormap)
} }
// build default special maps (e.g. invulnerability) // build default special maps (e.g. invulnerability)
InitSpecialColormaps(GPalette.BaseColors);
R_UpdateInvulnerabilityColormap();
for (unsigned i = 0; i < countof(SpecialColormapParms); ++i)
{
AddSpecialColormap(SpecialColormapParms[i].Start[0], SpecialColormapParms[i].Start[1],
SpecialColormapParms[i].Start[2], SpecialColormapParms[i].End[0],
SpecialColormapParms[i].End[1], SpecialColormapParms[i].End[2]);
}
// desaturated colormaps. These are used for texture composition // desaturated colormaps. These are used for texture composition
for(int m = 0; m < 31; m++) for(int m = 0; m < 31; m++)
{ {
@ -339,32 +234,24 @@ uint32_t R_BlendForColormap (uint32_t map)
void R_UpdateInvulnerabilityColormap() void R_UpdateInvulnerabilityColormap()
{ {
float r1, g1, b1, r2, g2, b2;
// some of us really don't like Doom's idea of an invulnerability sphere colormap // some of us really don't like Doom's idea of an invulnerability sphere colormap
// this hack will override that // this hack will override that
if (cl_customizeinvulmap) if (cl_customizeinvulmap)
{ {
uint32_t color1 = cl_custominvulmapcolor1; uint32_t color1 = cl_custominvulmapcolor1;
uint32_t color2 = cl_custominvulmapcolor2; uint32_t color2 = cl_custominvulmapcolor2;
r1 = (float)((color1 & 0xff0000) >> 16) / 128.f; float r1 = (float)((color1 & 0xff0000) >> 16) / 128.f;
g1 = (float)((color1 & 0x00ff00) >> 8) / 128.f; float g1 = (float)((color1 & 0x00ff00) >> 8) / 128.f;
b1 = (float)((color1 & 0x0000ff) >> 0) / 128.f; float b1 = (float)((color1 & 0x0000ff) >> 0) / 128.f;
r2 = (float)((color2 & 0xff0000) >> 16) / 128.f; float r2 = (float)((color2 & 0xff0000) >> 16) / 128.f;
g2 = (float)((color2 & 0x00ff00) >> 8) / 128.f; float g2 = (float)((color2 & 0x00ff00) >> 8) / 128.f;
b2 = (float)((color2 & 0x0000ff) >> 0) / 128.f; float b2 = (float)((color2 & 0x0000ff) >> 0) / 128.f;
UpdateSpecialColormap(GPalette.BaseColors, 0, r1, g1, b1, r2, g2, b2);
} }
else else
{ {
FSpecialColormapParameters &defaultColors = SpecialColormapParms[0]; SpecialColormaps[INVERSECOLORMAP] = SpecialColormaps[REALINVERSECOLORMAP];
r1 = defaultColors.Start[0];
g1 = defaultColors.Start[1];
b1 = defaultColors.Start[2];
r2 = defaultColors.End[0];
g2 = defaultColors.End[1];
b2 = defaultColors.End[2];
} }
UpdateSpecialColormap(0, r1, g1, b1, r2, g2, b2);
} }

View file

@ -97,23 +97,6 @@ struct FColormapStyle
float FadeLevel; float FadeLevel;
}; };
enum
{
NOFIXEDCOLORMAP = -1,
INVERSECOLORMAP, // the inverse map is used explicitly in a few places.
};
struct FSpecialColormap
{
float ColorizeStart[3];
float ColorizeEnd[3];
uint8_t Colormap[256];
PalEntry GrayscaleToColor[256];
};
extern TArray<FSpecialColormap> SpecialColormaps;
// some utility functions to store special colormaps in powerup blends // some utility functions to store special colormaps in powerup blends
#define SPECIALCOLORMAP_MASK 0x00b60000 #define SPECIALCOLORMAP_MASK 0x00b60000
@ -123,10 +106,6 @@ inline uint32_t MakeSpecialColormap(int index)
return index | SPECIALCOLORMAP_MASK; return index | SPECIALCOLORMAP_MASK;
} }
int AddSpecialColormap(float r1, float g1, float b1, float r2, float g2, float b2);
extern uint8_t DesaturateColormap[31][256]; extern uint8_t DesaturateColormap[31][256];

View file

@ -271,7 +271,7 @@ int HWDrawInfo::SetFullbrightFlags(player_t *player)
int cm = CM_DEFAULT; int cm = CM_DEFAULT;
if (cplayer->extralight == INT_MIN) if (cplayer->extralight == INT_MIN)
{ {
cm = CM_FIRSTSPECIALCOLORMAP + INVERSECOLORMAP; cm = CM_FIRSTSPECIALCOLORMAP + REALINVERSECOLORMAP;
Viewpoint.extralight = 0; Viewpoint.extralight = 0;
FullbrightFlags = Fullbright; FullbrightFlags = Fullbright;
// This does never set stealth vision. // This does never set stealth vision.

View file

@ -87,7 +87,7 @@ namespace swrenderer
// [RH] Inverse light for shooting the Sigil // [RH] Inverse light for shooting the Sigil
if (fixedcolormap == nullptr && viewpoint.extralight == INT_MIN) if (fixedcolormap == nullptr && viewpoint.extralight == INT_MIN)
{ {
fixedcolormap = &SpecialSWColormaps[INVERSECOLORMAP]; fixedcolormap = &SpecialSWColormaps[REALINVERSECOLORMAP];
viewpoint.extralight = 0; viewpoint.extralight = 0;
} }
} }

View file

@ -377,7 +377,7 @@ namespace swrenderer
if (visstyle.Invert) if (visstyle.Invert)
{ {
vis.Light.BaseColormap = &SpecialSWColormaps[INVERSECOLORMAP]; vis.Light.BaseColormap = &SpecialSWColormaps[REALINVERSECOLORMAP];
vis.Light.ColormapNum = 0; vis.Light.ColormapNum = 0;
noaccel = true; noaccel = true;
} }

View file

@ -1276,7 +1276,7 @@ DEFINE_CLASS_PROPERTY_PREFIX(powerup, colormap, FFFfff, Inventory)
PROP_FLOAT_PARM(r, 0); PROP_FLOAT_PARM(r, 0);
PROP_FLOAT_PARM(g, 1); PROP_FLOAT_PARM(g, 1);
PROP_FLOAT_PARM(b, 2); PROP_FLOAT_PARM(b, 2);
BlendColor = MakeSpecialColormap(AddSpecialColormap(0, 0, 0, r, g, b)); BlendColor = MakeSpecialColormap(AddSpecialColormap(GPalette.BaseColors, 0, 0, 0, r, g, b));
} }
else if (PROP_PARM_COUNT == 6) else if (PROP_PARM_COUNT == 6)
{ {
@ -1286,7 +1286,7 @@ DEFINE_CLASS_PROPERTY_PREFIX(powerup, colormap, FFFfff, Inventory)
PROP_FLOAT_PARM(r2, 3); PROP_FLOAT_PARM(r2, 3);
PROP_FLOAT_PARM(g2, 4); PROP_FLOAT_PARM(g2, 4);
PROP_FLOAT_PARM(b2, 5); PROP_FLOAT_PARM(b2, 5);
BlendColor = MakeSpecialColormap(AddSpecialColormap(r1, g1, b1, r2, g2, b2)); BlendColor = MakeSpecialColormap(AddSpecialColormap(GPalette.BaseColors, r1, g1, b1, r2, g2, b2));
} }
else else
{ {