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:
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
|
@ -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;
|
||||||
|
<? }
|
||||||
|
}
|
||||||
|
|
||||||
?>
|
?>
|
Loading…
Reference in a new issue