diff --git a/osu.Framework/Graphics/BlendingParameters.cs b/osu.Framework/Graphics/BlendingParameters.cs index 1721dab3ac..4ad89417de 100644 --- a/osu.Framework/Graphics/BlendingParameters.cs +++ b/osu.Framework/Graphics/BlendingParameters.cs @@ -80,6 +80,17 @@ public struct BlendingParameters : IEquatable AlphaEquation = BlendingEquation.Add, }; + // we can't really get an accurate diffrence blend for alphas with the current blending params, this is a close approximation + public static BlendingParameters Difference => new BlendingParameters + { + Source = BlendingType.One, + Destination = BlendingType.One, + SourceAlpha = BlendingType.Zero, + DestinationAlpha = BlendingType.One, + RGBEquation = BlendingEquation.Subtract, + AlphaEquation = BlendingEquation.Add, + }; + public static BlendingParameters Additive => new BlendingParameters { Source = BlendingType.SrcAlpha, @@ -90,8 +101,65 @@ public struct BlendingParameters : IEquatable AlphaEquation = BlendingEquation.Add, }; + public static BlendingParameters Subtractive => new BlendingParameters + { + Source = BlendingType.One, + Destination = BlendingType.One, + SourceAlpha = BlendingType.Zero, + DestinationAlpha = BlendingType.One, + RGBEquation = BlendingEquation.ReverseSubtract, + AlphaEquation = BlendingEquation.Add, + }; + + public static BlendingParameters Screen => new BlendingParameters + { + Source = BlendingType.One, + Destination = BlendingType.OneMinusSrcColor, + SourceAlpha = BlendingType.One, + DestinationAlpha = BlendingType.OneMinusSrcAlpha, + RGBEquation = BlendingEquation.Add, + AlphaEquation = BlendingEquation.Add, + }; + + public static BlendingParameters Multiplicative => new BlendingParameters + { + Source = BlendingType.DstColor, + Destination = BlendingType.OneMinusSrcAlpha, + SourceAlpha = BlendingType.One, + DestinationAlpha = BlendingType.OneMinusSrcAlpha, + RGBEquation = BlendingEquation.Add, + AlphaEquation = BlendingEquation.Add, + }; + + public static BlendingParameters Premultiplied => new BlendingParameters + { + Source = BlendingType.One, + Destination = BlendingType.OneMinusSrcAlpha, + SourceAlpha = BlendingType.One, + DestinationAlpha = BlendingType.OneMinusSrcAlpha, + RGBEquation = BlendingEquation.Add, + AlphaEquation = BlendingEquation.Add, + }; + #endregion + public static BlendingParameters GetDefaultParameters(DefaultBlendingParameters blendingParameterType) + { + return blendingParameterType switch + { + DefaultBlendingParameters.None => None, + DefaultBlendingParameters.Inherit => Inherit, + DefaultBlendingParameters.Mix => Mixture, + DefaultBlendingParameters.Difference => Difference, + DefaultBlendingParameters.Add => Additive, + DefaultBlendingParameters.Subtract => Subtractive, + DefaultBlendingParameters.Screen => Screen, + DefaultBlendingParameters.Multiply => Multiplicative, + DefaultBlendingParameters.Premultiplied => Premultiplied, + _ => throw new ArgumentOutOfRangeException(nameof(blendingParameterType), blendingParameterType, null), + }; + } + /// /// Copy all properties that are marked as inherited from a parent object. /// @@ -238,7 +306,7 @@ private static BlendingFactorSrc translateBlendingFactorSrc(BlendingType factor) return BlendingFactorSrc.OneMinusDstColor; case BlendingType.OneMinusSrcAlpha: - return BlendingFactorSrc.OneMinusSrcColor; + return BlendingFactorSrc.OneMinusSrcAlpha; case BlendingType.SrcAlpha: return BlendingFactorSrc.SrcAlpha; diff --git a/osu.Framework/Graphics/DefaultBlendingParameters.cs b/osu.Framework/Graphics/DefaultBlendingParameters.cs new file mode 100644 index 0000000000..f4e2372698 --- /dev/null +++ b/osu.Framework/Graphics/DefaultBlendingParameters.cs @@ -0,0 +1,18 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +namespace osu.Framework.Graphics +{ + public enum DefaultBlendingParameters + { + None, + Inherit, + Mix, + Difference, + Add, + Subtract, + Screen, + Multiply, + Premultiplied, + } +} diff --git a/osu.Framework/Graphics/Textures/TextureUpload.cs b/osu.Framework/Graphics/Textures/TextureUpload.cs index 096e7ed783..27774c8f91 100644 --- a/osu.Framework/Graphics/Textures/TextureUpload.cs +++ b/osu.Framework/Graphics/Textures/TextureUpload.cs @@ -13,6 +13,7 @@ using osuTK.Graphics.ES30; using SixLabors.ImageSharp; using SixLabors.ImageSharp.PixelFormats; +using SixLabors.ImageSharp.Processing; using StbiSharp; namespace osu.Framework.Graphics.Textures @@ -98,10 +99,35 @@ internal static Image LoadFromStream(Stream stream) where TPixel Logger.Log($"Texture could not be loaded via STB; falling back to ImageSharp: {e.Message}"); stream.Position = initialPos; - return Image.Load(stream); + + bool isWebP = TextureUpload.isWebP(stream); + var image = Image.Load(stream); + + // a stupid fix for heavily compressed webp images with visible artifacts but it's efficient and works + if (isWebP) + image.Mutate(x => x.BoxBlur(0)); + + return image; } } + private static bool isWebP(Stream stream) + { + long initialPos = stream.Position; + + if (stream.Length < 12) + return false; + + Span header = stackalloc byte[12]; + stream.ReadExactly(header); + stream.Position = initialPos; + + return header[0] == 'R' && header[1] == 'I' && + header[2] == 'F' && header[3] == 'F' && + header[8] == 'W' && header[9] == 'E' && + header[10] == 'B' && header[11] == 'P'; + } + /// /// Create an empty upload. Used by for initialisation. ///