1
0
mirror of https://github.com/ppy/osu.git synced 2024-12-14 22:22:54 +08:00

Merge pull request #13594 from frenzibyte/ruleset-shaders

Add support for loading shaders from ruleset resources
This commit is contained in:
Dan Balasescu 2021-07-07 17:54:18 +09:00 committed by GitHub
commit ec3bd14e0a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 107 additions and 0 deletions

View File

@ -0,0 +1,11 @@
#include "sh_Utils.h"
varying mediump vec2 v_TexCoord;
varying mediump vec4 v_TexRect;
void main(void)
{
float hueValue = v_TexCoord.x / (v_TexRect[2] - v_TexRect[0]);
gl_FragColor = hsv2rgb(vec4(hueValue, 1, 1, 1));
}

View File

@ -0,0 +1,31 @@
#include "sh_Utils.h"
attribute highp vec2 m_Position;
attribute lowp vec4 m_Colour;
attribute mediump vec2 m_TexCoord;
attribute mediump vec4 m_TexRect;
attribute mediump vec2 m_BlendRange;
varying highp vec2 v_MaskingPosition;
varying lowp vec4 v_Colour;
varying mediump vec2 v_TexCoord;
varying mediump vec4 v_TexRect;
varying mediump vec2 v_BlendRange;
uniform highp mat4 g_ProjMatrix;
uniform highp mat3 g_ToMaskingSpace;
void main(void)
{
// Transform from screen space to masking space.
highp vec3 maskingPos = g_ToMaskingSpace * vec3(m_Position, 1.0);
v_MaskingPosition = maskingPos.xy / maskingPos.z;
v_Colour = m_Colour;
v_TexCoord = m_TexCoord;
v_TexRect = m_TexRect;
v_BlendRange = m_BlendRange;
gl_Position = gProjMatrix * vec4(m_Position, 1.0, 1.0);
}

View File

@ -13,8 +13,10 @@ using osu.Framework.Bindables;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.OpenGL.Textures; using osu.Framework.Graphics.OpenGL.Textures;
using osu.Framework.Graphics.Shaders;
using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.Shapes;
using osu.Framework.Graphics.Textures; using osu.Framework.Graphics.Textures;
using osu.Framework.IO.Stores;
using osu.Framework.Testing; using osu.Framework.Testing;
using osu.Game.Rulesets.Osu; using osu.Game.Rulesets.Osu;
using osu.Game.Rulesets.UI; using osu.Game.Rulesets.UI;
@ -31,12 +33,14 @@ namespace osu.Game.Tests.Rulesets
DrawableWithDependencies drawable = null; DrawableWithDependencies drawable = null;
TestTextureStore textureStore = null; TestTextureStore textureStore = null;
TestSampleStore sampleStore = null; TestSampleStore sampleStore = null;
TestShaderManager shaderManager = null;
AddStep("add dependencies", () => AddStep("add dependencies", () =>
{ {
Child = drawable = new DrawableWithDependencies(); Child = drawable = new DrawableWithDependencies();
textureStore = drawable.ParentTextureStore; textureStore = drawable.ParentTextureStore;
sampleStore = drawable.ParentSampleStore; sampleStore = drawable.ParentSampleStore;
shaderManager = drawable.ParentShaderManager;
}); });
AddStep("clear children", Clear); AddStep("clear children", Clear);
@ -52,12 +56,14 @@ namespace osu.Game.Tests.Rulesets
AddAssert("parent texture store not disposed", () => !textureStore.IsDisposed); AddAssert("parent texture store not disposed", () => !textureStore.IsDisposed);
AddAssert("parent sample store not disposed", () => !sampleStore.IsDisposed); AddAssert("parent sample store not disposed", () => !sampleStore.IsDisposed);
AddAssert("parent shader manager not disposed", () => !shaderManager.IsDisposed);
} }
private class DrawableWithDependencies : CompositeDrawable private class DrawableWithDependencies : CompositeDrawable
{ {
public TestTextureStore ParentTextureStore { get; private set; } public TestTextureStore ParentTextureStore { get; private set; }
public TestSampleStore ParentSampleStore { get; private set; } public TestSampleStore ParentSampleStore { get; private set; }
public TestShaderManager ParentShaderManager { get; private set; }
public DrawableWithDependencies() public DrawableWithDependencies()
{ {
@ -70,6 +76,7 @@ namespace osu.Game.Tests.Rulesets
dependencies.CacheAs<TextureStore>(ParentTextureStore = new TestTextureStore()); dependencies.CacheAs<TextureStore>(ParentTextureStore = new TestTextureStore());
dependencies.CacheAs<ISampleStore>(ParentSampleStore = new TestSampleStore()); dependencies.CacheAs<ISampleStore>(ParentSampleStore = new TestSampleStore());
dependencies.CacheAs<ShaderManager>(ParentShaderManager = new TestShaderManager());
return new DrawableRulesetDependencies(new OsuRuleset(), dependencies); return new DrawableRulesetDependencies(new OsuRuleset(), dependencies);
} }
@ -135,5 +142,23 @@ namespace osu.Game.Tests.Rulesets
public int PlaybackConcurrency { get; set; } public int PlaybackConcurrency { get; set; }
} }
private class TestShaderManager : ShaderManager
{
public TestShaderManager()
: base(new ResourceStore<byte[]>())
{
}
public override byte[] LoadRaw(string name) => null;
public bool IsDisposed { get; private set; }
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
IsDisposed = true;
}
}
} }
} }

