aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorraysan5 <raysan5@gmail.com>2018-04-29 18:39:57 +0200
committerraysan5 <raysan5@gmail.com>2018-04-29 18:39:57 +0200
commitc51203ae7e7aefac5fa95097d424aefdbe9c759c (patch)
tree8ad59f76bb132f28381e2bbe7422ca10d9968f94 /src
parentdff10284666ad30823fa88ec57d0ae8eac7e7fad (diff)
downloadraylib-c51203ae7e7aefac5fa95097d424aefdbe9c759c.tar.gz
raylib-c51203ae7e7aefac5fa95097d424aefdbe9c759c.zip
Corrected alpha blending on ImageDraw()
Diffstat (limited to 'src')
-rw-r--r--src/textures.c54
1 files changed, 24 insertions, 30 deletions
diff --git a/src/textures.c b/src/textures.c
index 43453f73..eadb0c59 100644
--- a/src/textures.c
+++ b/src/textures.c
@@ -1312,44 +1312,38 @@ void ImageDraw(Image *dst, Image src, Rectangle srcRec, Rectangle dstRec)
UnloadImage(srcCopy); // Source copy not required any more...
- Color srcCol, dstCol;
-
+ Vector4 fsrc, fdst, fout; // float based versions of pixel data
+
// Blit pixels, copy source image into destination
// TODO: Probably out-of-bounds blitting could be considered here instead of so much cropping...
for (int j = dstRec.y; j < (dstRec.y + dstRec.height); j++)
{
for (int i = dstRec.x; i < (dstRec.x + dstRec.width); i++)
{
- // Alpha blending implementation
- dstCol = dstPixels[j*dst->width + i];
- srcCol = srcPixels[(j - dstRec.y)*dstRec.width + (i - dstRec.x)];
-
- /*
- // Pre-multiply alpha
- Vector3 dstColf = { (float)dstCol.r/255.0f, (float)dstCol.g/255.0f, (float)dstCol.b/255.0f };
- dstColf = Vector3Multiply(dstColf, (float)dstCol.a/255.0f);
- Vector3 srcColf = { (float)srcCol.r/255.0f, (float)srcCol.g/255.0f, (float)srcCol.b/255.0f };
- srcColf = Vector3Multiply(srcColf, (float)srcCol.a/255.0f);
+ // Alpha blending (https://en.wikipedia.org/wiki/Alpha_compositing)
- dstColf = Vector3Add(dstColf, srcColf);
-
- if (dstColf.x > 1.0f) dstColf.x = 1.0f;
- if (dstColf.y > 1.0f) dstColf.y = 1.0f;
- if (dstColf.z > 1.0f) dstColf.z = 1.0f;
+ fdst = ColorNormalize(dstPixels[j*dst->width + i]);
+ fsrc = ColorNormalize(srcPixels[(j - dstRec.y)*dstRec.width + (i - dstRec.x)]);
+
+ fout.w = fsrc.w + fdst.w*(1.0f - fsrc.w);
- dstCol.r = (unsigned char)(dstColf.x*255.0f);
- dstCol.g = (unsigned char)(dstColf.y*255.0f);
- dstCol.b = (unsigned char)(dstColf.z*255.0f);
- dstCol.a = srcCol.a;
- */
-
- dstCol.r = ((srcCol.a*(srcCol.r - dstCol.r)) >> 8) + dstCol.r;
- dstCol.g = ((srcCol.a*(srcCol.g - dstCol.g)) >> 8) + dstCol.g;
- dstCol.b = ((srcCol.a*(srcCol.b - dstCol.b)) >> 8) + dstCol.b;
- //dstCol.a = ((srcCol.a*(srcCol.a - dstCol.a)) >> 8) + dstCol.a;
- dstCol.a = srcCol.a;
-
- dstPixels[j*dst->width + i] = dstCol;
+ if (fout.w <= 0.0f)
+ {
+ fout.x = 0.0f;
+ fout.y = 0.0f;
+ fout.z = 0.0f;
+ }
+ else
+ {
+ fout.x = (fsrc.x*fsrc.w + fdst.x*fdst.w*(1 - fsrc.w))/fout.w;
+ fout.y = (fsrc.y*fsrc.w + fdst.y*fdst.w*(1 - fsrc.w))/fout.w;
+ fout.z = (fsrc.z*fsrc.w + fdst.z*fdst.w*(1 - fsrc.w))/fout.w;
+ }
+
+ dstPixels[j*dst->width + i] = (Color){ (unsigned char)(fout.x*255.0f),
+ (unsigned char)(fout.y*255.0f),
+ (unsigned char)(fout.z*255.0f),
+ (unsigned char)(fout.w*255.0f) };
// TODO: Support other blending options
}