diff options
author | Jesse Plamondon-Willard <github@jplamondonw.com> | 2018-09-25 00:58:46 -0400 |
---|---|---|
committer | Jesse Plamondon-Willard <github@jplamondonw.com> | 2018-09-25 00:58:46 -0400 |
commit | b9844c4acd93411c2a7d21bd115cb4fee1791d76 (patch) | |
tree | 7e25e04a7e57e740ddd4fa726b58e5832d7bec29 /src/SMAPI/Framework | |
parent | 99e4a4a1ccf5dcbe0e4b1af7591e229a0eeae447 (diff) | |
download | SMAPI-b9844c4acd93411c2a7d21bd115cb4fee1791d76.tar.gz SMAPI-b9844c4acd93411c2a7d21bd115cb4fee1791d76.tar.bz2 SMAPI-b9844c4acd93411c2a7d21bd115cb4fee1791d76.zip |
add support for semi-transparency when overlaying images
Diffstat (limited to 'src/SMAPI/Framework')
-rw-r--r-- | src/SMAPI/Framework/Content/AssetDataForImage.cs | 39 |
1 files changed, 36 insertions, 3 deletions
diff --git a/src/SMAPI/Framework/Content/AssetDataForImage.cs b/src/SMAPI/Framework/Content/AssetDataForImage.cs index 5c7b87de..cd372948 100644 --- a/src/SMAPI/Framework/Content/AssetDataForImage.cs +++ b/src/SMAPI/Framework/Content/AssetDataForImage.cs @@ -8,6 +8,14 @@ namespace StardewModdingAPI.Framework.Content internal class AssetDataForImage : AssetData<Texture2D>, IAssetDataForImage { /********* + ** Properties + *********/ + /// <summary>The minimum value to consider non-transparent.</summary> + /// <remarks>On Linux/Mac, fully transparent pixels may have an alpha up to 4 for some reason.</remarks> + private const byte MinOpacity = 5; + + + /********* ** Public methods *********/ /// <summary>Construct an instance.</summary> @@ -53,13 +61,38 @@ namespace StardewModdingAPI.Framework.Content // merge data in overlay mode if (patchMode == PatchMode.Overlay) { + // get target data + Color[] targetData = new Color[pixelCount]; + target.GetData(0, targetArea, targetData, 0, pixelCount); + + // merge pixels Color[] newData = new Color[targetArea.Value.Width * targetArea.Value.Height]; target.GetData(0, targetArea, newData, 0, newData.Length); for (int i = 0; i < sourceData.Length; i++) { - Color pixel = sourceData[i]; - if (pixel.A > 4) // not transparent (note: on Linux/Mac, fully transparent pixels may have an alpha up to 4 for some reason) - newData[i] = pixel; + Color above = sourceData[i]; + Color below = targetData[i]; + + // shortcut transparency + if (above.A < AssetDataForImage.MinOpacity) + continue; + if (below.A < AssetDataForImage.MinOpacity) + { + newData[i] = above; + continue; + } + + // merge pixels + // This performs a conventional alpha blend for the pixels, which are already + // premultiplied by the content pipeline. + float alphaAbove = above.A / 255f; + float alphaBelow = (255 - above.A) / 255f; + newData[i] = new Color( + r: (int)((above.R * alphaAbove) + (below.R * alphaBelow)), + g: (int)((above.G * alphaAbove) + (below.G * alphaBelow)), + b: (int)((above.B * alphaAbove) + (below.B * alphaBelow)), + a: Math.Max(above.A, below.A) + ); } sourceData = newData; } |