Attempt to properly match Software texture blending

without messing with the original ASTBlendPixel function
This commit is contained in:
Jaime Passos 2020-05-16 13:51:10 -03:00
parent 288d7166bc
commit c64e231b2b
3 changed files with 47 additions and 14 deletions

View file

@ -135,7 +135,7 @@ static void HWR_DrawColumnInCache(const column_t *patchcol, UINT8 *block, GLMipm
{ {
case 2 : // uhhhhhhhh.......... case 2 : // uhhhhhhhh..........
if ((originPatch != NULL) && (originPatch->style != AST_COPY)) if ((originPatch != NULL) && (originPatch->style != AST_COPY))
texel = ASTBlendPixel_8bpp(*(dest+1), texel, originPatch->style, originPatch->alpha); texel = ASTBlendPaletteIndexes(*(dest+1), texel, originPatch->style, originPatch->alpha);
texelu16 = (UINT16)((alpha<<8) | texel); texelu16 = (UINT16)((alpha<<8) | texel);
memcpy(dest, &texelu16, sizeof(UINT16)); memcpy(dest, &texelu16, sizeof(UINT16));
break; break;
@ -144,7 +144,7 @@ static void HWR_DrawColumnInCache(const column_t *patchcol, UINT8 *block, GLMipm
{ {
RGBA_t rgbatexel; RGBA_t rgbatexel;
rgbatexel.rgba = *(UINT32 *)dest; rgbatexel.rgba = *(UINT32 *)dest;
colortemp.rgba = ASTBlendPixel(rgbatexel, colortemp, originPatch->style, originPatch->alpha); colortemp.rgba = ASTBlendTexturePixel(rgbatexel, colortemp, originPatch->style, originPatch->alpha);
} }
memcpy(dest, &colortemp, sizeof(RGBA_t)-sizeof(UINT8)); memcpy(dest, &colortemp, sizeof(RGBA_t)-sizeof(UINT8));
break; break;
@ -154,14 +154,14 @@ static void HWR_DrawColumnInCache(const column_t *patchcol, UINT8 *block, GLMipm
{ {
RGBA_t rgbatexel; RGBA_t rgbatexel;
rgbatexel.rgba = *(UINT32 *)dest; rgbatexel.rgba = *(UINT32 *)dest;
colortemp.rgba = ASTBlendPixel(rgbatexel, colortemp, originPatch->style, originPatch->alpha); colortemp.rgba = ASTBlendTexturePixel(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: default:
if ((originPatch != NULL) && (originPatch->style != AST_COPY)) if ((originPatch != NULL) && (originPatch->style != AST_COPY))
*dest = ASTBlendPixel_8bpp(*dest, texel, originPatch->style, originPatch->alpha); *dest = ASTBlendPaletteIndexes(*dest, texel, originPatch->style, originPatch->alpha);
else else
*dest = texel; *dest = texel;
break; break;
@ -247,7 +247,7 @@ static void HWR_DrawFlippedColumnInCache(const column_t *patchcol, UINT8 *block,
{ {
case 2 : // uhhhhhhhh.......... case 2 : // uhhhhhhhh..........
if ((originPatch != NULL) && (originPatch->style != AST_COPY)) if ((originPatch != NULL) && (originPatch->style != AST_COPY))
texel = ASTBlendPixel_8bpp(*(dest+1), texel, originPatch->style, originPatch->alpha); texel = ASTBlendPaletteIndexes(*(dest+1), texel, originPatch->style, originPatch->alpha);
texelu16 = (UINT16)((alpha<<8) | texel); texelu16 = (UINT16)((alpha<<8) | texel);
memcpy(dest, &texelu16, sizeof(UINT16)); memcpy(dest, &texelu16, sizeof(UINT16));
break; break;
@ -256,7 +256,7 @@ static void HWR_DrawFlippedColumnInCache(const column_t *patchcol, UINT8 *block,
{ {
RGBA_t rgbatexel; RGBA_t rgbatexel;
rgbatexel.rgba = *(UINT32 *)dest; rgbatexel.rgba = *(UINT32 *)dest;
colortemp.rgba = ASTBlendPixel(rgbatexel, colortemp, originPatch->style, originPatch->alpha); colortemp.rgba = ASTBlendTexturePixel(rgbatexel, colortemp, originPatch->style, originPatch->alpha);
} }
memcpy(dest, &colortemp, sizeof(RGBA_t)-sizeof(UINT8)); memcpy(dest, &colortemp, sizeof(RGBA_t)-sizeof(UINT8));
break; break;
@ -266,14 +266,14 @@ static void HWR_DrawFlippedColumnInCache(const column_t *patchcol, UINT8 *block,
{ {
RGBA_t rgbatexel; RGBA_t rgbatexel;
rgbatexel.rgba = *(UINT32 *)dest; rgbatexel.rgba = *(UINT32 *)dest;
colortemp.rgba = ASTBlendPixel(rgbatexel, colortemp, originPatch->style, originPatch->alpha); colortemp.rgba = ASTBlendTexturePixel(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: default:
if ((originPatch != NULL) && (originPatch->style != AST_COPY)) if ((originPatch != NULL) && (originPatch->style != AST_COPY))
*dest = ASTBlendPixel_8bpp(*dest, texel, originPatch->style, originPatch->alpha); *dest = ASTBlendPaletteIndexes(*dest, texel, originPatch->style, originPatch->alpha);
else else
*dest = texel; *dest = texel;
break; break;

View file

@ -227,6 +227,8 @@ static inline void R_DrawFlippedColumnInCache(column_t *patch, UINT8 *cache, tex
} }
} }
// Blends two pixels together, using the equation
// that matches the specified alpha style.
UINT32 ASTBlendPixel(RGBA_t background, RGBA_t foreground, int style, UINT8 alpha) UINT32 ASTBlendPixel(RGBA_t background, RGBA_t foreground, int style, UINT8 alpha)
{ {
RGBA_t output; RGBA_t output;
@ -307,18 +309,46 @@ UINT32 ASTBlendPixel(RGBA_t background, RGBA_t foreground, int style, UINT8 alph
return 0; return 0;
} }
UINT8 ASTBlendPixel_8bpp(UINT8 background, UINT8 foreground, int style, UINT8 alpha) INT32 ASTTextureBlendingThreshold[2] = {255/11, (10*255/11)};
// Blends a pixel for a texture patch.
UINT32 ASTBlendTexturePixel(RGBA_t background, RGBA_t foreground, int style, UINT8 alpha)
{ {
// Alpha style set to translucent? // Alpha style set to translucent?
if (style == AST_TRANSLUCENT) if (style == AST_TRANSLUCENT)
{ {
// Is the alpha small enough for translucency? // Is the alpha small enough for translucency?
if (alpha <= (10*255/11)) if (alpha <= ASTTextureBlendingThreshold[1])
{
// Is the patch way too translucent? Don't blend then.
if (alpha < ASTTextureBlendingThreshold[0])
return background;
return foreground;
}
else // just copy the pixel
return foreground;
}
else
return ASTBlendPixel(background, foreground, style, alpha);
}
// Blends two palette indexes for a texture patch, then
// finds the nearest palette index from the blended output.
UINT8 ASTBlendPaletteIndexes(UINT8 background, UINT8 foreground, int style, UINT8 alpha)
{
// Alpha style set to translucent?
if (style == AST_TRANSLUCENT)
{
// Is the alpha small enough for translucency?
if (alpha <= ASTTextureBlendingThreshold[1])
{ {
UINT8 *mytransmap; UINT8 *mytransmap;
// Is the patch way too translucent? Don't blend then. // Is the patch way too translucent? Don't blend then.
if (alpha < 255/11) if (alpha < ASTTextureBlendingThreshold[0])
return background; return background;
// The equation's not exact but it works as intended. I'll call it a day for now. // 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); mytransmap = transtables + ((8*(alpha) + 255/8)/(255 - 255/11) << FF_TRANSSHIFT);
if (background != 0xFF) if (background != 0xFF)
@ -383,7 +413,7 @@ static inline void R_DrawBlendColumnInCache(column_t *patch, UINT8 *cache, texpa
{ {
for (; dest < cache + position + count; source++, dest++) for (; dest < cache + position + count; source++, dest++)
if (*source != 0xFF) if (*source != 0xFF)
*dest = ASTBlendPixel_8bpp(*dest, *source, originPatch->style, originPatch->alpha); *dest = ASTBlendPaletteIndexes(*dest, *source, originPatch->style, originPatch->alpha);
} }
patch = (column_t *)((UINT8 *)patch + patch->length + 4); patch = (column_t *)((UINT8 *)patch + patch->length + 4);
@ -427,7 +457,7 @@ static inline void R_DrawBlendFlippedColumnInCache(column_t *patch, UINT8 *cache
{ {
for (; dest < cache + position + count; --source, dest++) for (; dest < cache + position + count; --source, dest++)
if (*source != 0xFF) if (*source != 0xFF)
*dest = ASTBlendPixel_8bpp(*dest, *source, originPatch->style, originPatch->alpha); *dest = ASTBlendPaletteIndexes(*dest, *source, originPatch->style, originPatch->alpha);
} }
patch = (column_t *)((UINT8 *)patch + patch->length + 4); patch = (column_t *)((UINT8 *)patch + patch->length + 4);

View file

@ -26,7 +26,10 @@
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};
UINT32 ASTBlendPixel(RGBA_t background, RGBA_t foreground, int style, UINT8 alpha); UINT32 ASTBlendPixel(RGBA_t background, RGBA_t foreground, int style, UINT8 alpha);
UINT8 ASTBlendPixel_8bpp(UINT8 background, UINT8 foreground, int style, UINT8 alpha); UINT32 ASTBlendTexturePixel(RGBA_t background, RGBA_t foreground, int style, UINT8 alpha);
UINT8 ASTBlendPaletteIndexes(UINT8 background, UINT8 foreground, int style, UINT8 alpha);
extern INT32 ASTTextureBlendingThreshold[2];
UINT8 NearestColor(UINT8 r, UINT8 g, UINT8 b); UINT8 NearestColor(UINT8 r, UINT8 g, UINT8 b);