From 30b2ea1661259c55b8032c5824c6719bc8ad743e Mon Sep 17 00:00:00 2001 From: andy840119 Date: Sun, 19 Mar 2023 19:51:00 +0800 Subject: [PATCH 01/11] Drawable class should be partial. --- .../Visual/Sprites/TestSceneKaraokeSpriteText.cs | 2 +- .../Visual/Sprites/TestSceneKaraokeSpriteTextTransforms.cs | 2 +- .../Visual/Sprites/TestSceneKaraokeSpriteTextWithShader.cs | 2 +- .../Visual/Sprites/TestSceneLyricSpriteText.cs | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Framework.Font.Tests/Visual/Sprites/TestSceneKaraokeSpriteText.cs b/osu.Framework.Font.Tests/Visual/Sprites/TestSceneKaraokeSpriteText.cs index 9d07fd9..1809438 100644 --- a/osu.Framework.Font.Tests/Visual/Sprites/TestSceneKaraokeSpriteText.cs +++ b/osu.Framework.Font.Tests/Visual/Sprites/TestSceneKaraokeSpriteText.cs @@ -223,7 +223,7 @@ public void TestLyricShaders() }); } - private class TestKaraokeSpriteText : KaraokeSpriteText + private partial class TestKaraokeSpriteText : KaraokeSpriteText { public Action? TransformAction; diff --git a/osu.Framework.Font.Tests/Visual/Sprites/TestSceneKaraokeSpriteTextTransforms.cs b/osu.Framework.Font.Tests/Visual/Sprites/TestSceneKaraokeSpriteTextTransforms.cs index 10d00a8..d0b1e33 100644 --- a/osu.Framework.Font.Tests/Visual/Sprites/TestSceneKaraokeSpriteTextTransforms.cs +++ b/osu.Framework.Font.Tests/Visual/Sprites/TestSceneKaraokeSpriteTextTransforms.cs @@ -203,7 +203,7 @@ public void TestApplyOutlineAndShadowShader(bool differentSizing) private static string getApplyDescription(bool applyDifferentSizing) => applyDifferentSizing ? "Apply shader with different sizing" : "Apply shader"; - private class TestKaraokeSpriteText : KaraokeSpriteText + private partial class TestKaraokeSpriteText : KaraokeSpriteText { public override bool RemoveCompletedTransforms => false; } diff --git a/osu.Framework.Font.Tests/Visual/Sprites/TestSceneKaraokeSpriteTextWithShader.cs b/osu.Framework.Font.Tests/Visual/Sprites/TestSceneKaraokeSpriteTextWithShader.cs index 541629e..65a18db 100644 --- a/osu.Framework.Font.Tests/Visual/Sprites/TestSceneKaraokeSpriteTextWithShader.cs +++ b/osu.Framework.Font.Tests/Visual/Sprites/TestSceneKaraokeSpriteTextWithShader.cs @@ -107,7 +107,7 @@ public void ApplyRightLyricTextShader() }); } - private class TestKaraokeSpriteText : KaraokeSpriteText + private partial class TestKaraokeSpriteText : KaraokeSpriteText { public override bool RemoveCompletedTransforms => false; } diff --git a/osu.Framework.Font.Tests/Visual/Sprites/TestSceneLyricSpriteText.cs b/osu.Framework.Font.Tests/Visual/Sprites/TestSceneLyricSpriteText.cs index 7101288..e393875 100644 --- a/osu.Framework.Font.Tests/Visual/Sprites/TestSceneLyricSpriteText.cs +++ b/osu.Framework.Font.Tests/Visual/Sprites/TestSceneLyricSpriteText.cs @@ -230,7 +230,7 @@ private void setContents(Func creationFunction) Child = creationFunction().With(x => x.Scale = new Vector2(2)); } - internal class DefaultLyricSpriteText : LyricSpriteText + internal partial class DefaultLyricSpriteText : LyricSpriteText { public DefaultLyricSpriteText(bool ruby = true, bool romaji = true) { From 2ba5bd2817045539f7c952bc3196a68c70f927ed Mon Sep 17 00:00:00 2001 From: andy840119 Date: Tue, 14 Mar 2023 20:22:17 +0800 Subject: [PATCH 02/11] Upgrade the framework and the resource package to the latest. --- osu.Framework.Font.Tests/osu.Framework.Font.Tests.csproj | 2 +- osu.Framework.Font/osu.Framework.Font.csproj | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Framework.Font.Tests/osu.Framework.Font.Tests.csproj b/osu.Framework.Font.Tests/osu.Framework.Font.Tests.csproj index 1d330f9..fcea9c2 100644 --- a/osu.Framework.Font.Tests/osu.Framework.Font.Tests.csproj +++ b/osu.Framework.Font.Tests/osu.Framework.Font.Tests.csproj @@ -11,7 +11,7 @@ - + diff --git a/osu.Framework.Font/osu.Framework.Font.csproj b/osu.Framework.Font/osu.Framework.Font.csproj index ee181f1..f2b231c 100644 --- a/osu.Framework.Font/osu.Framework.Font.csproj +++ b/osu.Framework.Font/osu.Framework.Font.csproj @@ -29,7 +29,7 @@ en - + From af7f8996642d42decd8ba37d3a26299b1ad8ecbe Mon Sep 17 00:00:00 2001 From: andy840119 Date: Sat, 18 Mar 2023 22:39:52 +0800 Subject: [PATCH 03/11] Expose the renderer because need the renderer to create the binding object. --- .../Graphics/CustomizedShaderBufferedDrawNode.cs | 2 +- osu.Framework.Font/Graphics/Shaders/CustomizedShader.cs | 3 ++- osu.Framework.Font/Graphics/Shaders/ICustomizedShader.cs | 3 ++- osu.Framework.Font/Graphics/Shaders/OutlineShader.cs | 3 ++- osu.Framework.Font/Graphics/Shaders/PixelShader.cs | 3 ++- osu.Framework.Font/Graphics/Shaders/RainbowShader.cs | 3 ++- .../Graphics/Shaders/RepeatMovingBackgroundShader.cs | 3 ++- osu.Framework.Font/Graphics/Shaders/ShadowShader.cs | 3 ++- osu.Framework.Font/Graphics/Shaders/StepShader.cs | 3 ++- 9 files changed, 17 insertions(+), 9 deletions(-) diff --git a/osu.Framework.Font/Graphics/CustomizedShaderBufferedDrawNode.cs b/osu.Framework.Font/Graphics/CustomizedShaderBufferedDrawNode.cs index 65f0bf7..00a08af 100644 --- a/osu.Framework.Font/Graphics/CustomizedShaderBufferedDrawNode.cs +++ b/osu.Framework.Font/Graphics/CustomizedShaderBufferedDrawNode.cs @@ -71,7 +71,7 @@ protected void RenderShader(IRenderer renderer, ICustomizedShader shader, IFrame } if (shader is ICustomizedShader customizedShader) - customizedShader.ApplyValue(); + customizedShader.ApplyValue(renderer); shader.Bind(); renderer.DrawFrameBuffer(current, new RectangleF(0, 0, current.Texture.Width, current.Texture.Height), ColourInfo.SingleColour(Color4.White)); diff --git a/osu.Framework.Font/Graphics/Shaders/CustomizedShader.cs b/osu.Framework.Font/Graphics/Shaders/CustomizedShader.cs index 0872208..1b84c8f 100644 --- a/osu.Framework.Font/Graphics/Shaders/CustomizedShader.cs +++ b/osu.Framework.Font/Graphics/Shaders/CustomizedShader.cs @@ -2,6 +2,7 @@ // See the LICENCE file in the repository root for full licence text. using System; +using osu.Framework.Graphics.Rendering; namespace osu.Framework.Graphics.Shaders; @@ -28,7 +29,7 @@ public Uniform GetUniform(string name) where T : unmanaged, IEquatable public bool IsBound { get; private set; } - public abstract void ApplyValue(); + public abstract void ApplyValue(IRenderer renderer); public void Dispose() { diff --git a/osu.Framework.Font/Graphics/Shaders/ICustomizedShader.cs b/osu.Framework.Font/Graphics/Shaders/ICustomizedShader.cs index e8ef34d..f0ac6f7 100644 --- a/osu.Framework.Font/Graphics/Shaders/ICustomizedShader.cs +++ b/osu.Framework.Font/Graphics/Shaders/ICustomizedShader.cs @@ -2,12 +2,13 @@ // See the LICENCE file in the repository root for full licence text. using System; +using osu.Framework.Graphics.Rendering; namespace osu.Framework.Graphics.Shaders; public interface ICustomizedShader { - void ApplyValue(); + void ApplyValue(IRenderer renderer); /// /// Binds this shader to be used for rendering. diff --git a/osu.Framework.Font/Graphics/Shaders/OutlineShader.cs b/osu.Framework.Font/Graphics/Shaders/OutlineShader.cs index 50bac34..75ea736 100644 --- a/osu.Framework.Font/Graphics/Shaders/OutlineShader.cs +++ b/osu.Framework.Font/Graphics/Shaders/OutlineShader.cs @@ -3,6 +3,7 @@ using System; using osu.Framework.Graphics.Primitives; +using osu.Framework.Graphics.Rendering; using osuTK; using osuTK.Graphics; @@ -18,7 +19,7 @@ public class OutlineShader : InternalShader, IApplicableToCharacterSize, IApplic public Color4 OutlineColour { get; set; } - public override void ApplyValue() + public override void ApplyValue(IRenderer renderer) { var colourMatrix = new Vector4(Colour.R, Colour.G, Colour.B, Colour.A); GetUniform(@"g_Colour").UpdateValue(ref colourMatrix); diff --git a/osu.Framework.Font/Graphics/Shaders/PixelShader.cs b/osu.Framework.Font/Graphics/Shaders/PixelShader.cs index 784eeb3..bb60337 100644 --- a/osu.Framework.Font/Graphics/Shaders/PixelShader.cs +++ b/osu.Framework.Font/Graphics/Shaders/PixelShader.cs @@ -1,6 +1,7 @@ // Copyright (c) karaoke.dev . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using osu.Framework.Graphics.Rendering; using osuTK; namespace osu.Framework.Graphics.Shaders; @@ -11,7 +12,7 @@ public class PixelShader : InternalShader, IHasTextureSize, IHasInflationPercent public Vector2 Size { get; set; } = new(5); - public override void ApplyValue() + public override void ApplyValue(IRenderer renderer) { var size = Size; GetUniform(@"g_Size").UpdateValue(ref size); diff --git a/osu.Framework.Font/Graphics/Shaders/RainbowShader.cs b/osu.Framework.Font/Graphics/Shaders/RainbowShader.cs index 8512bac..66460be 100644 --- a/osu.Framework.Font/Graphics/Shaders/RainbowShader.cs +++ b/osu.Framework.Font/Graphics/Shaders/RainbowShader.cs @@ -1,6 +1,7 @@ // Copyright (c) karaoke.dev . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using osu.Framework.Graphics.Rendering; using osuTK; namespace osu.Framework.Graphics.Shaders; @@ -22,7 +23,7 @@ public class RainbowShader : InternalShader, IHasCurrentTime public float Mix { get; set; } = 0.5f; - public override void ApplyValue() + public override void ApplyValue(IRenderer renderer) { var uv = Uv; GetUniform(@"g_Uv").UpdateValue(ref uv); diff --git a/osu.Framework.Font/Graphics/Shaders/RepeatMovingBackgroundShader.cs b/osu.Framework.Font/Graphics/Shaders/RepeatMovingBackgroundShader.cs index 83f8072..8de955c 100644 --- a/osu.Framework.Font/Graphics/Shaders/RepeatMovingBackgroundShader.cs +++ b/osu.Framework.Font/Graphics/Shaders/RepeatMovingBackgroundShader.cs @@ -2,6 +2,7 @@ // See the LICENCE file in the repository root for full licence text. using System; +using osu.Framework.Graphics.Rendering; using osu.Framework.Graphics.Textures; using osuTK; using osuTK.Graphics.ES30; @@ -22,7 +23,7 @@ public class RepeatMovingBackgroundShader : InternalShader, IHasCurrentTime, IHa public float Mix { get; set; } = 1f; - public override void ApplyValue() + public override void ApplyValue(IRenderer renderer) { if (Texture == null) return; diff --git a/osu.Framework.Font/Graphics/Shaders/ShadowShader.cs b/osu.Framework.Font/Graphics/Shaders/ShadowShader.cs index a04ae66..0a520f7 100644 --- a/osu.Framework.Font/Graphics/Shaders/ShadowShader.cs +++ b/osu.Framework.Font/Graphics/Shaders/ShadowShader.cs @@ -3,6 +3,7 @@ using System; using osu.Framework.Graphics.Primitives; +using osu.Framework.Graphics.Rendering; using osuTK; using osuTK.Graphics; @@ -16,7 +17,7 @@ public class ShadowShader : InternalShader, IApplicableToDrawRectangle, IHasText public Vector2 ShadowOffset { get; set; } - public override void ApplyValue() + public override void ApplyValue(IRenderer renderer) { var shadowColour = new Vector4(ShadowColour.R, ShadowColour.G, ShadowColour.B, ShadowColour.A); GetUniform(@"g_Colour").UpdateValue(ref shadowColour); diff --git a/osu.Framework.Font/Graphics/Shaders/StepShader.cs b/osu.Framework.Font/Graphics/Shaders/StepShader.cs index 4f7493f..a7738b9 100644 --- a/osu.Framework.Font/Graphics/Shaders/StepShader.cs +++ b/osu.Framework.Font/Graphics/Shaders/StepShader.cs @@ -5,6 +5,7 @@ using System.Collections.Generic; using System.Linq; using osu.Framework.Graphics.Primitives; +using osu.Framework.Graphics.Rendering; namespace osu.Framework.Graphics.Shaders; @@ -45,7 +46,7 @@ public bool IsLoaded public bool IsBound { get; private set; } - public void ApplyValue() + public void ApplyValue(IRenderer renderer) => throw new NotSupportedException(); public RectangleF ComputeCharacterDrawRectangle(RectangleF originalCharacterDrawRectangle) => From 8037214e2b5be56b5ad9f810a8895705de51e426 Mon Sep 17 00:00:00 2001 From: andy840119 Date: Sun, 19 Mar 2023 10:49:33 +0800 Subject: [PATCH 04/11] Should wrap the shared params into single record for better management. --- .../CustomizedShaderBufferedDrawNode.cs | 31 ++++++++++++++++--- 1 file changed, 27 insertions(+), 4 deletions(-) diff --git a/osu.Framework.Font/Graphics/CustomizedShaderBufferedDrawNode.cs b/osu.Framework.Font/Graphics/CustomizedShaderBufferedDrawNode.cs index 00a08af..a75a54a 100644 --- a/osu.Framework.Font/Graphics/CustomizedShaderBufferedDrawNode.cs +++ b/osu.Framework.Font/Graphics/CustomizedShaderBufferedDrawNode.cs @@ -4,11 +4,12 @@ using System; using System.Linq; using System.Reflection; +using System.Runtime.InteropServices; using osu.Framework.Graphics.Colour; using osu.Framework.Graphics.Primitives; using osu.Framework.Graphics.Rendering; using osu.Framework.Graphics.Shaders; -using osuTK; +using osu.Framework.Graphics.Shaders.Types; using osuTK.Graphics; namespace osu.Framework.Graphics; @@ -46,8 +47,12 @@ protected void ResetDrawVersion() prop.SetValue(SharedData, -1); } + private IUniformBuffer? sharedParametersBuffer; + protected void RenderShader(IRenderer renderer, ICustomizedShader shader, IFrameBuffer current, IFrameBuffer target) { + sharedParametersBuffer ??= renderer.CreateUniformBuffer(); + renderer.SetBlend(BlendingParameters.None); using (BindFrameBuffer(target)) @@ -55,27 +60,45 @@ protected void RenderShader(IRenderer renderer, ICustomizedShader shader, IFrame if (shader is IHasTextureSize) { var size = current.Size; - shader.GetUniform(@"g_TexSize").UpdateValue(ref size); + sharedParametersBuffer.Data = sharedParametersBuffer.Data with + { + TexSize = size + }; } if (shader is IHasInflationPercentage) { var localInflationAmount = DrawInfo.Matrix.ExtractScale().X; - shader.GetUniform(@"g_InflationPercentage").UpdateValue(ref localInflationAmount); + sharedParametersBuffer.Data = sharedParametersBuffer.Data with + { + InflationPercentage = localInflationAmount + }; } if (shader is IHasCurrentTime) { var currentTime = (float)(Source.Clock.CurrentTime - loadTime) / 1000; - shader.GetUniform("g_Time").UpdateValue(ref currentTime); + sharedParametersBuffer.Data = sharedParametersBuffer.Data with + { + Time = currentTime + }; } if (shader is ICustomizedShader customizedShader) customizedShader.ApplyValue(renderer); shader.Bind(); + shader.BindUniformBlock("m_SharedParameters", sharedParametersBuffer); renderer.DrawFrameBuffer(current, new RectangleF(0, 0, current.Texture.Width, current.Texture.Height), ColourInfo.SingleColour(Color4.White)); shader.Unbind(); } } + + [StructLayout(LayoutKind.Sequential, Pack = 1)] + private record struct SharedParameters + { + public UniformVector2 TexSize; + public UniformFloat InflationPercentage; + public UniformFloat Time; + } } From 20484d6299176ef00be0e163e0ad6f38c19e2d80 Mon Sep 17 00:00:00 2001 From: andy840119 Date: Sat, 18 Mar 2023 22:42:53 +0800 Subject: [PATCH 05/11] Implement the BindUniformBlock for able to pass the structure to the shader. --- osu.Framework.Font/Graphics/Shaders/CustomizedShader.cs | 3 +++ osu.Framework.Font/Graphics/Shaders/ICustomizedShader.cs | 7 +++++++ osu.Framework.Font/Graphics/Shaders/StepShader.cs | 3 +++ .../Resources/Shaders/sh_CustomizedShaderGlobalUniforms.h | 8 ++++++++ 4 files changed, 21 insertions(+) create mode 100644 osu.Framework.Font/Resources/Shaders/sh_CustomizedShaderGlobalUniforms.h diff --git a/osu.Framework.Font/Graphics/Shaders/CustomizedShader.cs b/osu.Framework.Font/Graphics/Shaders/CustomizedShader.cs index 1b84c8f..9536fa9 100644 --- a/osu.Framework.Font/Graphics/Shaders/CustomizedShader.cs +++ b/osu.Framework.Font/Graphics/Shaders/CustomizedShader.cs @@ -25,6 +25,9 @@ public void AttachOriginShader(IShader originShader) public Uniform GetUniform(string name) where T : unmanaged, IEquatable => shader.GetUniform(name); + public void BindUniformBlock(string blockName, IUniformBuffer buffer) + => shader.BindUniformBlock(blockName, buffer); + public bool IsLoaded => shader.IsLoaded; public bool IsBound { get; private set; } diff --git a/osu.Framework.Font/Graphics/Shaders/ICustomizedShader.cs b/osu.Framework.Font/Graphics/Shaders/ICustomizedShader.cs index f0ac6f7..45542ee 100644 --- a/osu.Framework.Font/Graphics/Shaders/ICustomizedShader.cs +++ b/osu.Framework.Font/Graphics/Shaders/ICustomizedShader.cs @@ -37,4 +37,11 @@ public interface ICustomizedShader /// The retrieved uniform. Uniform GetUniform(string name) where T : unmanaged, IEquatable; + + /// + /// Binds an to a uniform block of the given name. + /// + /// The uniform block name. + /// The buffer to bind to the block. + void BindUniformBlock(string blockName, IUniformBuffer buffer); } diff --git a/osu.Framework.Font/Graphics/Shaders/StepShader.cs b/osu.Framework.Font/Graphics/Shaders/StepShader.cs index a7738b9..08a9bb5 100644 --- a/osu.Framework.Font/Graphics/Shaders/StepShader.cs +++ b/osu.Framework.Font/Graphics/Shaders/StepShader.cs @@ -41,6 +41,9 @@ public void Unbind() public Uniform GetUniform(string name) where T : unmanaged, IEquatable => throw new NotSupportedException(); + public void BindUniformBlock(string blockName, IUniformBuffer buffer) + => throw new NotSupportedException(); + public bool IsLoaded => throw new NotSupportedException(); diff --git a/osu.Framework.Font/Resources/Shaders/sh_CustomizedShaderGlobalUniforms.h b/osu.Framework.Font/Resources/Shaders/sh_CustomizedShaderGlobalUniforms.h new file mode 100644 index 0000000..dc4893c --- /dev/null +++ b/osu.Framework.Font/Resources/Shaders/sh_CustomizedShaderGlobalUniforms.h @@ -0,0 +1,8 @@ +// Should include this file if is customized shader. + +layout(std140, set = 0, binding = 0) uniform m_SharedParameters +{ + mediump vec2 g_TexSize; + float g_InflationPercentage; + mediump float g_Time; +}; \ No newline at end of file From 3fb62888a31c02691bc1c39bd798c74d0f11a122 Mon Sep 17 00:00:00 2001 From: andy840119 Date: Sat, 18 Mar 2023 23:13:12 +0800 Subject: [PATCH 06/11] Fix the outline shader. Co-authored-by: WebFreak001 --- .../Shaders/OutlineShaderTest.cs | 10 +- .../Graphics/Shaders/OutlineShader.cs | 29 +++-- .../Resources/Shaders/sh_Outline.fs | 112 ++++++++++-------- 3 files changed, 88 insertions(+), 63 deletions(-) diff --git a/osu.Framework.Font.Tests/Shaders/OutlineShaderTest.cs b/osu.Framework.Font.Tests/Shaders/OutlineShaderTest.cs index 0f8dcc5..7b4e44a 100644 --- a/osu.Framework.Font.Tests/Shaders/OutlineShaderTest.cs +++ b/osu.Framework.Font.Tests/Shaders/OutlineShaderTest.cs @@ -52,19 +52,19 @@ public void CreateGetOutlineMethod(int samples) const float pi = 3.14159265359f; double angle = 0.0f; - Console.WriteLine("lowp float outlineAlpha(sampler2D tex, float radius, mediump vec2 texCoord, mediump vec2 texSize)"); + Console.WriteLine("lowp float outlineAlpha(in float radius, in mediump vec2 texCoord, in mediump vec2 texSize)"); Console.WriteLine("{"); - Console.WriteLine(" mediump vec2 offset = mediump vec2(radius) / texSize;"); - Console.WriteLine(" lowp float alpha = 0.0;"); + Console.WriteLine(" mediump vec2 offset = vec2(radius) / texSize;"); + Console.WriteLine(" lowp float alpha = 0.0;"); Console.WriteLine(); for (int i = 0; i < samples; i++) { angle += 1.0 / (samples / 2.0) * pi; - Console.WriteLine($" alpha = max(alpha, texture2D(tex, texCoord - lowp vec2({Math.Sin(angle):N2}, {Math.Cos(angle):N2}) * offset).a);"); + Console.WriteLine($" alpha = max(alpha, tex(texCoord - vec2({Math.Sin(angle):N2}, {Math.Cos(angle):N2}) * offset).a);"); } - Console.WriteLine(" return alpha;"); + Console.WriteLine(" return alpha;"); Console.WriteLine("}"); } } diff --git a/osu.Framework.Font/Graphics/Shaders/OutlineShader.cs b/osu.Framework.Font/Graphics/Shaders/OutlineShader.cs index 75ea736..ef854c9 100644 --- a/osu.Framework.Font/Graphics/Shaders/OutlineShader.cs +++ b/osu.Framework.Font/Graphics/Shaders/OutlineShader.cs @@ -2,8 +2,10 @@ // See the LICENCE file in the repository root for full licence text. using System; +using System.Runtime.InteropServices; using osu.Framework.Graphics.Primitives; using osu.Framework.Graphics.Rendering; +using osu.Framework.Graphics.Shaders.Types; using osuTK; using osuTK.Graphics; @@ -15,20 +17,24 @@ public class OutlineShader : InternalShader, IApplicableToCharacterSize, IApplic public Color4 Colour { get; set; } + public Color4 OutlineColour { get; set; } + public float Radius { get; set; } - public Color4 OutlineColour { get; set; } + private IUniformBuffer? outlineParametersBuffer; public override void ApplyValue(IRenderer renderer) { - var colourMatrix = new Vector4(Colour.R, Colour.G, Colour.B, Colour.A); - GetUniform(@"g_Colour").UpdateValue(ref colourMatrix); + outlineParametersBuffer ??= renderer.CreateUniformBuffer(); - float radius = Radius; - GetUniform(@"g_Radius").UpdateValue(ref radius); + outlineParametersBuffer.Data = new OutlineParameters + { + Colour = new Vector4(Colour.R, Colour.G, Colour.B, Colour.A), + OutlineColour = new Vector4(OutlineColour.R, OutlineColour.G, OutlineColour.B, OutlineColour.A), + Radius = Radius, + }; - var outlineColourMatrix = new Vector4(OutlineColour.R, OutlineColour.G, OutlineColour.B, OutlineColour.A); - GetUniform(@"g_OutlineColour").UpdateValue(ref outlineColourMatrix); + BindUniformBlock("m_OutlineParameters", outlineParametersBuffer); } public RectangleF ComputeCharacterDrawRectangle(RectangleF originalCharacterDrawRectangle) @@ -36,4 +42,13 @@ public RectangleF ComputeCharacterDrawRectangle(RectangleF originalCharacterDraw public RectangleF ComputeDrawRectangle(RectangleF originDrawRectangle) => ComputeCharacterDrawRectangle(originDrawRectangle); + + [StructLayout(LayoutKind.Sequential, Pack = 1)] + private record struct OutlineParameters + { + public UniformVector4 Colour; + public UniformVector4 OutlineColour; + public UniformFloat Radius; + private readonly UniformPadding12 pad1; + } } diff --git a/osu.Framework.Font/Resources/Shaders/sh_Outline.fs b/osu.Framework.Font/Resources/Shaders/sh_Outline.fs index efab411..be9c7b6 100644 --- a/osu.Framework.Font/Resources/Shaders/sh_Outline.fs +++ b/osu.Framework.Font/Resources/Shaders/sh_Outline.fs @@ -1,66 +1,76 @@ +#include "sh_CustomizedShaderGlobalUniforms.h" #include "sh_Utils.h" -varying mediump vec2 v_TexCoord; +layout(location = 2) in highp vec2 v_TexCoord; -uniform lowp sampler2D m_Sampler; +layout(std140, set = 2, binding = 0) uniform m_OutlineParameters +{ + mediump vec4 g_Colour; + mediump vec4 g_OutlineColour; + mediump float g_Radius; +}; + +layout(set = 1, binding = 0) uniform lowp texture2D m_Texture; +layout(set = 1, binding = 1) uniform lowp sampler m_Sampler; + +layout(location = 0) out vec4 o_Colour; -uniform mediump vec2 g_TexSize; -uniform vec4 g_Colour; -uniform float g_Radius; -uniform vec4 g_OutlineColour; -uniform float g_InflationPercentage; +mediump vec4 tex(in mediump vec2 texCoord) +{ + return texture(sampler2D(m_Texture, m_Sampler), texCoord); +} -lowp float outlineAlpha(sampler2D tex, float radius, mediump vec2 texCoord, mediump vec2 texSize) +lowp float outlineAlpha(in float radius, in mediump vec2 texCoord, in mediump vec2 texSize) { - mediump vec2 offset = mediump vec2(radius) / texSize; - lowp float alpha = 0.0; + mediump vec2 offset = vec2(radius) / texSize; + lowp float alpha = 0.0; - alpha = max(alpha, texture2D(tex, texCoord - lowp vec2(0.20, 0.98) * offset).a); - alpha = max(alpha, texture2D(tex, texCoord - lowp vec2(0.38, 0.92) * offset).a); - alpha = max(alpha, texture2D(tex, texCoord - lowp vec2(0.56, 0.83) * offset).a); - alpha = max(alpha, texture2D(tex, texCoord - lowp vec2(0.71, 0.71) * offset).a); - alpha = max(alpha, texture2D(tex, texCoord - lowp vec2(0.83, 0.56) * offset).a); - alpha = max(alpha, texture2D(tex, texCoord - lowp vec2(0.92, 0.38) * offset).a); - alpha = max(alpha, texture2D(tex, texCoord - lowp vec2(0.98, 0.20) * offset).a); - alpha = max(alpha, texture2D(tex, texCoord - lowp vec2(1.00, -0.00) * offset).a); - alpha = max(alpha, texture2D(tex, texCoord - lowp vec2(0.98, -0.20) * offset).a); - alpha = max(alpha, texture2D(tex, texCoord - lowp vec2(0.92, -0.38) * offset).a); - alpha = max(alpha, texture2D(tex, texCoord - lowp vec2(0.83, -0.56) * offset).a); - alpha = max(alpha, texture2D(tex, texCoord - lowp vec2(0.71, -0.71) * offset).a); - alpha = max(alpha, texture2D(tex, texCoord - lowp vec2(0.56, -0.83) * offset).a); - alpha = max(alpha, texture2D(tex, texCoord - lowp vec2(0.38, -0.92) * offset).a); - alpha = max(alpha, texture2D(tex, texCoord - lowp vec2(0.20, -0.98) * offset).a); - alpha = max(alpha, texture2D(tex, texCoord - lowp vec2(-0.00, -1.00) * offset).a); - alpha = max(alpha, texture2D(tex, texCoord - lowp vec2(-0.20, -0.98) * offset).a); - alpha = max(alpha, texture2D(tex, texCoord - lowp vec2(-0.38, -0.92) * offset).a); - alpha = max(alpha, texture2D(tex, texCoord - lowp vec2(-0.56, -0.83) * offset).a); - alpha = max(alpha, texture2D(tex, texCoord - lowp vec2(-0.71, -0.71) * offset).a); - alpha = max(alpha, texture2D(tex, texCoord - lowp vec2(-0.83, -0.56) * offset).a); - alpha = max(alpha, texture2D(tex, texCoord - lowp vec2(-0.92, -0.38) * offset).a); - alpha = max(alpha, texture2D(tex, texCoord - lowp vec2(-0.98, -0.20) * offset).a); - alpha = max(alpha, texture2D(tex, texCoord - lowp vec2(-1.00, 0.00) * offset).a); - alpha = max(alpha, texture2D(tex, texCoord - lowp vec2(-0.98, 0.20) * offset).a); - alpha = max(alpha, texture2D(tex, texCoord - lowp vec2(-0.92, 0.38) * offset).a); - alpha = max(alpha, texture2D(tex, texCoord - lowp vec2(-0.83, 0.56) * offset).a); - alpha = max(alpha, texture2D(tex, texCoord - lowp vec2(-0.71, 0.71) * offset).a); - alpha = max(alpha, texture2D(tex, texCoord - lowp vec2(-0.56, 0.83) * offset).a); - alpha = max(alpha, texture2D(tex, texCoord - lowp vec2(-0.38, 0.92) * offset).a); - alpha = max(alpha, texture2D(tex, texCoord - lowp vec2(-0.20, 0.98) * offset).a); - alpha = max(alpha, texture2D(tex, texCoord - lowp vec2(0.00, 1.00) * offset).a); - return alpha; + alpha = max(alpha, tex(texCoord - vec2(0.20, 0.98) * offset).a); + alpha = max(alpha, tex(texCoord - vec2(0.38, 0.92) * offset).a); + alpha = max(alpha, tex(texCoord - vec2(0.56, 0.83) * offset).a); + alpha = max(alpha, tex(texCoord - vec2(0.71, 0.71) * offset).a); + alpha = max(alpha, tex(texCoord - vec2(0.83, 0.56) * offset).a); + alpha = max(alpha, tex(texCoord - vec2(0.92, 0.38) * offset).a); + alpha = max(alpha, tex(texCoord - vec2(0.98, 0.20) * offset).a); + alpha = max(alpha, tex(texCoord - vec2(1.00, -0.00) * offset).a); + alpha = max(alpha, tex(texCoord - vec2(0.98, -0.20) * offset).a); + alpha = max(alpha, tex(texCoord - vec2(0.92, -0.38) * offset).a); + alpha = max(alpha, tex(texCoord - vec2(0.83, -0.56) * offset).a); + alpha = max(alpha, tex(texCoord - vec2(0.71, -0.71) * offset).a); + alpha = max(alpha, tex(texCoord - vec2(0.56, -0.83) * offset).a); + alpha = max(alpha, tex(texCoord - vec2(0.38, -0.92) * offset).a); + alpha = max(alpha, tex(texCoord - vec2(0.20, -0.98) * offset).a); + alpha = max(alpha, tex(texCoord - vec2(-0.00, -1.00) * offset).a); + alpha = max(alpha, tex(texCoord - vec2(-0.20, -0.98) * offset).a); + alpha = max(alpha, tex(texCoord - vec2(-0.38, -0.92) * offset).a); + alpha = max(alpha, tex(texCoord - vec2(-0.56, -0.83) * offset).a); + alpha = max(alpha, tex(texCoord - vec2(-0.71, -0.71) * offset).a); + alpha = max(alpha, tex(texCoord - vec2(-0.83, -0.56) * offset).a); + alpha = max(alpha, tex(texCoord - vec2(-0.92, -0.38) * offset).a); + alpha = max(alpha, tex(texCoord - vec2(-0.98, -0.20) * offset).a); + alpha = max(alpha, tex(texCoord - vec2(-1.00, 0.00) * offset).a); + alpha = max(alpha, tex(texCoord - vec2(-0.98, 0.20) * offset).a); + alpha = max(alpha, tex(texCoord - vec2(-0.92, 0.38) * offset).a); + alpha = max(alpha, tex(texCoord - vec2(-0.83, 0.56) * offset).a); + alpha = max(alpha, tex(texCoord - vec2(-0.71, 0.71) * offset).a); + alpha = max(alpha, tex(texCoord - vec2(-0.56, 0.83) * offset).a); + alpha = max(alpha, tex(texCoord - vec2(-0.38, 0.92) * offset).a); + alpha = max(alpha, tex(texCoord - vec2(-0.20, 0.98) * offset).a); + alpha = max(alpha, tex(texCoord - vec2(0.00, 1.00) * offset).a); + return alpha; } -lowp vec4 outline(sampler2D tex, float radius, mediump vec2 texCoord, mediump vec2 texSize, mediump vec4 colour) +lowp vec4 outline(float radius, mediump vec2 texCoord, mediump vec2 texSize, mediump vec4 colour) { - lowp float outlineAlpha = max(outlineAlpha(tex, radius, texCoord, texSize), outlineAlpha(tex, radius / 2.0, texCoord, texSize)); - return mix(vec4(0.0), colour, outlineAlpha); + lowp float res = max(outlineAlpha(radius, texCoord, texSize), outlineAlpha(radius / 2.0, texCoord, texSize)); + return mix(vec4(0.0), colour, res); } void main(void) { - lowp vec4 sample = toSRGB(texture2D(m_Sampler, v_TexCoord)); - lowp vec4 originColur = vec4(mix(sample.rgb, g_Colour.rgb, g_Colour.a), sample.a); - lowp vec4 outlineColour = outline(m_Sampler, g_Radius * g_InflationPercentage, v_TexCoord, g_TexSize, g_OutlineColour); + lowp vec4 texColour = toSRGB(texture(sampler2D(m_Texture, m_Sampler), v_TexCoord)); + lowp vec4 originColour = vec4(mix(texColour.rgb, g_Colour.rgb, g_Colour.a), texColour.a); + lowp vec4 outlineColour = outline(g_Radius * g_InflationPercentage, v_TexCoord, g_TexSize, g_OutlineColour); - gl_FragColor = mix(outlineColour, originColur, originColur.a); -} \ No newline at end of file + o_Colour = mix(outlineColour, originColour, originColour.a); +} From 6c094528de12da13dd2f1569b53e9f0a5aaca6d1 Mon Sep 17 00:00:00 2001 From: andy840119 Date: Sun, 19 Mar 2023 10:00:58 +0800 Subject: [PATCH 07/11] Fix the pixel shader. Co-authored-by: WebFreak001 --- .../Graphics/Shaders/PixelShader.cs | 18 ++++++++++++++++-- .../Resources/Shaders/sh_Pixel.fs | 16 ++++++++++------ 2 files changed, 26 insertions(+), 8 deletions(-) diff --git a/osu.Framework.Font/Graphics/Shaders/PixelShader.cs b/osu.Framework.Font/Graphics/Shaders/PixelShader.cs index bb60337..aa63105 100644 --- a/osu.Framework.Font/Graphics/Shaders/PixelShader.cs +++ b/osu.Framework.Font/Graphics/Shaders/PixelShader.cs @@ -1,7 +1,9 @@ // Copyright (c) karaoke.dev . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using System.Runtime.InteropServices; using osu.Framework.Graphics.Rendering; +using osu.Framework.Graphics.Shaders.Types; using osuTK; namespace osu.Framework.Graphics.Shaders; @@ -12,9 +14,21 @@ public class PixelShader : InternalShader, IHasTextureSize, IHasInflationPercent public Vector2 Size { get; set; } = new(5); + private IUniformBuffer? pixelParametersBuffer; + public override void ApplyValue(IRenderer renderer) { - var size = Size; - GetUniform(@"g_Size").UpdateValue(ref size); + pixelParametersBuffer ??= renderer.CreateUniformBuffer(); + + pixelParametersBuffer.Data = new PixelParameters { Size = Size }; + + BindUniformBlock("m_PixelParameters", pixelParametersBuffer); + } + + [StructLayout(LayoutKind.Sequential, Pack = 1)] + private record struct PixelParameters + { + public UniformVector2 Size; + private readonly UniformPadding8 pad1; } } diff --git a/osu.Framework.Font/Resources/Shaders/sh_Pixel.fs b/osu.Framework.Font/Resources/Shaders/sh_Pixel.fs index 5ca9f70..0cec5f6 100644 --- a/osu.Framework.Font/Resources/Shaders/sh_Pixel.fs +++ b/osu.Framework.Font/Resources/Shaders/sh_Pixel.fs @@ -1,14 +1,18 @@ // see the demo: https://www.geeks3d.com/20101029/shader-library-pixelation-post-processing-effect-glsl/ +#include "sh_CustomizedShaderGlobalUniforms.h" #include "sh_Utils.h" -varying mediump vec2 v_TexCoord; +layout(location = 2) in mediump vec2 v_TexCoord; -uniform lowp sampler2D m_Sampler; +layout(std140, set = 2, binding = 0) uniform m_PixelParameters +{ + mediump vec2 g_Size; +}; -uniform mediump vec2 g_TexSize; -uniform mediump vec2 g_Size; -uniform float g_InflationPercentage; +layout(set = 1, binding = 0) uniform lowp texture2D m_Texture; +layout(set = 1, binding = 1) uniform lowp sampler m_Sampler; +layout(location = 0) out vec4 o_Colour; void main(void) { @@ -17,5 +21,5 @@ void main(void) uv = uv * separaorParts; uv = floor(uv); uv = uv / separaorParts; - gl_FragColor = toSRGB(texture2D(m_Sampler, uv)); + o_Colour = toSRGB(texture(sampler2D(m_Texture, m_Sampler), uv)); } \ No newline at end of file From cab33aef08729838584bc37ab3d4ca977955ee84 Mon Sep 17 00:00:00 2001 From: andy840119 Date: Sun, 19 Mar 2023 11:07:07 +0800 Subject: [PATCH 08/11] Fix the rainbow shader. Co-authored-by: WebFreak001 --- .../Graphics/Shaders/RainbowShader.cs | 44 ++++++++++++------- .../Resources/Shaders/sh_Rainbow.fs | 39 +++++++++------- 2 files changed, 50 insertions(+), 33 deletions(-) diff --git a/osu.Framework.Font/Graphics/Shaders/RainbowShader.cs b/osu.Framework.Font/Graphics/Shaders/RainbowShader.cs index 66460be..2d7e123 100644 --- a/osu.Framework.Font/Graphics/Shaders/RainbowShader.cs +++ b/osu.Framework.Font/Graphics/Shaders/RainbowShader.cs @@ -1,7 +1,9 @@ // Copyright (c) karaoke.dev . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using System.Runtime.InteropServices; using osu.Framework.Graphics.Rendering; +using osu.Framework.Graphics.Shaders.Types; using osuTK; namespace osu.Framework.Graphics.Shaders; @@ -23,24 +25,34 @@ public class RainbowShader : InternalShader, IHasCurrentTime public float Mix { get; set; } = 0.5f; + private IUniformBuffer? rainbowParametersBuffer; + public override void ApplyValue(IRenderer renderer) { - var uv = Uv; - GetUniform(@"g_Uv").UpdateValue(ref uv); - - var speed = Speed; - GetUniform(@"g_Speed").UpdateValue(ref speed); - - var saturation = Saturation; - GetUniform(@"g_Saturation").UpdateValue(ref saturation); - - var brightness = Brightness; - GetUniform(@"g_Brightness").UpdateValue(ref brightness); - - var section = Section; - GetUniform(@"g_Section").UpdateValue(ref section); + rainbowParametersBuffer ??= renderer.CreateUniformBuffer(); + + rainbowParametersBuffer.Data = new RainbowParameters + { + Uv = Uv, + Speed = Speed, + Saturation = Saturation, + Brightness = Brightness, + Section = Section, + Mix = Mix, + }; + + BindUniformBlock("m_RainbowParameters", rainbowParametersBuffer); + } - var mix = Mix; - GetUniform(@"g_Mix").UpdateValue(ref mix); + [StructLayout(LayoutKind.Sequential, Pack = 1)] + private record struct RainbowParameters + { + public UniformVector2 Uv; + public UniformFloat Speed; + public UniformFloat Saturation; + public UniformFloat Brightness; + public UniformFloat Section; + public UniformFloat Mix; + private readonly UniformPadding4 pad1; } } diff --git a/osu.Framework.Font/Resources/Shaders/sh_Rainbow.fs b/osu.Framework.Font/Resources/Shaders/sh_Rainbow.fs index 909c25f..892abea 100644 --- a/osu.Framework.Font/Resources/Shaders/sh_Rainbow.fs +++ b/osu.Framework.Font/Resources/Shaders/sh_Rainbow.fs @@ -1,26 +1,31 @@ // see the demo: https://developer.amazon.com/es/blogs/appstore/post/acefafad-29ba-4f31-8dae-00805fda3f58/intro-to-shaders-and-surfaces-with-gamemaker-studio-2 +#include "sh_CustomizedShaderGlobalUniforms.h" #include "sh_Utils.h" -varying vec2 v_TexCoord; -varying vec4 v_Colour; +layout(location = 2) in highp vec2 v_TexCoord; -uniform lowp sampler2D m_Sampler; +layout(std140, set = 2, binding = 0) uniform m_RainbowParameters +{ + highp vec2 g_Uv; + mediump float g_Speed; + mediump float g_Saturation; + mediump float g_Brightness; + mediump float g_Section; + mediump float g_Mix; +}; + +layout(set = 1, binding = 0) uniform lowp texture2D m_Texture; +layout(set = 1, binding = 1) uniform lowp sampler m_Sampler; -uniform vec2 g_Uv; -uniform float g_Speed; -uniform float g_Time; -uniform float g_Saturation; -uniform float g_Brightness; -uniform float g_Section; -uniform float g_Mix; +layout(location = 0) out vec4 o_Colour; void main(void) { - float pos = (v_TexCoord.y - g_Uv[0]) / (g_Uv[1] - g_Uv[0]); - vec4 texColor = toSRGB(texture2D(m_Sampler, v_TexCoord)); - - vec4 col = vec4(g_Section * ((g_Time * g_Speed) + pos), g_Saturation, g_Brightness, 1); - vec4 finalCol = mix(texColor, vec4(hsv2rgb(col).xyz, texColor.a), g_Mix); - - gl_FragColor = finalCol; + float pos = (v_TexCoord.y - g_Uv[0]) / (g_Uv[1] - g_Uv[0]); + vec4 texColor = toSRGB(texture(sampler2D(m_Texture, m_Sampler), v_TexCoord)); + + vec4 col = vec4(g_Section * ((g_Time * g_Speed) + pos), g_Saturation, g_Brightness, 1); + vec4 finalCol = mix(texColor, vec4(hsv2rgb(col).xyz, texColor.a), g_Mix); + + o_Colour = finalCol; } \ No newline at end of file From 3d2faa4a45fc2fcb5f8691ecdef8c5306c7e9b27 Mon Sep 17 00:00:00 2001 From: andy840119 Date: Sun, 19 Mar 2023 14:53:06 +0800 Subject: [PATCH 09/11] Fix the repeat moving background shader. Co-authored-by: WebFreak001 --- .../Shaders/RepeatMovingBackgroundShader.cs | 49 ++++++++++++------- .../Shaders/sh_RepeatMovingBackground.fs | 45 +++++++++-------- 2 files changed, 54 insertions(+), 40 deletions(-) diff --git a/osu.Framework.Font/Graphics/Shaders/RepeatMovingBackgroundShader.cs b/osu.Framework.Font/Graphics/Shaders/RepeatMovingBackgroundShader.cs index 8de955c..0660201 100644 --- a/osu.Framework.Font/Graphics/Shaders/RepeatMovingBackgroundShader.cs +++ b/osu.Framework.Font/Graphics/Shaders/RepeatMovingBackgroundShader.cs @@ -2,10 +2,11 @@ // See the LICENCE file in the repository root for full licence text. using System; +using System.Runtime.InteropServices; using osu.Framework.Graphics.Rendering; +using osu.Framework.Graphics.Shaders.Types; using osu.Framework.Graphics.Textures; using osuTK; -using osuTK.Graphics.ES30; namespace osu.Framework.Graphics.Shaders; @@ -23,32 +24,42 @@ public class RepeatMovingBackgroundShader : InternalShader, IHasCurrentTime, IHa public float Mix { get; set; } = 1f; + private IUniformBuffer? repeatParametersBuffer; + public override void ApplyValue(IRenderer renderer) { if (Texture == null) return; - Texture.Bind(1); - - var unitId = TextureUnit.Texture1 - TextureUnit.Texture0; - GetUniform(@"g_RepeatSample").UpdateValue(ref unitId); - - var textureCoord = Texture.GetTextureRect().TopLeft; - GetUniform(@"g_RepeatSampleCoord").UpdateValue(ref textureCoord); + // todo: think about how to upload the texture. + // Texture.Bind(1); + // var unitId = TextureUnit.Texture1 - TextureUnit.Texture0; + // GetUniform(@"g_RepeatSample").UpdateValue(ref unitId); - var textureSize = Texture.GetTextureRect().Size; - GetUniform(@"g_RepeatSampleSize").UpdateValue(ref textureSize); + repeatParametersBuffer ??= renderer.CreateUniformBuffer(); - var textureDisplaySize = TextureDisplaySize; - GetUniform("g_DisplaySize").UpdateValue(ref textureDisplaySize); + repeatParametersBuffer.Data = new RepeatParameters + { + RepeatSampleCoord = Texture.GetTextureRect().TopLeft, + RepeatSampleSize = Texture.GetTextureRect().Size, + DisplaySize = TextureDisplaySize, + DisplayBorder = TextureDisplayBorder, + Speed = Speed, + Mix = Math.Clamp(Mix, 0, 1) + }; - var textureDisplayBorder = TextureDisplayBorder; - GetUniform("g_DisplayBorder").UpdateValue(ref textureDisplayBorder); - - var speed = Speed; - GetUniform("g_Speed").UpdateValue(ref speed); + BindUniformBlock("m_RepeatMovingBackgroundParameters", repeatParametersBuffer); + } - var mix = Math.Clamp(Mix, 0, 1); - GetUniform(@"g_Mix").UpdateValue(ref mix); + [StructLayout(LayoutKind.Sequential, Pack = 1)] + private record struct RepeatParameters + { + public UniformVector2 RepeatSampleCoord; + public UniformVector2 RepeatSampleSize; + public UniformVector2 DisplaySize; + public UniformVector2 DisplayBorder; + public UniformVector2 Speed; + public UniformFloat Mix; + private UniformPadding4 pad1; } } diff --git a/osu.Framework.Font/Resources/Shaders/sh_RepeatMovingBackground.fs b/osu.Framework.Font/Resources/Shaders/sh_RepeatMovingBackground.fs index f651335..cdfccc5 100644 --- a/osu.Framework.Font/Resources/Shaders/sh_RepeatMovingBackground.fs +++ b/osu.Framework.Font/Resources/Shaders/sh_RepeatMovingBackground.fs @@ -1,40 +1,43 @@ // see : https://github.com/kiwipxl/GLSL-shaders/blob/master/repeat.glsl +#include "sh_CustomizedShaderGlobalUniforms.h" #include "sh_Utils.h" -varying vec2 v_TexCoord; -varying vec4 v_Colour; -varying mediump vec4 v_TexRect; +layout(location = 1) in lowp vec4 v_Colour; +layout(location = 2) in highp vec2 v_TexCoord; +layout(location = 3) in highp vec4 v_TexRect; -uniform lowp sampler2D m_Sampler; +layout(set = 2, binding = 0) uniform lowp texture2D m_RepeatTexture; +layout(set = 2, binding = 1) uniform lowp sampler m_RepeatSampler; -uniform mediump vec2 g_TexSize; -uniform lowp sampler2D g_RepeatSample; -uniform vec2 g_RepeatSampleCoord; -uniform vec2 g_RepeatSampleSize; -uniform vec2 g_DisplaySize; -uniform vec2 g_DisplayBorder; -uniform vec2 g_Speed; -uniform float g_Time; -uniform float g_Mix; +layout(std140, set = 3, binding = 0) uniform m_RepeatMovingBackgroundParameters +{ + mediump vec2 g_RepeatSampleCoord; + mediump vec2 g_RepeatSampleSize; + mediump vec2 g_DisplaySize; + mediump vec2 g_DisplayBorder; + mediump vec2 g_Speed; + mediump float g_Mix; +}; -float mod(float a, int b) { - return a - (float(b) * floor(a/float(b))); -} +layout(set = 1, binding = 0) uniform lowp texture2D m_Texture; +layout(set = 1, binding = 1) uniform lowp sampler m_Sampler; + +layout(location = 0) out vec4 o_Colour; void main(void) { // calculate how many times texture should be repeated. vec2 repeat = g_TexSize / (g_DisplaySize + g_DisplayBorder); // get the repeat texture coordinate. - float repeatTexCoordX = mod(v_TexCoord.x * repeat.x + g_Speed.x * g_Time, 1); - float repeatTexCoordY = mod(v_TexCoord.y * repeat.y + g_Speed.y * g_Time, 1); + float repeatTexCoordX = mod(v_TexCoord.x * repeat.x + g_Speed.x * g_Time, 1.0); + float repeatTexCoordY = mod(v_TexCoord.y * repeat.y + g_Speed.y * g_Time, 1.0); vec2 repeatTexCoord = vec2(repeatTexCoordX, repeatTexCoordY) / g_DisplaySize * (g_DisplaySize + g_DisplayBorder); // because repeat texture will be the size of 1024*1024, so should make a conversion to get the target area of the texture. vec2 fixedTexCoord = repeatTexCoord * g_RepeatSampleSize + g_RepeatSampleCoord; // get point colour from sample. - vec4 texColor = texture2D(m_Sampler, v_TexCoord); - vec4 repeatSampleColor = v_Colour * vec4(texture2D(g_RepeatSample, fixedTexCoord).xyz, texColor.a); - gl_FragColor = toSRGB(mix(texColor, repeatSampleColor, g_Mix)); + vec4 texColor = texture(sampler2D(m_Texture, m_Sampler), v_TexCoord); + vec4 repeatSampleColor = v_Colour * vec4(texture(sampler2D(m_RepeatTexture, m_RepeatSampler), fixedTexCoord).xyz, texColor.a); + o_Colour = toSRGB(mix(texColor, repeatSampleColor, g_Mix)); } From 537648abffe76e2547f4660369165967dcdf617f Mon Sep 17 00:00:00 2001 From: andy840119 Date: Sun, 19 Mar 2023 15:47:20 +0800 Subject: [PATCH 10/11] Fix the shadow shader. Co-authored-by: WebFreak001 --- .../Graphics/Shaders/ShadowShader.cs | 24 ++++++++++++++--- .../Resources/Shaders/sh_Shadow.fs | 27 +++++++++++-------- 2 files changed, 37 insertions(+), 14 deletions(-) diff --git a/osu.Framework.Font/Graphics/Shaders/ShadowShader.cs b/osu.Framework.Font/Graphics/Shaders/ShadowShader.cs index 0a520f7..71cf3b8 100644 --- a/osu.Framework.Font/Graphics/Shaders/ShadowShader.cs +++ b/osu.Framework.Font/Graphics/Shaders/ShadowShader.cs @@ -2,8 +2,10 @@ // See the LICENCE file in the repository root for full licence text. using System; +using System.Runtime.InteropServices; using osu.Framework.Graphics.Primitives; using osu.Framework.Graphics.Rendering; +using osu.Framework.Graphics.Shaders.Types; using osuTK; using osuTK.Graphics; @@ -17,13 +19,21 @@ public class ShadowShader : InternalShader, IApplicableToDrawRectangle, IHasText public Vector2 ShadowOffset { get; set; } + private IUniformBuffer? shadowParametersBuffer; + public override void ApplyValue(IRenderer renderer) { - var shadowColour = new Vector4(ShadowColour.R, ShadowColour.G, ShadowColour.B, ShadowColour.A); - GetUniform(@"g_Colour").UpdateValue(ref shadowColour); + shadowParametersBuffer ??= renderer.CreateUniformBuffer(); + var shadowColour = new Vector4(ShadowColour.R, ShadowColour.G, ShadowColour.B, ShadowColour.A); var shadowOffset = new Vector2(-ShadowOffset.X, ShadowOffset.Y); - GetUniform(@"g_Offset").UpdateValue(ref shadowOffset); + shadowParametersBuffer.Data = new ShadowParameters + { + Colour = shadowColour, + Offset = shadowOffset, + }; + + BindUniformBlock("m_ShadowParameters", shadowParametersBuffer); } public RectangleF ComputeDrawRectangle(RectangleF originDrawRectangle) @@ -34,4 +44,12 @@ public RectangleF ComputeDrawRectangle(RectangleF originDrawRectangle) Top = Math.Max(-ShadowOffset.Y, 0), Bottom = Math.Max(ShadowOffset.Y, 0), }); + + [StructLayout(LayoutKind.Sequential, Pack = 1)] + private record struct ShadowParameters + { + public UniformVector4 Colour; + public UniformVector2 Offset; + private UniformPadding8 pad1; + } } diff --git a/osu.Framework.Font/Resources/Shaders/sh_Shadow.fs b/osu.Framework.Font/Resources/Shaders/sh_Shadow.fs index a82b882..d150a29 100644 --- a/osu.Framework.Font/Resources/Shaders/sh_Shadow.fs +++ b/osu.Framework.Font/Resources/Shaders/sh_Shadow.fs @@ -1,22 +1,27 @@ +#include "sh_CustomizedShaderGlobalUniforms.h" #include "sh_Utils.h" -varying mediump vec2 v_TexCoord; +layout(location = 2) in highp vec2 v_TexCoord; -uniform lowp sampler2D m_Sampler; +layout(std140, set = 2, binding = 0) uniform m_ShadowParameters +{ + mediump vec4 g_Colour; + mediump vec2 g_Offset; +}; + +layout(set = 1, binding = 0) uniform lowp texture2D m_Texture; +layout(set = 1, binding = 1) uniform lowp sampler m_Sampler; -uniform mediump vec2 g_TexSize; -uniform vec4 g_Colour; -uniform vec2 g_Offset; -uniform float g_InflationPercentage; +layout(location = 0) out vec4 o_Colour; -lowp vec4 shadow(sampler2D tex, mediump vec2 texCoord, mediump vec2 texSize, mediump vec4 colour, mediump vec2 offset) +lowp vec4 shadow(texture2D tex, mediump vec2 texCoord, mediump vec2 texSize, mediump vec4 colour, mediump vec2 offset) { - return texture2D(tex, texCoord + offset / texSize).a * colour; + return texture(sampler2D(tex, m_Sampler), texCoord + offset / texSize).a * colour; } void main(void) { - lowp vec4 texture = toSRGB(texture2D(m_Sampler, v_TexCoord)); - lowp vec4 shadow = shadow(m_Sampler, v_TexCoord, g_TexSize, g_Colour, g_Offset * g_InflationPercentage); - gl_FragColor = mix(shadow, texture, texture.a); + lowp vec4 texture = toSRGB(texture(sampler2D(m_Texture, m_Sampler), v_TexCoord)); + lowp vec4 shadow = shadow(m_Texture, v_TexCoord, g_TexSize, g_Colour, g_Offset * g_InflationPercentage); + o_Colour = mix(shadow, texture, texture.a); } \ No newline at end of file From c0fa63f0cb75a4a3b5d4222ebcd4db51c2a0ad82 Mon Sep 17 00:00:00 2001 From: andy840119 Date: Sun, 19 Mar 2023 19:50:54 +0800 Subject: [PATCH 11/11] Add Framework which provides a test runner with resources from the test project. And note that this runner only create if not open the visual test windows. --- .../Visual/BackgroundGridTestScene.cs | 3 +-- .../Visual/FrameworkTestScene.cs | 18 ++++++++++++++++++ .../Visual/FrameworkTestSceneTestRunner.cs | 18 ++++++++++++++++++ .../Sprites/TestSceneKaraokeSpriteText.cs | 3 +-- .../Visual/Sprites/TestSceneLyricSpriteText.cs | 4 ++-- 5 files changed, 40 insertions(+), 6 deletions(-) create mode 100644 osu.Framework.Font.Tests/Visual/FrameworkTestScene.cs create mode 100644 osu.Framework.Font.Tests/Visual/FrameworkTestSceneTestRunner.cs diff --git a/osu.Framework.Font.Tests/Visual/BackgroundGridTestScene.cs b/osu.Framework.Font.Tests/Visual/BackgroundGridTestScene.cs index 70c375f..f92c12d 100644 --- a/osu.Framework.Font.Tests/Visual/BackgroundGridTestScene.cs +++ b/osu.Framework.Font.Tests/Visual/BackgroundGridTestScene.cs @@ -11,13 +11,12 @@ using osu.Framework.Graphics.Shaders; using osu.Framework.Graphics.Shapes; using osu.Framework.Input.Events; -using osu.Framework.Testing; using osuTK; using osuTK.Graphics; namespace osu.Framework.Font.Tests.Visual; -public abstract partial class BackgroundGridTestScene : TestScene +public abstract partial class BackgroundGridTestScene : FrameworkTestScene { protected const int GRID_SIZE = 30; diff --git a/osu.Framework.Font.Tests/Visual/FrameworkTestScene.cs b/osu.Framework.Font.Tests/Visual/FrameworkTestScene.cs new file mode 100644 index 0000000..dfa7411 --- /dev/null +++ b/osu.Framework.Font.Tests/Visual/FrameworkTestScene.cs @@ -0,0 +1,18 @@ +// Copyright (c) karaoke.dev . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Framework.Testing; + +namespace osu.Framework.Font.Tests.Visual; + +/// +/// All the test scene with resource should inherit this class. +/// +public abstract partial class FrameworkTestScene : TestScene +{ + /// + /// This runner will be created only if run the unit-test. + /// + /// + protected override ITestSceneTestRunner CreateRunner() => new FrameworkTestSceneTestRunner(); +} diff --git a/osu.Framework.Font.Tests/Visual/FrameworkTestSceneTestRunner.cs b/osu.Framework.Font.Tests/Visual/FrameworkTestSceneTestRunner.cs new file mode 100644 index 0000000..cd68008 --- /dev/null +++ b/osu.Framework.Font.Tests/Visual/FrameworkTestSceneTestRunner.cs @@ -0,0 +1,18 @@ +// Copyright (c) karaoke.dev . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Framework.Allocation; +using osu.Framework.IO.Stores; +using osu.Framework.Testing; + +namespace osu.Framework.Font.Tests.Visual; + +public partial class FrameworkTestSceneTestRunner : TestSceneTestRunner +{ + [BackgroundDependencyLoader] + private void load() + { + Resources.AddStore(new NamespacedResourceStore(new DllResourceStore(typeof(FrameworkTestSceneTestRunner).Assembly), "Resources")); + Resources.AddStore(new NamespacedResourceStore(new ShaderResourceStore(), "Resources")); + } +} diff --git a/osu.Framework.Font.Tests/Visual/Sprites/TestSceneKaraokeSpriteText.cs b/osu.Framework.Font.Tests/Visual/Sprites/TestSceneKaraokeSpriteText.cs index 1809438..e33cfe4 100644 --- a/osu.Framework.Font.Tests/Visual/Sprites/TestSceneKaraokeSpriteText.cs +++ b/osu.Framework.Font.Tests/Visual/Sprites/TestSceneKaraokeSpriteText.cs @@ -13,13 +13,12 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Shaders; using osu.Framework.Graphics.Sprites; -using osu.Framework.Testing; using osuTK; using osuTK.Graphics; namespace osu.Framework.Font.Tests.Visual.Sprites; -public partial class TestSceneKaraokeSpriteText : TestScene +public partial class TestSceneKaraokeSpriteText : FrameworkTestScene { private readonly TestKaraokeSpriteText karaokeSpriteText; private readonly SpriteText transformAmountSpriteText; diff --git a/osu.Framework.Font.Tests/Visual/Sprites/TestSceneLyricSpriteText.cs b/osu.Framework.Font.Tests/Visual/Sprites/TestSceneLyricSpriteText.cs index e393875..bc700d6 100644 --- a/osu.Framework.Font.Tests/Visual/Sprites/TestSceneLyricSpriteText.cs +++ b/osu.Framework.Font.Tests/Visual/Sprites/TestSceneLyricSpriteText.cs @@ -6,12 +6,11 @@ using osu.Framework.Font.Tests.Helper; using osu.Framework.Graphics; using osu.Framework.Graphics.Sprites; -using osu.Framework.Testing; using osuTK; namespace osu.Framework.Font.Tests.Visual.Sprites; -public partial class TestSceneLyricSpriteText : TestScene +public partial class TestSceneLyricSpriteText : FrameworkTestScene { [TestCase("karaoke", null, null)] [TestCase("カラオケ", new[] { "[0,1]:か", "[1,2]:ら", "[2,3]:お", "[3,4]:け" }, null)] @@ -235,6 +234,7 @@ internal partial class DefaultLyricSpriteText : LyricSpriteText public DefaultLyricSpriteText(bool ruby = true, bool romaji = true) { Text = "カラオケ"; + Font = FontUsage.Default; if (ruby) {