mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2026-04-27 20:41:46 +00:00
Gradient skincolors for MD2 blend textures
This commit is contained in:
parent
33492573f4
commit
dca1a05a7f
2 changed files with 93 additions and 76 deletions
|
|
@ -653,13 +653,12 @@ spritemd2found:
|
||||||
// 0.2126 to red
|
// 0.2126 to red
|
||||||
// 0.7152 to green
|
// 0.7152 to green
|
||||||
// 0.0722 to blue
|
// 0.0722 to blue
|
||||||
// (See this same define in k_kart.c!)
|
// (See this same define in hw_md2.c!)
|
||||||
#define SETBRIGHTNESS(brightness,r,g,b) \
|
#define SETBRIGHTNESS(brightness,r,g,b) \
|
||||||
brightness = (UINT8)(((1063*((UINT16)r)/5000) + (3576*((UINT16)g)/5000) + (361*((UINT16)b)/5000)) / 3)
|
brightness = (UINT8)(((1063*(UINT16)(r))/5000) + ((3576*(UINT16)(g))/5000) + ((361*(UINT16)(b))/5000))
|
||||||
|
|
||||||
static void HWR_CreateBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch, GLMipmap_t *grmip, INT32 skinnum, skincolors_t color)
|
static void HWR_CreateBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch, GLMipmap_t *grmip, INT32 skinnum, skincolors_t color)
|
||||||
{
|
{
|
||||||
UINT8 i;
|
|
||||||
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;
|
||||||
|
|
@ -684,102 +683,120 @@ static void HWR_CreateBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch,
|
||||||
|
|
||||||
image = gpatch->mipmap.grInfo.data;
|
image = gpatch->mipmap.grInfo.data;
|
||||||
blendimage = blendgpatch->mipmap.grInfo.data;
|
blendimage = blendgpatch->mipmap.grInfo.data;
|
||||||
|
blendcolor = V_GetColor(0); // initialize
|
||||||
|
|
||||||
// Average all of the translation's colors
|
while (size--)
|
||||||
{
|
{
|
||||||
const UINT8 div = 6;
|
UINT16 brightness;
|
||||||
const UINT8 start = 4;
|
|
||||||
UINT32 r, g, b;
|
|
||||||
|
|
||||||
blendcolor = V_GetColor(colortranslations[color][start]);
|
// Don't bother with blending the pixel if the alpha of the blend pixel is 0
|
||||||
r = (UINT32)(blendcolor.s.red*blendcolor.s.red);
|
if (skinnum == TC_RAINBOW)
|
||||||
g = (UINT32)(blendcolor.s.green*blendcolor.s.green);
|
|
||||||
b = (UINT32)(blendcolor.s.blue*blendcolor.s.blue);
|
|
||||||
|
|
||||||
for (i = 1; i < div; i++)
|
|
||||||
{
|
|
||||||
RGBA_t nextcolor = V_GetColor(colortranslations[color][start+i]);
|
|
||||||
r += (UINT32)(nextcolor.s.red*nextcolor.s.red);
|
|
||||||
g += (UINT32)(nextcolor.s.green*nextcolor.s.green);
|
|
||||||
b += (UINT32)(nextcolor.s.blue*nextcolor.s.blue);
|
|
||||||
}
|
|
||||||
|
|
||||||
blendcolor.s.red = (UINT8)(FixedSqrt((r/div)<<FRACBITS)>>FRACBITS);
|
|
||||||
blendcolor.s.green = (UINT8)(FixedSqrt((g/div)<<FRACBITS)>>FRACBITS);
|
|
||||||
blendcolor.s.blue = (UINT8)(FixedSqrt((b/div)<<FRACBITS)>>FRACBITS);
|
|
||||||
}
|
|
||||||
|
|
||||||
// rainbow support, could theoretically support boss ones too
|
|
||||||
if (skinnum == TC_RAINBOW)
|
|
||||||
{
|
|
||||||
while (size--)
|
|
||||||
{
|
{
|
||||||
if (image->s.alpha == 0 && blendimage->s.alpha == 0)
|
if (image->s.alpha == 0 && blendimage->s.alpha == 0)
|
||||||
{
|
{
|
||||||
// Don't bother with blending the pixel if the alpha of the blend pixel is 0
|
|
||||||
cur->rgba = image->rgba;
|
cur->rgba = image->rgba;
|
||||||
|
cur++; image++; blendimage++;
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
UINT32 tempcolor;
|
UINT16 imagebright, blendbright;
|
||||||
UINT16 imagebright, blendbright, finalbright, colorbright;
|
|
||||||
SETBRIGHTNESS(imagebright,image->s.red,image->s.green,image->s.blue);
|
SETBRIGHTNESS(imagebright,image->s.red,image->s.green,image->s.blue);
|
||||||
SETBRIGHTNESS(blendbright,blendimage->s.red,blendimage->s.green,blendimage->s.blue);
|
SETBRIGHTNESS(blendbright,blendimage->s.red,blendimage->s.green,blendimage->s.blue);
|
||||||
// slightly dumb average between the blend image color and base image colour, usually one or the other will be fully opaque anyway
|
// slightly dumb average between the blend image color and base image colour, usually one or the other will be fully opaque anyway
|
||||||
finalbright = (imagebright*(255-blendimage->s.alpha))/255 + (blendbright*blendimage->s.alpha)/255;
|
brightness = (imagebright*(255-blendimage->s.alpha))/255 + (blendbright*blendimage->s.alpha)/255;
|
||||||
SETBRIGHTNESS(colorbright,blendcolor.s.red,blendcolor.s.green,blendcolor.s.blue);
|
|
||||||
|
|
||||||
tempcolor = (finalbright*blendcolor.s.red)/colorbright;
|
|
||||||
tempcolor = min(255, tempcolor);
|
|
||||||
cur->s.red = (UINT8)tempcolor;
|
|
||||||
tempcolor = (finalbright*blendcolor.s.green)/colorbright;
|
|
||||||
tempcolor = min(255, tempcolor);
|
|
||||||
cur->s.green = (UINT8)tempcolor;
|
|
||||||
tempcolor = (finalbright*blendcolor.s.blue)/colorbright;
|
|
||||||
tempcolor = min(255, tempcolor);
|
|
||||||
cur->s.blue = (UINT8)tempcolor;
|
|
||||||
cur->s.alpha = image->s.alpha;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cur++; image++; blendimage++;
|
|
||||||
}
|
}
|
||||||
}
|
else
|
||||||
else
|
|
||||||
{
|
|
||||||
while (size--)
|
|
||||||
{
|
{
|
||||||
if (blendimage->s.alpha == 0)
|
if (blendimage->s.alpha == 0)
|
||||||
{
|
{
|
||||||
// Don't bother with blending the pixel if the alpha of the blend pixel is 0
|
|
||||||
cur->rgba = image->rgba;
|
cur->rgba = image->rgba;
|
||||||
|
cur++; image++; blendimage++;
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
INT32 tempcolor;
|
SETBRIGHTNESS(brightness,blendimage->s.red,blendimage->s.green,blendimage->s.blue);
|
||||||
INT16 tempmult, tempalpha;
|
|
||||||
tempalpha = -(abs(blendimage->s.red-127)-127)*2;
|
|
||||||
if (tempalpha > 255)
|
|
||||||
tempalpha = 255;
|
|
||||||
else if (tempalpha < 0)
|
|
||||||
tempalpha = 0;
|
|
||||||
|
|
||||||
tempmult = (blendimage->s.red-127)*2;
|
|
||||||
if (tempmult > 255)
|
|
||||||
tempmult = 255;
|
|
||||||
else if (tempmult < 0)
|
|
||||||
tempmult = 0;
|
|
||||||
|
|
||||||
tempcolor = (image->s.red*(255-blendimage->s.alpha))/255 + ((tempmult + ((tempalpha*blendcolor.s.red)/255)) * blendimage->s.alpha)/255;
|
|
||||||
cur->s.red = (UINT8)tempcolor;
|
|
||||||
tempcolor = (image->s.green*(255-blendimage->s.alpha))/255 + ((tempmult + ((tempalpha*blendcolor.s.green)/255)) * blendimage->s.alpha)/255;
|
|
||||||
cur->s.green = (UINT8)tempcolor;
|
|
||||||
tempcolor = (image->s.blue*(255-blendimage->s.alpha))/255 + ((tempmult + ((tempalpha*blendcolor.s.blue)/255)) * blendimage->s.alpha)/255;
|
|
||||||
cur->s.blue = (UINT8)tempcolor;
|
|
||||||
cur->s.alpha = image->s.alpha;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cur++; image++; blendimage++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Calculate a sort of "gradient" for the skincolor
|
||||||
|
// (Me splitting this into a function didn't work, so I had to ruin this entire function's groove...)
|
||||||
|
{
|
||||||
|
RGBA_t nextcolor;
|
||||||
|
UINT8 firsti, secondi, mul;
|
||||||
|
UINT32 r, g, b;
|
||||||
|
|
||||||
|
firsti = ((UINT8)(255-brightness) / 16);
|
||||||
|
mul = ((UINT8)(255-brightness) % 16);
|
||||||
|
|
||||||
|
blendcolor = V_GetColor(colortranslations[color][firsti]);
|
||||||
|
|
||||||
|
if (mul > 0) // If it's 0, then we only need the first color.
|
||||||
|
{
|
||||||
|
secondi = firsti+1;
|
||||||
|
|
||||||
|
if (secondi == 16) // blend to black
|
||||||
|
nextcolor = V_GetColor(31);
|
||||||
|
else
|
||||||
|
nextcolor = V_GetColor(colortranslations[color][secondi]);
|
||||||
|
|
||||||
|
// Find difference between points
|
||||||
|
r = (UINT32)(nextcolor.s.red - blendcolor.s.red);
|
||||||
|
g = (UINT32)(nextcolor.s.green - blendcolor.s.green);
|
||||||
|
b = (UINT32)(nextcolor.s.blue - blendcolor.s.blue);
|
||||||
|
|
||||||
|
// Find the gradient of the two points
|
||||||
|
r = ((mul * r) / 16);
|
||||||
|
g = ((mul * g) / 16);
|
||||||
|
b = ((mul * b) / 16);
|
||||||
|
|
||||||
|
// Add gradient value to color
|
||||||
|
blendcolor.s.red += r;
|
||||||
|
blendcolor.s.green += g;
|
||||||
|
blendcolor.s.blue += b;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (skinnum == TC_RAINBOW)
|
||||||
|
{
|
||||||
|
// Directly set blendcolor
|
||||||
|
cur->s.red = blendcolor.s.red;
|
||||||
|
cur->s.green = blendcolor.s.green;
|
||||||
|
cur->s.blue = blendcolor.s.blue;
|
||||||
|
cur->s.alpha = image->s.alpha;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Color strength depends on image alpha
|
||||||
|
INT32 tempcolor;
|
||||||
|
INT16 tempmult, tempalpha;
|
||||||
|
|
||||||
|
tempalpha = -(abs(blendimage->s.red-127)-127)*2;
|
||||||
|
if (tempalpha > 255)
|
||||||
|
tempalpha = 255;
|
||||||
|
else if (tempalpha < 0)
|
||||||
|
tempalpha = 0;
|
||||||
|
|
||||||
|
tempmult = (blendimage->s.red-127)*2;
|
||||||
|
if (tempmult > 255)
|
||||||
|
tempmult = 255;
|
||||||
|
else if (tempmult < 0)
|
||||||
|
tempmult = 0;
|
||||||
|
|
||||||
|
tempcolor = (image->s.red*(255-blendimage->s.alpha))/255 + ((tempmult + ((tempalpha*blendcolor.s.red)/255)) * blendimage->s.alpha)/255;
|
||||||
|
cur->s.red = (UINT8)tempcolor;
|
||||||
|
|
||||||
|
tempcolor = (image->s.green*(255-blendimage->s.alpha))/255 + ((tempmult + ((tempalpha*blendcolor.s.green)/255)) * blendimage->s.alpha)/255;
|
||||||
|
cur->s.green = (UINT8)tempcolor;
|
||||||
|
|
||||||
|
tempcolor = (image->s.blue*(255-blendimage->s.alpha))/255 + ((tempmult + ((tempalpha*blendcolor.s.blue)/255)) * blendimage->s.alpha)/255;
|
||||||
|
cur->s.blue = (UINT8)tempcolor;
|
||||||
|
cur->s.alpha = image->s.alpha;
|
||||||
|
}
|
||||||
|
|
||||||
|
cur++; image++; blendimage++;
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
|
|
||||||
|
|
@ -410,7 +410,7 @@ UINT8 colortranslations[MAXTRANSLATIONS][16] = {
|
||||||
// 0.0722 to blue
|
// 0.0722 to blue
|
||||||
// (See this same define in hw_md2.c!)
|
// (See this same define in hw_md2.c!)
|
||||||
#define SETBRIGHTNESS(brightness,r,g,b) \
|
#define SETBRIGHTNESS(brightness,r,g,b) \
|
||||||
brightness = (UINT8)(((1063*((UINT16)r)/5000) + (3576*((UINT16)g)/5000) + (361*((UINT16)b)/5000)) / 3)
|
brightness = (UINT8)(((1063*(UINT16)(r))/5000) + ((3576*(UINT16)(g))/5000) + ((361*(UINT16)(b))/5000))
|
||||||
|
|
||||||
/** \brief Generates the rainbow colourmaps that are used when a player has the invincibility power
|
/** \brief Generates the rainbow colourmaps that are used when a player has the invincibility power
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue