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)); }