0
0
Fork 0
mirror of https://github.com/ZDoom/gzdoom.git synced 2025-03-02 15:42:17 +00:00

Added most of the blend modes

This commit is contained in:
Magnus Norddahl 2017-02-22 00:27:06 +01:00
parent c918950ff6
commit 38453d0435
2 changed files with 999 additions and 702 deletions
src/polyrenderer/drawers

File diff suppressed because it is too large Load diff

View file

@ -78,21 +78,21 @@ std::vector<void(*)(const TriDrawTriangleArgs *, WorkerThreadData *)> ScreenTria
{ {
<? } <? }
OutputDrawer($namePrefix."Copy", "opaque", $isTruecolor, $isColorFill, $isListEntry); OutputDrawer($namePrefix."Copy", "opaque", false, $isTruecolor, $isColorFill, $isListEntry);
OutputDrawer($namePrefix."AlphaBlend", "masked", $isTruecolor, $isColorFill, $isListEntry); OutputDrawer($namePrefix."AlphaBlend", "masked", false, $isTruecolor, $isColorFill, $isListEntry);
OutputDrawer($namePrefix."AddSolid", "translucent", $isTruecolor, $isColorFill, $isListEntry); OutputDrawer($namePrefix."AddSolid", "translucent", false, $isTruecolor, $isColorFill, $isListEntry);
OutputDrawer($namePrefix."Add", "add", $isTruecolor, $isColorFill, $isListEntry); OutputDrawer($namePrefix."Add", "add", false, $isTruecolor, $isColorFill, $isListEntry);
OutputDrawer($namePrefix."Sub", "sub", $isTruecolor, $isColorFill, $isListEntry); OutputDrawer($namePrefix."Sub", "sub", false, $isTruecolor, $isColorFill, $isListEntry);
OutputDrawer($namePrefix."RevSub", "revsub", $isTruecolor, $isColorFill, $isListEntry); OutputDrawer($namePrefix."RevSub", "revsub", false, $isTruecolor, $isColorFill, $isListEntry);
OutputDrawer($namePrefix."Stencil", "stencil", $isTruecolor, $isColorFill, $isListEntry); OutputDrawer($namePrefix."Stencil", "stencil", false, $isTruecolor, $isColorFill, $isListEntry);
OutputDrawer($namePrefix."Shaded", "shaded", $isTruecolor, $isColorFill, $isListEntry); OutputDrawer($namePrefix."Shaded", "shaded", false, $isTruecolor, $isColorFill, $isListEntry);
OutputDrawer($namePrefix."TranslateCopy", "translate", $isTruecolor, $isColorFill, $isListEntry); OutputDrawer($namePrefix."TranslateCopy", "opaque", true, $isTruecolor, $isColorFill, $isListEntry);
OutputDrawer($namePrefix."TranslateAlphaBlend", "translatemasked", $isTruecolor, $isColorFill, $isListEntry); OutputDrawer($namePrefix."TranslateAlphaBlend", "masked", true, $isTruecolor, $isColorFill, $isListEntry);
OutputDrawer($namePrefix."TranslateAdd", "translateadd", $isTruecolor, $isColorFill, $isListEntry); OutputDrawer($namePrefix."TranslateAdd", "add", true, $isTruecolor, $isColorFill, $isListEntry);
OutputDrawer($namePrefix."TranslateSub", "translatesub", $isTruecolor, $isColorFill, $isListEntry); OutputDrawer($namePrefix."TranslateSub", "sub", true, $isTruecolor, $isColorFill, $isListEntry);
OutputDrawer($namePrefix."TranslateRevSub", "translaterevsub", $isTruecolor, $isColorFill, $isListEntry); OutputDrawer($namePrefix."TranslateRevSub", "revsub", true, $isTruecolor, $isColorFill, $isListEntry);
OutputDrawer($namePrefix."AddSrcColorOneMinusSrcColor", "addsrccolor", $isTruecolor, $isColorFill, $isListEntry); OutputDrawer($namePrefix."AddSrcColorOneMinusSrcColor", "addsrccolor", false, $isTruecolor, $isColorFill, $isListEntry);
OutputDrawer($namePrefix."Skycap", "skycap", $isTruecolor, $isColorFill, $isListEntry); OutputDrawer($namePrefix."Skycap", "skycap", false, $isTruecolor, $isColorFill, $isListEntry);
if ($isListEntry) if ($isListEntry)
{ ?> { ?>
@ -101,7 +101,7 @@ std::vector<void(*)(const TriDrawTriangleArgs *, WorkerThreadData *)> ScreenTria
<? } <? }
} }
function OutputDrawer($drawerName, $blendmode, $isTruecolor, $isColorFill, $isListEntry) function OutputDrawer($drawerName, $blendmode, $isTranslated, $isTruecolor, $isColorFill, $isListEntry)
{ {
if ($isListEntry) if ($isListEntry)
{ ?> { ?>
@ -109,11 +109,11 @@ function OutputDrawer($drawerName, $blendmode, $isTruecolor, $isColorFill, $isLi
<? } <? }
else else
{ {
GenerateDrawer($drawerName, $blendmode, $isTruecolor, $isColorFill); GenerateDrawer($drawerName, $blendmode, $isTranslated, $isTruecolor, $isColorFill);
} }
} }
function GenerateDrawer($drawerName, $blendmode, $isTruecolor, $isColorFill) function GenerateDrawer($drawerName, $blendmode, $isTranslated, $isTruecolor, $isColorFill)
{ {
$pixeltype = $isTruecolor ? "uint32_t" : "uint8_t"; $pixeltype = $isTruecolor ? "uint32_t" : "uint8_t";
?> ?>
@ -132,6 +132,8 @@ static void <?=$drawerName?>(const TriDrawTriangleArgs *args, WorkerThreadData *
bool is_fixed_light = (flags & TriUniforms::fixed_light) == TriUniforms::fixed_light; bool is_fixed_light = (flags & TriUniforms::fixed_light) == TriUniforms::fixed_light;
uint32_t lightmask = is_fixed_light ? 0 : 0xffffffff; uint32_t lightmask = is_fixed_light ? 0 : 0xffffffff;
auto colormaps = args->colormaps; auto colormaps = args->colormaps;
uint32_t srcalpha = args->uniforms->srcalpha;
uint32_t destalpha = args->uniforms->destalpha;
// Calculate gradients // Calculate gradients
const TriVertex &v1 = *args->v1; const TriVertex &v1 = *args->v1;
@ -150,7 +152,15 @@ static void <?=$drawerName?>(const TriDrawTriangleArgs *args, WorkerThreadData *
start.Varying[i] = v1.varying[i] * v1.w + gradientX.Varying[i] * (startX - v1.x) + gradientY.Varying[i] * (startY - v1.y); start.Varying[i] = v1.varying[i] * v1.w + gradientX.Varying[i] * (startX - v1.x) + gradientY.Varying[i] * (startY - v1.y);
} }
<? if ($isTranslated || $blendmode == "shaded")
{ ?>
const uint8_t * RESTRICT texPixels = args->texturePixels;
const <?=$pixeltype?> * RESTRICT translation = (const <?=$pixeltype?> *)args->translation;
<? }
else
{ ?>
const <?=$pixeltype?> * RESTRICT texPixels = (const <?=$pixeltype?> *)args->texturePixels; const <?=$pixeltype?> * RESTRICT texPixels = (const <?=$pixeltype?> *)args->texturePixels;
<? }?>
uint32_t texWidth = args->textureWidth; uint32_t texWidth = args->textureWidth;
uint32_t texHeight = args->textureHeight; uint32_t texHeight = args->textureHeight;
@ -208,51 +218,9 @@ static void <?=$drawerName?>(const TriDrawTriangleArgs *args, WorkerThreadData *
for (int ix = 0; ix < 8; ix++) for (int ix = 0; ix < 8; ix++)
{ {
<? if ($isColorFill) <?=$pixeltype?> *destptr = dest + x * 8 + ix;
{ ?> <? ProcessPixel($blendmode, $isTranslated, $isTruecolor, $isColorFill, $pixeltype); ?>
<?=$pixeltype?> fg = color; *destptr = fg;
<? }
else
{ ?>
int texelX = ((((uint32_t)varyingPos[0] << 8) >> 16) * texWidth) >> 16;
int texelY = ((((uint32_t)varyingPos[1] << 8) >> 16) * texHeight) >> 16;
<?=$pixeltype?> fg = texPixels[texelX * texHeight + texelY];
<? }
if ($isTruecolor)
{ ?>
uint32_t r = RPART(fg);
uint32_t g = GPART(fg);
uint32_t b = BPART(fg);
r = (r * lightpos) >> 16;
g = (g * lightpos) >> 16;
b = (b * lightpos) >> 16;
<? if ($blendmode != "opaque")
{ ?>
uint32_t a = APART(fg);
a += a >> 7;
uint32_t inv_a = 256 - a;
uint32_t bg = dest[x * 8 + ix];
uint32_t bg_red = RPART(bg);
uint32_t bg_green = GPART(bg);
uint32_t bg_blue = BPART(bg);
r = (r * a + bg_red * inv_a + 127) >> 8;
g = (g * a + bg_green * inv_a + 127) >> 8;
b = (b * a + bg_blue * inv_a + 127) >> 8;
fg = 0xff000000 | (r << 16) | (g << 8) | b;
<? }
else
{ ?>
fg = 0xff000000 | (r << 16) | (g << 8) | b;
<? }
}
else
{ ?>
int colormapindex = MIN(((256 - (lightpos >> 8)) * 32) >> 8, 31) << 8;
fg = colormaps[colormapindex + fg];
<? } ?>
dest[x * 8 + ix] = fg;
for (int j = 0; j < TriVertex::NumVarying; j++) for (int j = 0; j < TriVertex::NumVarying; j++)
varyingPos[j] += varyingStep[j]; varyingPos[j] += varyingStep[j];
@ -317,51 +285,9 @@ static void <?=$drawerName?>(const TriDrawTriangleArgs *args, WorkerThreadData *
{ {
if (<?=$coveragemask?> & (1 << 31)) if (<?=$coveragemask?> & (1 << 31))
{ {
<? if ($isColorFill) <?=$pixeltype?> *destptr = dest + x;
{ ?> <? ProcessPixel($blendmode, $isTranslated, $isTruecolor, $isColorFill, $pixeltype); ?>
<?=$pixeltype?> fg = color; *destptr = fg;
<? }
else
{ ?>
int texelX = ((((uint32_t)varyingPos[0] << 8) >> 16) * texWidth) >> 16;
int texelY = ((((uint32_t)varyingPos[1] << 8) >> 16) * texHeight) >> 16;
<?=$pixeltype?> fg = texPixels[texelX * texHeight + texelY];
<? }
if ($isTruecolor)
{ ?>
uint32_t r = RPART(fg);
uint32_t g = GPART(fg);
uint32_t b = BPART(fg);
r = (r * lightpos) >> 16;
g = (g * lightpos) >> 16;
b = (b * lightpos) >> 16;
<? if ($blendmode != "opaque")
{ ?>
uint32_t a = APART(fg);
a += a >> 7;
uint32_t inv_a = 256 - a;
uint32_t bg = dest[x];
uint32_t bg_red = RPART(bg);
uint32_t bg_green = GPART(bg);
uint32_t bg_blue = BPART(bg);
r = (r * a + bg_red * inv_a + 127) >> 8;
g = (g * a + bg_green * inv_a + 127) >> 8;
b = (b * a + bg_blue * inv_a + 127) >> 8;
fg = 0xff000000 | (r << 16) | (g << 8) | b;
<? }
else
{ ?>
fg = 0xff000000 | (r << 16) | (g << 8) | b;
<? }
}
else
{ ?>
int colormapindex = MIN(((256 - (lightpos >> 8)) * 32) >> 8, 31) << 8;
fg = colormaps[colormapindex + fg];
<? } ?>
dest[x] = fg;
} }
<?=$coveragemask?> <<= 1; <?=$coveragemask?> <<= 1;
@ -383,4 +309,141 @@ static void <?=$drawerName?>(const TriDrawTriangleArgs *args, WorkerThreadData *
<? <?
} }
function ProcessPixel($blendmode, $isTranslated, $isTruecolor, $isColorFill, $pixeltype)
{
if ($isColorFill || $blendmode == "shaded")
{ ?>
<?=$pixeltype?> fg = color;
<? }
else
{ ?>
int texelX = ((((uint32_t)varyingPos[0] << 8) >> 16) * texWidth) >> 16;
int texelY = ((((uint32_t)varyingPos[1] << 8) >> 16) * texHeight) >> 16;
<?=$pixeltype?> fg = texPixels[texelX * texHeight + texelY];
<? }
if ($isTranslated)
{ ?>
fg = translation[fg];
<? }
if ($isTruecolor)
{ ?>
uint32_t r = RPART(fg);
uint32_t g = GPART(fg);
uint32_t b = BPART(fg);
r = (r * lightpos) >> 16;
g = (g * lightpos) >> 16;
b = (b * lightpos) >> 16;
<? TruecolorBlend($blendmode); ?>
fg = 0xff000000 | (r << 16) | (g << 8) | b;
<?
}
else
{ ?>
int colormapindex = MIN(((256 - (lightpos >> 8)) * 32) >> 8, 31) << 8;
fg = colormaps[colormapindex + fg];
<? }
}
function TruecolorBlend($blendmode)
{
if ($blendmode == "opaque")
{
}
else if ($blendmode == "masked")
{ ?>
uint32_t a = APART(fg);
a += a >> 7;
uint32_t inv_a = 256 - a;
uint32_t bg = *destptr;
uint32_t bg_red = RPART(bg);
uint32_t bg_green = GPART(bg);
uint32_t bg_blue = BPART(bg);
r = (r * a + bg_red * inv_a + 127) >> 8;
g = (g * a + bg_green * inv_a + 127) >> 8;
b = (b * a + bg_blue * inv_a + 127) >> 8;
<? }
else if ($blendmode == "translucent")
{ ?>
<? }
else if ($blendmode == "shaded")
{ ?>
int texelX = ((((uint32_t)varyingPos[0] << 8) >> 16) * texWidth) >> 16;
int texelY = ((((uint32_t)varyingPos[1] << 8) >> 16) * texHeight) >> 16;
int sample = texPixels[texelX * texHeight + texelY];
uint32_t fgalpha = sample;//clamp(sample, 0, 64) * 4;
uint32_t inv_fgalpha = 256 - fgalpha;
int a = (fgalpha * srcalpha + 128) >> 8;
int inv_a = (destalpha * fgalpha + 256 * inv_fgalpha + 128) >> 8;
uint32_t bg = *destptr;
uint32_t bg_red = RPART(bg);
uint32_t bg_green = GPART(bg);
uint32_t bg_blue = BPART(bg);
r = (r * a + bg_red * inv_a + 127) >> 8;
g = (g * a + bg_green * inv_a + 127) >> 8;
b = (b * a + bg_blue * inv_a + 127) >> 8;
<? }
else if ($blendmode == "stencil")
{ ?>
uint32_t fgalpha = APART(fg);
uint32_t inv_fgalpha = 256 - fgalpha;
int a = (fgalpha * srcalpha + 128) >> 8;
int inv_a = (destalpha * fgalpha + 256 * inv_fgalpha + 128) >> 8;
uint32_t bg = *destptr;
uint32_t bg_red = RPART(bg);
uint32_t bg_green = GPART(bg);
uint32_t bg_blue = BPART(bg);
r = (r * a + bg_red * inv_a + 127) >> 8;
g = (g * a + bg_green * inv_a + 127) >> 8;
b = (b * a + bg_blue * inv_a + 127) >> 8;
<? }
else if ($blendmode == "addsrccolor")
{ ?>
uint32_t inv_r = 256 - (r + (r >> 7));
uint32_t inv_g = 256 - (g + (r >> 7));
uint32_t inv_b = 256 - (b + (r >> 7));
uint32_t bg = *destptr;
uint32_t bg_red = RPART(bg);
uint32_t bg_green = GPART(bg);
uint32_t bg_blue = BPART(bg);
r = r + ((bg_red * inv_r + 127) >> 8);
g = g + ((bg_green * inv_g + 127) >> 8);
b = b + ((bg_blue * inv_b + 127) >> 8);
<? }
else if ($blendmode == "skycap")
{ ?>
int start_fade = 2; // How fast it should fade out
int alpha_top = clamp(varyingPos[1] >> (16 - start_fade), 0, 256);
int alpha_bottom = clamp(((2 << 24) - varyingPos[1]) >> (16 - start_fade), 0, 256);
int a = MIN(alpha_top, alpha_bottom);
int inv_a = 256 - a;
uint32_t bg_red = RPART(color);
uint32_t bg_green = GPART(color);
uint32_t bg_blue = BPART(color);
r = (r * a + bg_red * inv_a + 127) >> 8;
g = (g * a + bg_green * inv_a + 127) >> 8;
b = (b * a + bg_blue * inv_a + 127) >> 8;
<? }
else
{ ?>
uint32_t a = APART(fg);
a += a >> 7;
uint32_t inv_a = 256 - a;
uint32_t bg = *destptr;
uint32_t bg_red = RPART(bg);
uint32_t bg_green = GPART(bg);
uint32_t bg_blue = BPART(bg);
r = (r * a + bg_red * inv_a + 127) >> 8;
g = (g * a + bg_green * inv_a + 127) >> 8;
b = (b * a + bg_blue * inv_a + 127) >> 8;
<? }
}
?> ?>