mirror of
https://git.do.srb2.org/STJr/SRB2.git
synced 2025-02-19 10:30:54 +00:00
Merge branch 'ast_newstyles' into 'master'
Patch translucency styles See merge request STJr/SRB2Internal!324
This commit is contained in:
commit
1bafec9f55
3 changed files with 163 additions and 32 deletions
src
|
@ -61,7 +61,6 @@ static const INT32 format2bpp[16] =
|
||||||
2, //14 GR_TEXFMT_AP_88
|
2, //14 GR_TEXFMT_AP_88
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// This code was originally placed directly in HWR_DrawPatchInCache.
|
// This code was originally placed directly in HWR_DrawPatchInCache.
|
||||||
// It is now split from it for my sanity! (and the sanity of others)
|
// It is now split from it for my sanity! (and the sanity of others)
|
||||||
// -- Monster Iestyn (13/02/19)
|
// -- Monster Iestyn (13/02/19)
|
||||||
|
@ -139,18 +138,37 @@ static void HWR_DrawColumnInCache(const column_t *patchcol, UINT8 *block, GLMipm
|
||||||
// Alam: SRB2 uses Mingw, HUGS
|
// Alam: SRB2 uses Mingw, HUGS
|
||||||
switch (bpp)
|
switch (bpp)
|
||||||
{
|
{
|
||||||
case 2 : texelu16 = (UINT16)((alpha<<8) | texel);
|
case 2 : // uhhhhhhhh..........
|
||||||
|
if ((originPatch != NULL) && (originPatch->style != AST_COPY))
|
||||||
|
texel = ASTBlendPixel_8bpp(*(dest+1), texel, originPatch->style, originPatch->alpha);
|
||||||
|
texelu16 = (UINT16)((alpha<<8) | texel);
|
||||||
memcpy(dest, &texelu16, sizeof(UINT16));
|
memcpy(dest, &texelu16, sizeof(UINT16));
|
||||||
break;
|
break;
|
||||||
case 3 : colortemp = V_GetColor(texel);
|
case 3 : colortemp = V_GetColor(texel);
|
||||||
|
if ((originPatch != NULL) && (originPatch->style != AST_COPY))
|
||||||
|
{
|
||||||
|
RGBA_t rgbatexel;
|
||||||
|
rgbatexel.rgba = *(UINT32 *)dest;
|
||||||
|
colortemp = ASTBlendPixel(rgbatexel, colortemp, originPatch->style, originPatch->alpha);
|
||||||
|
}
|
||||||
memcpy(dest, &colortemp, sizeof(RGBA_t)-sizeof(UINT8));
|
memcpy(dest, &colortemp, sizeof(RGBA_t)-sizeof(UINT8));
|
||||||
break;
|
break;
|
||||||
case 4 : colortemp = V_GetColor(texel);
|
case 4 : colortemp = V_GetColor(texel);
|
||||||
colortemp.s.alpha = alpha;
|
colortemp.s.alpha = alpha;
|
||||||
|
if ((originPatch != NULL) && (originPatch->style != AST_COPY))
|
||||||
|
{
|
||||||
|
RGBA_t rgbatexel;
|
||||||
|
rgbatexel.rgba = *(UINT32 *)dest;
|
||||||
|
colortemp = ASTBlendPixel(rgbatexel, colortemp, originPatch->style, originPatch->alpha);
|
||||||
|
}
|
||||||
memcpy(dest, &colortemp, sizeof(RGBA_t));
|
memcpy(dest, &colortemp, sizeof(RGBA_t));
|
||||||
break;
|
break;
|
||||||
// default is 1
|
// default is 1
|
||||||
default: *dest = texel;
|
default:
|
||||||
|
if ((originPatch != NULL) && (originPatch->style != AST_COPY))
|
||||||
|
*dest = ASTBlendPixel_8bpp(*dest, texel, originPatch->style, originPatch->alpha);
|
||||||
|
else
|
||||||
|
*dest = texel;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -234,18 +252,37 @@ static void HWR_DrawFlippedColumnInCache(const column_t *patchcol, UINT8 *block,
|
||||||
// Alam: SRB2 uses Mingw, HUGS
|
// Alam: SRB2 uses Mingw, HUGS
|
||||||
switch (bpp)
|
switch (bpp)
|
||||||
{
|
{
|
||||||
case 2 : texelu16 = (UINT16)((alpha<<8) | texel);
|
case 2 : // uhhhhhhhh..........
|
||||||
|
if ((originPatch != NULL) && (originPatch->style != AST_COPY))
|
||||||
|
texel = ASTBlendPixel_8bpp(*(dest+1), texel, originPatch->style, originPatch->alpha);
|
||||||
|
texelu16 = (UINT16)((alpha<<8) | texel);
|
||||||
memcpy(dest, &texelu16, sizeof(UINT16));
|
memcpy(dest, &texelu16, sizeof(UINT16));
|
||||||
break;
|
break;
|
||||||
case 3 : colortemp = V_GetColor(texel);
|
case 3 : colortemp = V_GetColor(texel);
|
||||||
|
if ((originPatch != NULL) && (originPatch->style != AST_COPY))
|
||||||
|
{
|
||||||
|
RGBA_t rgbatexel;
|
||||||
|
rgbatexel.rgba = *(UINT32 *)dest;
|
||||||
|
colortemp = ASTBlendPixel(rgbatexel, colortemp, originPatch->style, originPatch->alpha);
|
||||||
|
}
|
||||||
memcpy(dest, &colortemp, sizeof(RGBA_t)-sizeof(UINT8));
|
memcpy(dest, &colortemp, sizeof(RGBA_t)-sizeof(UINT8));
|
||||||
break;
|
break;
|
||||||
case 4 : colortemp = V_GetColor(texel);
|
case 4 : colortemp = V_GetColor(texel);
|
||||||
colortemp.s.alpha = alpha;
|
colortemp.s.alpha = alpha;
|
||||||
|
if ((originPatch != NULL) && (originPatch->style != AST_COPY))
|
||||||
|
{
|
||||||
|
RGBA_t rgbatexel;
|
||||||
|
rgbatexel.rgba = *(UINT32 *)dest;
|
||||||
|
colortemp = ASTBlendPixel(rgbatexel, colortemp, originPatch->style, originPatch->alpha);
|
||||||
|
}
|
||||||
memcpy(dest, &colortemp, sizeof(RGBA_t));
|
memcpy(dest, &colortemp, sizeof(RGBA_t));
|
||||||
break;
|
break;
|
||||||
// default is 1
|
// default is 1
|
||||||
default: *dest = texel;
|
default:
|
||||||
|
if ((originPatch != NULL) && (originPatch->style != AST_COPY))
|
||||||
|
*dest = ASTBlendPixel_8bpp(*dest, texel, originPatch->style, originPatch->alpha);
|
||||||
|
else
|
||||||
|
*dest = texel;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -332,16 +369,7 @@ static void HWR_DrawTexturePatchInCache(GLMipmap_t *mipmap,
|
||||||
if (texture->width <= 0 || texture->height <= 0)
|
if (texture->width <= 0 || texture->height <= 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/*if ((patch->style == AST_TRANSLUCENT) && (patch->alpha <= (10*255/11))) // Alpha style set to translucent? Is the alpha small enough for translucency?
|
ColumnDrawerPointer = (patch->flip & 2) ? HWR_DrawFlippedColumnInCache : HWR_DrawColumnInCache;
|
||||||
{
|
|
||||||
if (patch->alpha < 255/11) // Is the patch way too translucent? Don't render then.
|
|
||||||
continue;
|
|
||||||
ColumnDrawerPointer = (patch->flip & 2) ? HWR_DrawTransFlippedColumnInCache : HWR_DrawTransColumnInCache;
|
|
||||||
}
|
|
||||||
else*/
|
|
||||||
{
|
|
||||||
ColumnDrawerPointer = (patch->flip & 2) ? HWR_DrawFlippedColumnInCache : HWR_DrawColumnInCache;
|
|
||||||
}
|
|
||||||
|
|
||||||
x1 = patch->originx;
|
x1 = patch->originx;
|
||||||
width = SHORT(realpatch->width);
|
width = SHORT(realpatch->width);
|
||||||
|
|
130
src/r_data.c
130
src/r_data.c
|
@ -241,15 +241,110 @@ static inline void R_DrawFlippedColumnInCache(column_t *patch, UINT8 *cache, tex
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RGBA_t ASTBlendPixel(RGBA_t background, RGBA_t foreground, int style, UINT8 alpha)
|
||||||
|
{
|
||||||
|
RGBA_t output;
|
||||||
|
if (style == AST_TRANSLUCENT)
|
||||||
|
{
|
||||||
|
if (alpha == 0)
|
||||||
|
output.rgba = background.rgba;
|
||||||
|
else if (alpha == 0xFF)
|
||||||
|
output.rgba = foreground.rgba;
|
||||||
|
else if (alpha < 0xFF)
|
||||||
|
{
|
||||||
|
UINT8 beta = (0xFF - alpha);
|
||||||
|
output.s.red = ((background.s.red * beta) + (foreground.s.red * alpha)) / 0xFF;
|
||||||
|
output.s.green = ((background.s.green * beta) + (foreground.s.green * alpha)) / 0xFF;
|
||||||
|
output.s.blue = ((background.s.blue * beta) + (foreground.s.blue * alpha)) / 0xFF;
|
||||||
|
}
|
||||||
|
// write foreground pixel alpha
|
||||||
|
// if there's no pixel in here
|
||||||
|
if (!background.rgba)
|
||||||
|
output.s.alpha = foreground.s.alpha;
|
||||||
|
}
|
||||||
|
#define clamp(c) max(min(c, 0xFF), 0x00);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
float falpha = ((float)alpha / 256.0f);
|
||||||
|
float fr = ((float)foreground.s.red * falpha);
|
||||||
|
float fg = ((float)foreground.s.green * falpha);
|
||||||
|
float fb = ((float)foreground.s.blue * falpha);
|
||||||
|
if (style == AST_ADD)
|
||||||
|
{
|
||||||
|
output.s.red = clamp((int)(background.s.red + fr));
|
||||||
|
output.s.green = clamp((int)(background.s.green + fg));
|
||||||
|
output.s.blue = clamp((int)(background.s.blue + fb));
|
||||||
|
}
|
||||||
|
else if (style == AST_SUBTRACT)
|
||||||
|
{
|
||||||
|
output.s.red = clamp((int)(background.s.red - fr));
|
||||||
|
output.s.green = clamp((int)(background.s.green - fg));
|
||||||
|
output.s.blue = clamp((int)(background.s.blue - fb));
|
||||||
|
}
|
||||||
|
else if (style == AST_REVERSESUBTRACT)
|
||||||
|
{
|
||||||
|
output.s.red = clamp((int)((-background.s.red) + fr));
|
||||||
|
output.s.green = clamp((int)((-background.s.green) + fg));
|
||||||
|
output.s.blue = clamp((int)((-background.s.blue) + fb));
|
||||||
|
}
|
||||||
|
else if (style == AST_MODULATE)
|
||||||
|
{
|
||||||
|
fr = ((float)foreground.s.red / 256.0f);
|
||||||
|
fg = ((float)foreground.s.green / 256.0f);
|
||||||
|
fb = ((float)foreground.s.blue / 256.0f);
|
||||||
|
output.s.red = clamp((int)(background.s.red * fr));
|
||||||
|
output.s.green = clamp((int)(background.s.green * fg));
|
||||||
|
output.s.blue = clamp((int)(background.s.blue * fb));
|
||||||
|
}
|
||||||
|
// just copy the pixel
|
||||||
|
else if (style == AST_COPY)
|
||||||
|
return background;
|
||||||
|
}
|
||||||
|
#undef clamp
|
||||||
|
// unimplemented blend modes return the background pixel
|
||||||
|
output = background;
|
||||||
|
output.s.alpha = 0xFF;
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
UINT8 ASTBlendPixel_8bpp(UINT8 background, UINT8 foreground, int style, UINT8 alpha)
|
||||||
|
{
|
||||||
|
if ((style == AST_TRANSLUCENT) && (alpha <= (10*255/11))) // Alpha style set to translucent? Is the alpha small enough for translucency?
|
||||||
|
{
|
||||||
|
UINT8 *mytransmap;
|
||||||
|
if (alpha < 255/11) // Is the patch way too translucent? Don't render then.
|
||||||
|
return background;
|
||||||
|
// The equation's not exact but it works as intended. I'll call it a day for now.
|
||||||
|
mytransmap = transtables + ((8*(alpha) + 255/8)/(255 - 255/11) << FF_TRANSSHIFT);
|
||||||
|
if (background != 0xFF)
|
||||||
|
return *(mytransmap + (background<<8) + foreground);
|
||||||
|
}
|
||||||
|
// just copy the pixel
|
||||||
|
else if (style == AST_COPY)
|
||||||
|
return background;
|
||||||
|
// use ASTBlendPixel for all other blend modes
|
||||||
|
// and find the nearest colour in the palette
|
||||||
|
else if (style != AST_TRANSLUCENT)
|
||||||
|
{
|
||||||
|
RGBA_t texel;
|
||||||
|
RGBA_t bg = V_GetColor(background);
|
||||||
|
RGBA_t fg = V_GetColor(foreground);
|
||||||
|
texel = ASTBlendPixel(bg, fg, style, alpha);
|
||||||
|
return NearestColor(texel.s.red, texel.s.green, texel.s.blue);
|
||||||
|
}
|
||||||
|
// fallback if all above fails, somehow
|
||||||
|
// return the background pixel
|
||||||
|
return background;
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// R_DrawTransColumnInCache
|
// R_DrawBlendColumnInCache
|
||||||
// Draws a translucent column into the cache, applying a half-cooked equation to get a proper translucency value (Needs code in R_GenerateTexture()).
|
// Draws a translucent column into the cache, applying a half-cooked equation to get a proper translucency value (Needs code in R_GenerateTexture()).
|
||||||
//
|
//
|
||||||
static inline void R_DrawTransColumnInCache(column_t *patch, UINT8 *cache, texpatch_t *originPatch, INT32 cacheheight, INT32 patchheight)
|
static inline void R_DrawBlendColumnInCache(column_t *patch, UINT8 *cache, texpatch_t *originPatch, INT32 cacheheight, INT32 patchheight)
|
||||||
{
|
{
|
||||||
INT32 count, position;
|
INT32 count, position;
|
||||||
UINT8 *source, *dest;
|
UINT8 *source, *dest;
|
||||||
UINT8 *mytransmap = transtables + ((8*(originPatch->alpha) + 255/8)/(255 - 255/11) << FF_TRANSSHIFT); // The equation's not exact but it works as intended. I'll call it a day for now.
|
|
||||||
INT32 topdelta, prevdelta = -1;
|
INT32 topdelta, prevdelta = -1;
|
||||||
INT32 originy = originPatch->originy;
|
INT32 originy = originPatch->originy;
|
||||||
|
|
||||||
|
@ -279,7 +374,8 @@ static inline void R_DrawTransColumnInCache(column_t *patch, UINT8 *cache, texpa
|
||||||
if (count > 0)
|
if (count > 0)
|
||||||
{
|
{
|
||||||
for (; dest < cache + position + count; source++, dest++)
|
for (; dest < cache + position + count; source++, dest++)
|
||||||
if (*dest != 0xFF) *dest = *(mytransmap + ((*dest)<<8) + (*source));
|
if (*dest != 0xFF)
|
||||||
|
*dest = ASTBlendPixel_8bpp(*dest, *source, originPatch->style, originPatch->alpha);
|
||||||
}
|
}
|
||||||
|
|
||||||
patch = (column_t *)((UINT8 *)patch + patch->length + 4);
|
patch = (column_t *)((UINT8 *)patch + patch->length + 4);
|
||||||
|
@ -290,11 +386,10 @@ static inline void R_DrawTransColumnInCache(column_t *patch, UINT8 *cache, texpa
|
||||||
// R_DrawTransColumnInCache
|
// R_DrawTransColumnInCache
|
||||||
// Similar to the one above except that the column is inverted.
|
// Similar to the one above except that the column is inverted.
|
||||||
//
|
//
|
||||||
static inline void R_DrawTransFlippedColumnInCache(column_t *patch, UINT8 *cache, texpatch_t *originPatch, INT32 cacheheight, INT32 patchheight)
|
static inline void R_DrawBlendFlippedColumnInCache(column_t *patch, UINT8 *cache, texpatch_t *originPatch, INT32 cacheheight, INT32 patchheight)
|
||||||
{
|
{
|
||||||
INT32 count, position;
|
INT32 count, position;
|
||||||
UINT8 *source, *dest;
|
UINT8 *source, *dest;
|
||||||
UINT8 *mytransmap = transtables + ((8*(originPatch->alpha) + 255/8)/(255 - 255/11) << FF_TRANSSHIFT); // The equation's not exact but it works as intended. I'll call it a day for now.
|
|
||||||
INT32 topdelta, prevdelta = -1;
|
INT32 topdelta, prevdelta = -1;
|
||||||
INT32 originy = originPatch->originy;
|
INT32 originy = originPatch->originy;
|
||||||
|
|
||||||
|
@ -323,7 +418,8 @@ static inline void R_DrawTransFlippedColumnInCache(column_t *patch, UINT8 *cache
|
||||||
if (count > 0)
|
if (count > 0)
|
||||||
{
|
{
|
||||||
for (; dest < cache + position + count; --source, dest++)
|
for (; dest < cache + position + count; --source, dest++)
|
||||||
if (*dest != 0xFF) *dest = *(mytransmap + ((*dest)<<8) + (*source));
|
if (*dest != 0xFF)
|
||||||
|
*dest = ASTBlendPixel_8bpp(*dest, *source, originPatch->style, originPatch->alpha);
|
||||||
}
|
}
|
||||||
|
|
||||||
patch = (column_t *)((UINT8 *)patch + patch->length + 4);
|
patch = (column_t *)((UINT8 *)patch + patch->length + 4);
|
||||||
|
@ -462,16 +558,10 @@ static UINT8 *R_GenerateTexture(size_t texnum)
|
||||||
for (i = 0, patch = texture->patches; i < texture->patchcount; i++, patch++)
|
for (i = 0, patch = texture->patches; i < texture->patchcount; i++, patch++)
|
||||||
{
|
{
|
||||||
static void (*ColumnDrawerPointer)(column_t *, UINT8 *, texpatch_t *, INT32, INT32); // Column drawing function pointer.
|
static void (*ColumnDrawerPointer)(column_t *, UINT8 *, texpatch_t *, INT32, INT32); // Column drawing function pointer.
|
||||||
if ((patch->style == AST_TRANSLUCENT) && (patch->alpha <= (10*255/11))) // Alpha style set to translucent? Is the alpha small enough for translucency?
|
if (patch->style != AST_COPY)
|
||||||
{
|
ColumnDrawerPointer = (patch->flip & 2) ? R_DrawBlendFlippedColumnInCache : R_DrawBlendColumnInCache;
|
||||||
if (patch->alpha < 255/11) // Is the patch way too translucent? Don't render then.
|
|
||||||
continue;
|
|
||||||
ColumnDrawerPointer = (patch->flip & 2) ? R_DrawTransFlippedColumnInCache : R_DrawTransColumnInCache;
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
|
||||||
ColumnDrawerPointer = (patch->flip & 2) ? R_DrawFlippedColumnInCache : R_DrawColumnInCache;
|
ColumnDrawerPointer = (patch->flip & 2) ? R_DrawFlippedColumnInCache : R_DrawColumnInCache;
|
||||||
}
|
|
||||||
|
|
||||||
wadnum = patch->wad;
|
wadnum = patch->wad;
|
||||||
lumpnum = patch->lump;
|
lumpnum = patch->lump;
|
||||||
|
@ -917,8 +1007,16 @@ static texpatch_t *R_ParsePatch(boolean actuallyLoadPatch)
|
||||||
{
|
{
|
||||||
Z_Free(texturesToken);
|
Z_Free(texturesToken);
|
||||||
texturesToken = M_GetToken(NULL);
|
texturesToken = M_GetToken(NULL);
|
||||||
if(stricmp(texturesToken, "TRANSLUCENT")==0)
|
if (stricmp(texturesToken, "TRANSLUCENT")==0)
|
||||||
style = AST_TRANSLUCENT;
|
style = AST_TRANSLUCENT;
|
||||||
|
else if (stricmp(texturesToken, "ADD")==0)
|
||||||
|
style = AST_ADD;
|
||||||
|
else if (stricmp(texturesToken, "SUBTRACT")==0)
|
||||||
|
style = AST_SUBTRACT;
|
||||||
|
else if (stricmp(texturesToken, "REVERSESUBTRACT")==0)
|
||||||
|
style = AST_REVERSESUBTRACT;
|
||||||
|
else if (stricmp(texturesToken, "MODULATE")==0)
|
||||||
|
style = AST_MODULATE;
|
||||||
}
|
}
|
||||||
else if (stricmp(texturesToken, "FLIPX")==0)
|
else if (stricmp(texturesToken, "FLIPX")==0)
|
||||||
flip |= 1;
|
flip |= 1;
|
||||||
|
|
|
@ -23,7 +23,12 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Possible alpha types for a patch.
|
// Possible alpha types for a patch.
|
||||||
enum patchalphastyle {AST_COPY, AST_TRANSLUCENT}; // , AST_ADD, AST_SUBTRACT, AST_REVERSESUBTRACT, AST_MODULATE, AST_OVERLAY};
|
enum patchalphastyle {AST_COPY, AST_TRANSLUCENT, AST_ADD, AST_SUBTRACT, AST_REVERSESUBTRACT, AST_MODULATE, AST_OVERLAY};
|
||||||
|
|
||||||
|
RGBA_t ASTBlendPixel(RGBA_t background, RGBA_t foreground, int style, UINT8 alpha);
|
||||||
|
UINT8 ASTBlendPixel_8bpp(UINT8 background, UINT8 foreground, int style, UINT8 alpha);
|
||||||
|
|
||||||
|
UINT8 NearestColor(UINT8 r, UINT8 g, UINT8 b);
|
||||||
|
|
||||||
// moved here for r_sky.c (texpatch_t is used)
|
// moved here for r_sky.c (texpatch_t is used)
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue