Skip to content

Commit 15b6922

Browse files
Warr1024SmallJoker
authored andcommitted
Correction for alpha blending issues in texture mod compositing (#9029)
1 parent b7e3587 commit 15b6922

File tree

1 file changed

+20
-2
lines changed

1 file changed

+20
-2
lines changed

src/client/tile.cpp

+20-2
Original file line numberDiff line numberDiff line change
@@ -1811,6 +1811,24 @@ bool TextureSource::generateImagePart(std::string part_of_name,
18111811
return true;
18121812
}
18131813

1814+
/*
1815+
Calculate the color of a single pixel drawn on top of another pixel.
1816+
1817+
This is a little more complicated than just video::SColor::getInterpolated
1818+
because getInterpolated does not handle alpha correctly. For example, a
1819+
pixel with alpha=64 drawn atop a pixel with alpha=128 should yield a
1820+
pixel with alpha=160, while getInterpolated would yield alpha=96.
1821+
*/
1822+
static inline video::SColor blitPixel(const video::SColor &src_c, const video::SColor &dst_c, u32 ratio)
1823+
{
1824+
if (dst_c.getAlpha() == 0)
1825+
return src_c;
1826+
video::SColor out_c = src_c.getInterpolated(dst_c, (float)ratio / 255.0f);
1827+
out_c.setAlpha(dst_c.getAlpha() + (255 - dst_c.getAlpha()) *
1828+
src_c.getAlpha() * ratio / (255 * 255));
1829+
return out_c;
1830+
}
1831+
18141832
/*
18151833
Draw an image on top of an another one, using the alpha channel of the
18161834
source image
@@ -1830,7 +1848,7 @@ static void blit_with_alpha(video::IImage *src, video::IImage *dst,
18301848
s32 dst_y = dst_pos.Y + y0;
18311849
video::SColor src_c = src->getPixel(src_x, src_y);
18321850
video::SColor dst_c = dst->getPixel(dst_x, dst_y);
1833-
dst_c = src_c.getInterpolated(dst_c, (float)src_c.getAlpha()/255.0f);
1851+
dst_c = blitPixel(src_c, dst_c, src_c.getAlpha());
18341852
dst->setPixel(dst_x, dst_y, dst_c);
18351853
}
18361854
}
@@ -1853,7 +1871,7 @@ static void blit_with_alpha_overlay(video::IImage *src, video::IImage *dst,
18531871
video::SColor dst_c = dst->getPixel(dst_x, dst_y);
18541872
if (dst_c.getAlpha() == 255 && src_c.getAlpha() != 0)
18551873
{
1856-
dst_c = src_c.getInterpolated(dst_c, (float)src_c.getAlpha()/255.0f);
1874+
dst_c = blitPixel(src_c, dst_c, src_c.getAlpha());
18571875
dst->setPixel(dst_x, dst_y, dst_c);
18581876
}
18591877
}

0 commit comments

Comments
 (0)