- hooked up the high color texture colorization code.

Not tested and probably still not working correctly, the entire feature was a nearly impenetrable mess of convoluted code. This definitely needs verification with multiple mods using it.
This commit is contained in:
Christoph Oelckers 2020-01-11 22:18:06 +01:00
parent 17eddda36c
commit 55dab6d3d3
15 changed files with 131 additions and 128 deletions

View file

@ -2877,29 +2877,29 @@ void UpdateDacs(int nPalette, bool bNoTint)
{
case 0:
default:
tint->r = 255;
tint->g = 255;
tint->b = 255;
tint->tint.r = 255;
tint->tint.g = 255;
tint->tint.b = 255;
break;
case 1:
tint->r = 132;
tint->g = 164;
tint->b = 255;
tint->tint.r = 132;
tint->tint.g = 164;
tint->tint.b = 255;
break;
case 2:
tint->r = 255;
tint->g = 126;
tint->b = 105;
tint->tint.r = 255;
tint->tint.g = 126;
tint->tint.b = 105;
break;
case 3:
tint->r = 162;
tint->g = 186;
tint->b = 15;
tint->tint.r = 162;
tint->tint.g = 186;
tint->tint.b = 15;
break;
case 4:
tint->r = 255;
tint->g = 255;
tint->b = 255;
tint->tint.r = 255;
tint->tint.g = 255;
tint->tint.b = 255;
break;
}
if (!bNoTint)
@ -3709,9 +3709,9 @@ void viewSetCrosshairColor(int32_t r, int32_t g, int32_t b)
#ifdef USE_OPENGL
// XXX: this makes us also load all hightile textures tinted with the crosshair color!
polytint_t & crosshairtint = hictinting[CROSSHAIR_PAL];
crosshairtint.r = CrosshairColors.r;
crosshairtint.g = CrosshairColors.g;
crosshairtint.b = CrosshairColors.b;
crosshairtint.tint.r = CrosshairColors.r;
crosshairtint.tint.g = CrosshairColors.g;
crosshairtint.tint.b = CrosshairColors.b;
crosshairtint.f = HICTINT_USEONART | HICTINT_GRAYSCALE;
#endif
tileInvalidate(kCrosshairTile, -1, -1);

View file

@ -1,21 +1,16 @@
#ifndef HIGHTILE_PRIV_H
#define HIGHTILE_PRIV_H
#include "palentry.h"
typedef struct {
polytintflags_t f;
uint8_t r, g, b;
uint8_t sr, sg, sb;
PalEntry tint;
PalEntry shade;
} polytint_t;
extern polytint_t hictinting[MAXPALOOKUPS];
static inline void globaltinting_apply(float *color)
{
color[0] *= (float)globalr * (1.f/255.f);
color[1] *= (float)globalg * (1.f/255.f);
color[2] *= (float)globalb * (1.f/255.f);
}
// replacement flags
enum
@ -39,11 +34,8 @@ enum
HICTINT_BLEND_HARDLIGHT = 3<<6,
HICTINT_BLENDMASK = 64|128,
HICTINT_ALWAYSUSEART = 256,
HICTINT_PRECOMPUTED = HICTINT_COLORIZE | HICTINT_BLENDMASK,
HICTINT_IN_MEMORY = HICTINT_PRECOMPUTED | HICTINT_GRAYSCALE | HICTINT_INVERT,
HICTINT_MEMORY_COMBINATIONS = 1<<5,
};
#endif

View file

@ -24,7 +24,7 @@ void hicinit(void)
for (i=0; i<MAXPALOOKUPS; i++) // all tints should be 100%
{
polytint_t & tint = hictinting[i];
tint.r = tint.g = tint.b = 0xff;
tint.tint = 0xffffff;
tint.f = 0;
}
}
@ -41,12 +41,12 @@ void hicsetpalettetint(int32_t palnum, char r, char g, char b, char sr, char sg,
if ((uint32_t)palnum >= (uint32_t)MAXPALOOKUPS) return;
polytint_t & tint = hictinting[palnum];
tint.r = r;
tint.g = g;
tint.b = b;
tint.sr = sr;
tint.sg = sg;
tint.sb = sb;
tint.tint.r = r;
tint.tint.g = g;
tint.tint.b = b;
tint.shade.r = sr;
tint.shade.g = sg;
tint.shade.b = sb;
tint.f = effect;
}