View File

@ -7,6 +7,7 @@ using NUnit.Framework;
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Audio.Sample; using osu.Framework.Audio.Sample;
using osu.Framework.Configuration.Tracking; using osu.Framework.Configuration.Tracking;
using osu.Framework.Graphics.Shaders;
using osu.Framework.Graphics.Textures; using osu.Framework.Graphics.Textures;
using osu.Framework.IO.Stores; using osu.Framework.IO.Stores;
using osu.Framework.Testing; using osu.Framework.Testing;
@ -45,6 +46,14 @@ namespace osu.Game.Tests.Testing
Dependencies.Get<ISampleStore>().Get(@"test-sample") != null); Dependencies.Get<ISampleStore>().Get(@"test-sample") != null);
} }
[Test]
public void TestRetrieveShader()
{
AddAssert("ruleset shaders retrieved", () =>
Dependencies.Get<ShaderManager>().LoadRaw(@"sh_TestVertex.vs") != null &&
Dependencies.Get<ShaderManager>().LoadRaw(@"sh_TestFragment.fs") != null);
}
[Test] [Test]
public void TestResolveConfigManager() public void TestResolveConfigManager()
{ {

View File

@ -10,6 +10,7 @@ using osu.Framework.Audio;
using osu.Framework.Audio.Sample; using osu.Framework.Audio.Sample;
using osu.Framework.Bindables; using osu.Framework.Bindables;
using osu.Framework.Graphics.OpenGL.Textures; using osu.Framework.Graphics.OpenGL.Textures;
using osu.Framework.Graphics.Shaders;
using osu.Framework.Graphics.Textures; using osu.Framework.Graphics.Textures;
using osu.Framework.IO.Stores; using osu.Framework.IO.Stores;
using osu.Framework.Platform; using osu.Framework.Platform;
@ -34,6 +35,11 @@ namespace osu.Game.Rulesets.UI
/// </remarks> /// </remarks>
public ISampleStore SampleStore { get; } public ISampleStore SampleStore { get; }
/// <summary>
/// The shader manager to be used for the ruleset.
/// </summary>
public ShaderManager ShaderManager { get; }
/// <summary> /// <summary>
/// The ruleset config manager. /// The ruleset config manager.
/// </summary> /// </summary>
@ -52,6 +58,9 @@ namespace osu.Game.Rulesets.UI
SampleStore = parent.Get<AudioManager>().GetSampleStore(new NamespacedResourceStore<byte[]>(resources, @"Samples")); SampleStore = parent.Get<AudioManager>().GetSampleStore(new NamespacedResourceStore<byte[]>(resources, @"Samples"));
SampleStore.PlaybackConcurrency = OsuGameBase.SAMPLE_CONCURRENCY; SampleStore.PlaybackConcurrency = OsuGameBase.SAMPLE_CONCURRENCY;
CacheAs(SampleStore = new FallbackSampleStore(SampleStore, parent.Get<ISampleStore>())); CacheAs(SampleStore = new FallbackSampleStore(SampleStore, parent.Get<ISampleStore>()));
ShaderManager = new ShaderManager(new NamespacedResourceStore<byte[]>(resources, @"Shaders"));
CacheAs(ShaderManager = new FallbackShaderManager(ShaderManager, parent.Get<ShaderManager>()));
} }
RulesetConfigManager = parent.Get<RulesetConfigCache>().GetConfigFor(ruleset); RulesetConfigManager = parent.Get<RulesetConfigCache>().GetConfigFor(ruleset);
@ -84,6 +93,7 @@ namespace osu.Game.Rulesets.UI
SampleStore?.Dispose(); SampleStore?.Dispose();
TextureStore?.Dispose(); TextureStore?.Dispose();
ShaderManager?.Dispose();
RulesetConfigManager = null; RulesetConfigManager = null;
} }
@ -172,5 +182,26 @@ namespace osu.Game.Rulesets.UI
primary?.Dispose(); primary?.Dispose();
} }
} }
private class FallbackShaderManager : ShaderManager
{
private readonly ShaderManager primary;
private readonly ShaderManager fallback;
public FallbackShaderManager(ShaderManager primary, ShaderManager fallback)
: base(new ResourceStore<byte[]>())
{
this.primary = primary;
this.fallback = fallback;
}
public override byte[] LoadRaw(string name) => primary.LoadRaw(name) ?? fallback.LoadRaw(name);
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
primary?.Dispose();
}
}
} }
} }