Update blend textures to smooth out colors that have duplicate indices

This commit is contained in:
Sally Cochenour 2019-12-25 18:46:30 -05:00
parent 45404f7f27
commit 6476a92817

View file

@ -654,10 +654,14 @@ static void HWR_CreateBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch,
UINT16 w = gpatch->width, h = gpatch->height; UINT16 w = gpatch->width, h = gpatch->height;
UINT32 size = w*h; UINT32 size = w*h;
RGBA_t *image, *blendimage, *cur, blendcolor; RGBA_t *image, *blendimage, *cur, blendcolor;
UINT8 i;
UINT8 translation[16]; // First the color index
UINT8 cutoff[16]; // Brightness cutoff before using the next color
UINT8 translen = 0;
// vanilla port
UINT8 translation[16];
memset(translation, 0, sizeof(translation)); memset(translation, 0, sizeof(translation));
memset(cutoff, 0, sizeof(cutoff));
if (grmip->width == 0) if (grmip->width == 0)
{ {
@ -684,7 +688,33 @@ static void HWR_CreateBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch,
blendcolor = V_GetColor(0); // initialize blendcolor = V_GetColor(0); // initialize
if (color != SKINCOLOR_NONE) if (color != SKINCOLOR_NONE)
memcpy(&translation, &Color_Index[color - 1], 16); {
UINT8 numdupes = 1;
translation[translen] = Color_Index[color-1][0];
cutoff[translen] = 255;
for (i = 1; i < 16; i++)
{
if (translation[translen] == Color_Index[color-1][i])
{
numdupes++;
continue;
}
if (translen > 0)
{
cutoff[translen] = cutoff[translen-1] - (256 / (16 / numdupes));
}
numdupes = 1;
translen++;
translation[translen] = (UINT8)Color_Index[color-1][i];
}
translen++;
}
while (size--) while (size--)
{ {
@ -710,7 +740,7 @@ static void HWR_CreateBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch,
// Turn everything below a certain blue threshold white // Turn everything below a certain blue threshold white
if (image->s.red == 0 && image->s.green == 0 && image->s.blue <= 82) if (image->s.red == 0 && image->s.green == 0 && image->s.blue <= 82)
{ {
cur->s.red = cur->s.green = cur->s.blue = 255; cur->s.red = cur->s.green = cur->s.blue = (255 - image->s.blue);
} }
else else
{ {
@ -762,6 +792,8 @@ static void HWR_CreateBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch,
{ {
UINT16 brightness; UINT16 brightness;
I_Assert(translen > 0);
// Don't bother with blending the pixel if the alpha of the blend pixel is 0 // Don't bother with blending the pixel if the alpha of the blend pixel is 0
if (skinnum == TC_RAINBOW) if (skinnum == TC_RAINBOW)
{ {
@ -798,8 +830,8 @@ static void HWR_CreateBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch,
// (Me splitting this into a function didn't work, so I had to ruin this entire function's groove...) // (Me splitting this into a function didn't work, so I had to ruin this entire function's groove...)
{ {
RGBA_t nextcolor; RGBA_t nextcolor;
UINT8 firsti, secondi, mul; UINT8 firsti, secondi, mul, mulmax;
UINT32 r, g, b; INT32 r, g, b;
// Rainbow needs to find the closest match to the textures themselves, instead of matching brightnesses to other colors. // Rainbow needs to find the closest match to the textures themselves, instead of matching brightnesses to other colors.
// Ensue horrible mess. // Ensue horrible mess.
@ -808,7 +840,6 @@ static void HWR_CreateBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch,
UINT16 brightdif = 256; UINT16 brightdif = 256;
UINT8 colorbrightnesses[16]; UINT8 colorbrightnesses[16];
INT32 compare, m, d; INT32 compare, m, d;
UINT8 i;
// Ignore pure white & pitch black // Ignore pure white & pitch black
if (brightness > 253 || brightness < 2) if (brightness > 253 || brightness < 2)
@ -820,18 +851,21 @@ static void HWR_CreateBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch,
firsti = 0; firsti = 0;
mul = 0; mul = 0;
mulmax = 1;
for (i = 0; i < 16; i++) for (i = 0; i < translen; i++)
{ {
RGBA_t tempc = V_GetColor(translation[i]); RGBA_t tempc = V_GetColor(translation[i]);
SETBRIGHTNESS(colorbrightnesses[i], tempc.s.red, tempc.s.green, tempc.s.blue); // store brightnesses for comparison SETBRIGHTNESS(colorbrightnesses[i], tempc.s.red, tempc.s.green, tempc.s.blue); // store brightnesses for comparison
} }
for (i = 0; i < 16; i++) for (i = 0; i < translen; i++)
{ {
if (brightness > colorbrightnesses[i]) // don't allow greater matches (because calculating a makeshift gradient for this is already a huge mess as is) if (brightness > colorbrightnesses[i]) // don't allow greater matches (because calculating a makeshift gradient for this is already a huge mess as is)
continue; continue;
compare = abs((INT16)(colorbrightnesses[i]) - (INT16)(brightness)); compare = abs((INT16)(colorbrightnesses[i]) - (INT16)(brightness));
if (compare < brightdif) if (compare < brightdif)
{ {
brightdif = (UINT16)compare; brightdif = (UINT16)compare;
@ -840,7 +874,7 @@ static void HWR_CreateBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch,
} }
secondi = firsti+1; // next color in line secondi = firsti+1; // next color in line
if (secondi == 16) if (secondi >= translen)
{ {
m = (INT16)brightness; // - 0; m = (INT16)brightness; // - 0;
d = (INT16)colorbrightnesses[firsti]; // - 0; d = (INT16)colorbrightnesses[firsti]; // - 0;
@ -856,38 +890,57 @@ static void HWR_CreateBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch,
// calculate the "gradient" multiplier based on how close this color is to the one next in line // calculate the "gradient" multiplier based on how close this color is to the one next in line
if (m <= 0 || d <= 0) if (m <= 0 || d <= 0)
{
mul = 0; mul = 0;
}
else else
mul = 15 - ((m * 16) / d); {
mulmax = cutoff[firsti];
if (secondi < translen)
mulmax -= cutoff[secondi];
mul = (mulmax-1) - ((m * mulmax) / d);
}
} }
else else
{ {
// Thankfully, it's normally way more simple. // Just convert brightness to a skincolor value, use distance to next position to find the gradient multipler
// Just convert brightness to a skincolor value, use remainder to find the gradient multipler firsti = 0;
firsti = ((UINT8)(255-brightness) / 16);
for (i = 1; i < translen; i++)
{
if (brightness >= cutoff[i])
break;
firsti = i;
}
secondi = firsti+1; secondi = firsti+1;
mul = ((UINT8)(255-brightness) % 16);
mulmax = cutoff[firsti];
if (secondi < translen)
mulmax -= cutoff[secondi];
mul = cutoff[firsti] - brightness;
} }
blendcolor = V_GetColor(translation[firsti]); blendcolor = V_GetColor(translation[firsti]);
if (mul > 0 // If it's 0, then we only need the first color. if (mul > 0) // If it's 0, then we only need the first color.
&& translation[firsti] != translation[secondi]) // Some colors have duplicate colors in a row, so let's just save the process
{ {
if (secondi == 16) // blend to black if (secondi >= translen) // blend to black
nextcolor = V_GetColor(31); nextcolor = V_GetColor(31);
else else
nextcolor = V_GetColor(translation[secondi]); nextcolor = V_GetColor(translation[secondi]);
// Find difference between points // Find difference between points
r = (UINT32)(nextcolor.s.red - blendcolor.s.red); r = (INT32)(nextcolor.s.red - blendcolor.s.red);
g = (UINT32)(nextcolor.s.green - blendcolor.s.green); g = (INT32)(nextcolor.s.green - blendcolor.s.green);
b = (UINT32)(nextcolor.s.blue - blendcolor.s.blue); b = (INT32)(nextcolor.s.blue - blendcolor.s.blue);
// Find the gradient of the two points // Find the gradient of the two points
r = ((mul * r) / 16); r = ((mul * r) / mulmax);
g = ((mul * g) / 16); g = ((mul * g) / mulmax);
b = ((mul * b) / 16); b = ((mul * b) / mulmax);
// Add gradient value to color // Add gradient value to color
blendcolor.s.red += r; blendcolor.s.red += r;