View file

@ -1591,8 +1591,6 @@ static int32_t polymost_md3draw(md3model_t *m, tspriteptr_t tspr)
// tinting
pc[0] = pc[1] = pc[2] = ((float)numshades - min(max((globalshade * hw_shadescale) + m->shadeoff, 0.f), (float)numshades)) / (float)numshades;
auto h = hictinting[globalpal];
GLInterface.SetTinting(h.f, PalEntry(h.sr, h.sg, h.sb), PalEntry(h.r, h.g, h.b));
pc[3] = (tspr->cstat&2) ? glblend[tspr->blend].def[!!(tspr->cstat&512)].alpha : 1.0f;
pc[3] *= 1.0f - sext->alpha;

View file

@ -532,7 +532,6 @@ static void polymost_drawpoly(vec2f_t const * const dpxy, int32_t const n, int32
else if (drawpoly_trepeat) sampleroverride = SamplerClampX;
else sampleroverride = SamplerClampXY;
bool success = GLInterface.SetTexture(globalpicnum, TileFiles.tiles[globalpicnum], globalpal, method, sampleroverride);
if (!success)
{
@ -560,16 +559,6 @@ static void polymost_drawpoly(vec2f_t const * const dpxy, int32_t const n, int32
GLInterface.SetNpotEmulation(false, 1.f, 0.f);
}
vec2f_t hacksc = { 1.f, 1.f };
#if 0
if (pth->flags & PTH_HIGHTILE)
{
hacksc = pth->scale;
tsiz = pth->siz;
}
#endif
vec2_t tsiz2 = tsiz;
@ -580,28 +569,18 @@ static void polymost_drawpoly(vec2f_t const * const dpxy, int32_t const n, int32
float pc[4];
polytint_t const& tint = hictinting[globalpal];
// This makes no sense.
pc[0] = 1.f;// (1.f - (tint.sr * (1.f / 255.f))) + (tint.sr * (1.f / 255.f));
pc[1] = 1.f;// (1.f - (tint.sg * (1.f / 255.f))) + (tint.sg * (1.f / 255.f));
pc[2] = 1.f;// (1.f - (tint.sb * (1.f / 255.f))) + (tint.sb * (1.f / 255.f));
// spriteext full alpha control
// The shade rgb from the tint is ignored here.
pc[0] = (float)globalr * (1.f / 255.f);
pc[1] = (float)globalg * (1.f / 255.f);
pc[2] = (float)globalb * (1.f / 255.f);
pc[3] = float_trans(method & DAMETH_MASKPROPS, drawpoly_blend) * (1.f - drawpoly_alpha);
// tinting
auto& h = hictinting[globalpal];
GLInterface.SetTinting(h.f, PalEntry(h.sr, h.sg, h.sb), PalEntry(h.r, h.g, h.b));
globaltinting_apply(pc);
if (skyzbufferhack_pass)
pc[3] = 0.01f;
GLInterface.SetColor(pc[0], pc[1], pc[2], pc[3]);
vec2f_t const scale = { 1.f / tsiz2.x * hacksc.x, 1.f / tsiz2.y * hacksc.y };
vec2f_t const scale = { 1.f / tsiz2.x, 1.f / tsiz2.y };
auto data = GLInterface.AllocVertices(npoints);
auto vt = data.second;
for (bssize_t i = 0; i < npoints; ++i, vt++)
@ -3237,7 +3216,7 @@ void polymost_drawrooms()
// This is a global setting for the entire scene, so let's do it here, right at the start.
auto& hh = hictinting[MAXPALOOKUPS - 1];
// This sets a tinting color for global palettes, e.g. water or slime - only used for hires replacements (also an option for low-resource hardware where duplicating the textures may be problematic.)
GLInterface.SetBasepalTint(PalEntry(hh.r, hh.g, hh.b));
GLInterface.SetBasepalTint(hh.tint);
polymost_outputGLDebugMessage(3, "polymost_drawrooms()");

View file

@ -1082,9 +1082,6 @@ int32_t polymost_voxdraw(voxmodel_t *m, tspriteptr_t const tspr)
pc[0] = pc[1] = pc[2] = ((float)numshades - min(max((globalshade * hw_shadescale) + m->shadeoff, 0.f), (float)numshades)) / (float)numshades;
auto& h = hictinting[globalpal];
GLInterface.SetTinting(h.f, PalEntry(h.sr, h.sg, h.sb), PalEntry(h.r, h.g, h.b));
if (!shadowHack)
{
pc[3] = (tspr->cstat & 2) ? glblend[tspr->blend].def[!!(tspr->cstat & 512)].alpha : 1.0f;

View file

@ -166,9 +166,9 @@ void G_SetCrosshairColor(int32_t r, int32_t g, int32_t b)
#ifdef USE_OPENGL
// XXX: this makes us also load all hightile textures tinted with the crosshair color!
polytint_t & crosshairtint = hictinting[CROSSHAIR_PAL];
crosshairtint.r = CrosshairColors.r;
crosshairtint.g = CrosshairColors.g;
crosshairtint.b = CrosshairColors.b;
crosshairtint.tint.r = CrosshairColors.r;
crosshairtint.tint.g = CrosshairColors.g;
crosshairtint.tint.b = CrosshairColors.b;
crosshairtint.f = HICTINT_USEONART | HICTINT_GRAYSCALE;
#endif
tileInvalidate(CROSSHAIR, -1, -1);
@ -761,23 +761,23 @@ void G_DisplayRest(int32_t smoothratio)
if (pp->palette == WATERPAL)
{
fstint.r = 224;
fstint.g = 192;
fstint.b = 255;
fstint.tint.r = 224;
fstint.tint.g = 192;
fstint.tint.b = 255;
fstint.f = 0;
}
else if (pp->palette == SLIMEPAL)
{
fstint.r = 208;
fstint.g = 255;
fstint.b = 192;
fstint.tint.r = 208;
fstint.tint.g = 255;
fstint.tint.b = 192;
fstint.f = 0;
}
else
{
fstint.r = 255;
fstint.g = 255;
fstint.b = 255;
fstint.tint.r = 255;
fstint.tint.g = 255;
fstint.tint.b = 255;
fstint.f = 0;
}
}

View file

@ -35,6 +35,7 @@ enum PRSFlags
RF_HICTINT_BLEND_Overlay = 0x100000,
RF_HICTINT_BLEND_Hardlight = 0x200000,
RF_HICTINT_BLENDMASK = RF_HICTINT_BLEND_Screen | RF_HICTINT_BLEND_Overlay | RF_HICTINT_BLEND_Hardlight,
RF_HICTINT_MASK = 0x3f0000,
STF_BLEND = 1,
STF_COLORMASK = 2,
@ -68,6 +69,8 @@ struct PolymostRenderState
bool AlphaTest = true;
float Color[4] = { 1,1,1,1 };
short matrixIndex[NUMMATRICES] = { -1,-1,-1,-1,-1 };
PalEntry fullscreenTint = 0xffffff, hictint = 0, hictint_overlay = 0xffffff;
int hictint_flags = 0;
int StateFlags = STF_COLORMASK|STF_DEPTHMASK;
FRenderStyle Style{};

View file

@ -144,6 +144,9 @@ bool PolymostShader::Load(const char * name, const char * vert_prog, const char
Brightness.Init(hShader, "u_brightness");
FogColor.Init(hShader, "u_fogColor");
AlphaThreshold.Init(hShader, "u_alphaThreshold");
TintModulate.Init(hShader, "u_tintModulate");
TintOverlay.Init(hShader, "u_tintOverlay");
TintFlags.Init(hShader, "u_tintFlags");
RotMatrix.Init(hShader, "u_rotMatrix");
ModelMatrix.Init(hShader, "u_modelMatrix");

View file

@ -45,6 +45,10 @@ public:
FBufferedUniform1f Brightness;
FBufferedUniform1f AlphaThreshold;
FBufferedUniformPalEntry FogColor;
FBufferedUniformPalEntry TintModulate;
FBufferedUniformPalEntry TintOverlay;
FBufferedUniform1i TintFlags;
FUniformMatrix4f RotMatrix;
FUniformMatrix4f ModelMatrix;

View file

@ -164,24 +164,37 @@ bool GLInstance::SetTextureInternal(int picnum, FTexture* tex, int palette, int
int lookuppal = 0;
VSMatrix texmat;
auto rep = hw_hightile? tex->FindReplacement(palette) : nullptr;
auto& h = hictinting[palette];
bool applytint = false;
auto rep = (hw_hightile && !(h.f & HICTINT_ALWAYSUSEART)) ? tex->FindReplacement(palette) : nullptr;
if (rep)
{
// Hightile replacements have only one texture representation and it is always the base.
tex = rep->faces[0];
TextureType = TT_HICREPLACE;
if (rep->palnum != palette || (h.f & HICTINT_APPLYOVERALTPAL)) applytint = true;
}
else
{
// Only look up the palette if we really want to use it (i.e. when creating a true color texture of an ART tile.)
if (TextureType == TT_TRUECOLOR)
{
/*lookuppal = palmanager.LookupPalette(usepalette, usepalswap, true);
if (lookuppal< 0)*/ lookuppal = palmanager.LookupPalette(usepalette, usepalswap, false, g_nontransparent255);
// Tinting is not used on indexed textures
if (h.f & (HICTINT_ALWAYSUSEART | HICTINT_USEONART))
{
applytint = true;
if (!(h.f & HICTINT_APPLYOVERPALSWAP)) usepalswap = 0;
}
lookuppal = palmanager.LookupPalette(usepalette, usepalswap, false, g_nontransparent255);
}
}
// This is intentionally the same value for both parameters. The shader does not use the same uniform for modulation and overlay colors.
if (applytint) GLInterface.SetTinting(h.f, h.tint, h.tint);
else GLInterface.SetTinting(-1, 0xffffff, 0xffffff);
// Load the main texture
auto mtex = LoadTexture(tex, TextureType, lookuppal);
if (mtex)

View file

@ -481,6 +481,9 @@ void PolymostRenderState::Apply(PolymostShader* shader, GLState &oldState)
shader->AlphaThreshold.Set(AlphaTest ? AlphaThreshold : -1.f);
shader->Brightness.Set(Brightness);
shader->FogColor.Set(FogColor);
shader->TintFlags.Set(hictint_flags);
shader->TintModulate.Set(hictint);
shader->TintOverlay.Set(hictint_overlay);
if (matrixIndex[Matrix_View] != -1)
shader->RotMatrix.Set(matrixArray[matrixIndex[Matrix_View]].get());
if (matrixIndex[Matrix_Projection] != -1)

View file

@ -520,14 +520,16 @@ public:
renderState.Brightness = 8.f / (brightness + 8.f);
}
void SetTinting(int flags, PalEntry color, PalEntry modulateColor)
void SetTinting(int flags, PalEntry color, PalEntry overlayColor)
{
// not yet implemented.
renderState.hictint = color;
renderState.hictint_overlay = overlayColor;
renderState.hictint_flags = flags;
}
void SetBasepalTint(PalEntry color)
{
// not yet implemented - only relevant for hires replacements.
renderState.fullscreenTint = color;
}
int GetPaletteIndex(PalEntry* palette)

View file

@ -159,9 +159,9 @@ void G_SetCrosshairColor(int32_t r, int32_t g, int32_t b)
#ifdef USE_OPENGL
// XXX: this makes us also load all hightile textures tinted with the crosshair color!
polytint_t & crosshairtint = hictinting[CROSSHAIR_PAL];
crosshairtint.r = CrosshairColors.r;
crosshairtint.g = CrosshairColors.g;
crosshairtint.b = CrosshairColors.b;
crosshairtint.tint.r = CrosshairColors.r;
crosshairtint.tint.g = CrosshairColors.g;
crosshairtint.tint.b = CrosshairColors.b;
crosshairtint.f = HICTINT_USEONART | HICTINT_GRAYSCALE;
#endif
tileInvalidate(CROSSHAIR, -1, -1);
@ -759,23 +759,23 @@ void G_DisplayRest(int32_t smoothratio)
if (pp->palette == WATERPAL)
{
fstint.r = 224;
fstint.g = 192;
fstint.b = 255;
fstint.tint.r = 224;
fstint.tint.g = 192;
fstint.tint.b = 255;
fstint.f = 0;
}
else if (pp->palette == SLIMEPAL)
{
fstint.r = 208;
fstint.g = 255;
fstint.b = 192;
fstint.tint.r = 208;
fstint.tint.g = 255;
fstint.tint.b = 192;
fstint.f = 0;
}
else
{
fstint.r = 255;
fstint.g = 255;
fstint.b = 255;
fstint.tint.r = 255;
fstint.tint.g = 255;
fstint.tint.b = 255;
fstint.f = 0;
}
}

View file

@ -9,12 +9,12 @@ const int RF_NPOTEmulation = 32;
const int RF_ShadeInterpolate = 64;
const int RF_FogDisabled = 128;
const int RF_HICTINT_Grayscale = 0x10000;
const int RF_HICTINT_Invert = 0x20000;
const int RF_HICTINT_Colorize = 0x40000;
const int RF_HICTINT_BLEND_Screen = 0x80000;
const int RF_HICTINT_BLEND_Overlay = 0x100000;
const int RF_HICTINT_BLEND_Hardlight = 0x200000;
const int RF_HICTINT_Grayscale = 0x1;
const int RF_HICTINT_Invert = 0x2;
const int RF_HICTINT_Colorize = 0x4;
const int RF_HICTINT_BLEND_Screen = 64;
const int RF_HICTINT_BLEND_Overlay = 128;
const int RF_HICTINT_BLEND_Hardlight = 192;
const int RF_HICTINT_BLENDMASK = RF_HICTINT_BLEND_Screen | RF_HICTINT_BLEND_Overlay | RF_HICTINT_BLEND_Hardlight;
@ -36,6 +36,9 @@ uniform float u_visFactor;
uniform int u_flags;
uniform float u_alphaThreshold;
uniform vec4 u_tintOverlay, u_tintModulate;
uniform int u_tintFlags;
uniform float u_npotEmulationFactor;
uniform float u_npotEmulationXOffset;
uniform float u_brightness;
@ -81,51 +84,56 @@ float grayscale(vec4 color)
//
//===========================================================================
vec4 convertColor(vec4 color, int effect, vec3 tint)
vec4 convertColor(vec4 color)
{
#if 0
if (effect & RF_HICTINT_Grayscale)
int effect = u_tintFlags;
if ((effect & RF_HICTINT_Grayscale) != 0)
{
float g = grayscale(color);
color = vec4(g, g, g, color.a);
}
if (effect & RF_HICTINT_Invert)
if ((effect & RF_HICTINT_Invert) != 0)
{
color = vec4(1.0 - color.r, 1.0 - color.g, 1.0 - color.b);
color = vec4(1.0 - color.r, 1.0 - color.g, 1.0 - color.b, color.a);
}
vec3 tcol = color.rgb * 255.0; // * 255.0 to make it easier to reuse the integer math.
tint *= 255.0;
if (effect & RF_HICTINT_Colorize)
// Much of this looks quite broken by design. Why is this effectively multplied by 4 if the flag is set...? :(
if ((effect & RF_HICTINT_Colorize) != 0)
{
tcol.b = min(((tcol.b) * tint.r) / 64.0, 255.0);
tcol.g = min(((tcol.g) * tint.g) / 64.0, 255.0);
tcol.r = min(((tcol.r) * tint.b) / 64.0, 255.0);
tcol.b = min(((tcol.b) * u_tintModulate.r)* 4, 255.0);
tcol.g = min(((tcol.g) * u_tintModulate.g)* 4, 255.0);
tcol.r = min(((tcol.r) * u_tintModulate.b)* 4, 255.0);
}
else
{
tcol.b = min(((tcol.b) * u_tintModulate.r), 255.0);
tcol.g = min(((tcol.g) * u_tintModulate.g), 255.0);
tcol.r = min(((tcol.r) * u_tintModulate.b), 255.0);
}
vec4 ov = u_tintOverlay * 255.0;
switch (effect & RF_HICTINT_BLENDMASK)
{
case RF_HICTINT_BLEND_Screen:
tcol.b = 255.0 - (((255.0 - tcol.b) * (255.0 - tint.r)) / 256.0);
tcol.g = 255.0 - (((255.0 - tcol.g) * (255.0 - tint.g)) / 256.0);
tcol.r = 255.0 - (((255.0 - tcol.r) * (255.0 - tint.b)) / 256.0);
tcol.b = 255.0 - (((255.0 - tcol.b) * (255.0 - ov.r)) / 256.0);
tcol.g = 255.0 - (((255.0 - tcol.g) * (255.0 - ov.g)) / 256.0);
tcol.r = 255.0 - (((255.0 - tcol.r) * (255.0 - ov.b)) / 256.0);
break;
case RF_HICTINT_BLEND_Overlay:
tcol.b = tcol.b < 128.0? (tcol.b * tint.r) / 128.0 : 255.0 - (((255.0 - tcol.b) * (255.0 - tint.r)) / 128.0);
tcol.g = tcol.g < 128.0? (tcol.g * tint.g) / 128.0 : 255.0 - (((255.0 - tcol.g) * (255.0 - tint.g)) / 128.0);
tcol.r = tcol.r < 128.0? (tcol.r * tint.b) / 128.0 : 255.0 - (((255.0 - tcol.r) * (255.0 - tint.b)) / 128.0);
tcol.b = tcol.b < 128.0? (tcol.b * ov.r) / 128.0 : 255.0 - (((255.0 - tcol.b) * (255.0 - ov.r)) / 128.0);
tcol.g = tcol.g < 128.0? (tcol.g * ov.g) / 128.0 : 255.0 - (((255.0 - tcol.g) * (255.0 - ov.g)) / 128.0);
tcol.r = tcol.r < 128.0? (tcol.r * ov.b) / 128.0 : 255.0 - (((255.0 - tcol.r) * (255.0 - ov.b)) / 128.0);
break;
case RF_HICTINT_BLEND_Hardlight:
tcol.b = tint.r < 128.0 ? (tcol.b * tint.r) / 128.0 : 255.0 - (((255.0 - tcol.b) * (255.0 - r)) / 128.0);
tcol.g = tint.g < 128.0 ? (tcol.g * tint.g) / 128.0 : 255.0 - (((255.0 - tcol.g) * (255.0 - g)) / 128.0);
tcol.r = tint.b < 128.0 ? (tcol.r * tint.b) / 128.0 : 255.0 - (((255.0 - tcol.r) * (255.0 - b)) / 128.0);
tcol.b = ov.r < 128.0 ? (tcol.b * ov.r) / 128.0 : 255.0 - (((255.0 - tcol.b) * (255.0 - ov.r)) / 128.0);
tcol.g = ov.g < 128.0 ? (tcol.g * ov.g) / 128.0 : 255.0 - (((255.0 - tcol.g) * (255.0 - ov.g)) / 128.0);
tcol.r = ov.b < 128.0 ? (tcol.r * ov.b) / 128.0 : 255.0 - (((255.0 - tcol.r) * (255.0 - ov.b)) / 128.0);
break;
}
color.rgb = tcol / 255.0;
#endif
return color;
}
@ -196,6 +204,7 @@ void main()
}
else
{
if (u_tintFlags != -1) color = convertColor(color);
color.rgb *= detailColor.rgb;
vec3 lightcolor = v_color.rgb;