diff --git a/osu.Framework/Graphics/Audio/WaveformGraph.cs b/osu.Framework/Graphics/Audio/WaveformGraph.cs
index 83b8cc79a3..bbd819f2e8 100644
--- a/osu.Framework/Graphics/Audio/WaveformGraph.cs
+++ b/osu.Framework/Graphics/Audio/WaveformGraph.cs
@@ -336,7 +336,7 @@ public override void Draw(IRenderer renderer)
// We're dealing with a _large_ number of points, so we need to optimise the quadToDraw * drawInfo.Matrix multiplications below
// for points that are going to be masked out anyway. This allows for higher resolution graphs at larger scales with virtually no performance loss.
// Since the points are generated in the local coordinate space, we need to convert the screen space masking quad coordinates into the local coordinate space
- RectangleF localMaskingRectangle = (Quad.FromRectangle(renderer.CurrentMaskingInfo.ScreenSpaceScissorArea) * DrawInfo.MatrixInverse).AABBFloat;
+ RectangleF localMaskingRectangle = (Quad.FromRectangle(renderer.CurrentMaskingInfo.ScreenSpaceAABB) * DrawInfo.MatrixInverse).AABBFloat;
float separation = drawSize.X / (points.Count - 1);
diff --git a/osu.Framework/Graphics/BufferedDrawNode.cs b/osu.Framework/Graphics/BufferedDrawNode.cs
index 692494536c..dada195bcd 100644
--- a/osu.Framework/Graphics/BufferedDrawNode.cs
+++ b/osu.Framework/Graphics/BufferedDrawNode.cs
@@ -35,7 +35,6 @@ public class BufferedDrawNode : TexturedShaderDrawNode
protected RectangleF DrawRectangle { get; private set; }
private Color4 backgroundColour;
- private RectangleF localDrawRectangle;
private RectangleF screenSpaceDrawRectangle;
private Vector2 frameBufferScale;
private Vector2 frameBufferSize;
@@ -53,7 +52,6 @@ public override void ApplyState()
base.ApplyState();
backgroundColour = Source.BackgroundColour;
- localDrawRectangle = Source.DrawRectangle;
screenSpaceDrawRectangle = Source.ScreenSpaceDrawQuad.AABBFloat;
DrawColourInfo = Source.FrameBufferDrawColour ?? new DrawColourInfo(Color4.White, base.DrawColourInfo.Blending);
frameBufferScale = Source.FrameBufferScale;
@@ -157,12 +155,17 @@ protected IDisposable BindFrameBuffer(IFrameBuffer frameBuffer)
private IDisposable establishFrameBufferViewport(IRenderer renderer)
{
+ // Disable masking for generating the frame buffer since masking will be re-applied
+ // when actually drawing later on anyways. This allows more information to be captured
+ // in the frame buffer and helps with cached buffers being re-used.
+ RectangleI screenSpaceMaskingRect = new RectangleI((int)Math.Floor(screenSpaceDrawRectangle.X), (int)Math.Floor(screenSpaceDrawRectangle.Y), (int)frameBufferSize.X + 1,
+ (int)frameBufferSize.Y + 1);
+
renderer.PushMaskingInfo(new MaskingInfo
{
- ScreenSpaceScissorArea = screenSpaceDrawRectangle,
- MaskingArea = localDrawRectangle,
- ToMaskingSpace = DrawInfo.MatrixInverse,
- ToScissorSpace = Matrix3.Identity,
+ ScreenSpaceAABB = screenSpaceMaskingRect,
+ MaskingRect = screenSpaceDrawRectangle,
+ ToMaskingSpace = Matrix3.Identity,
BlendRange = 1,
AlphaExponent = 1,
}, true);
@@ -170,12 +173,14 @@ private IDisposable establishFrameBufferViewport(IRenderer renderer)
// Match viewport to FrameBuffer such that we don't draw unnecessary pixels.
renderer.PushViewport(new RectangleI(0, 0, (int)frameBufferSize.X, (int)frameBufferSize.Y));
renderer.PushScissor(new RectangleI(0, 0, (int)frameBufferSize.X, (int)frameBufferSize.Y));
+ renderer.PushScissorOffset(screenSpaceMaskingRect.Location);
return new ValueInvokeOnDisposal<(BufferedDrawNode node, IRenderer renderer)>((this, renderer), tup => tup.node.returnViewport(tup.renderer));
}
private void returnViewport(IRenderer renderer)
{
+ renderer.PopScissorOffset();
renderer.PopViewport();
renderer.PopScissor();
renderer.PopMaskingInfo();
diff --git a/osu.Framework/Graphics/Containers/BufferedContainer.cs b/osu.Framework/Graphics/Containers/BufferedContainer.cs
index 4f5a11caa2..5a83d0b87a 100644
--- a/osu.Framework/Graphics/Containers/BufferedContainer.cs
+++ b/osu.Framework/Graphics/Containers/BufferedContainer.cs
@@ -266,7 +266,7 @@ public BufferedContainer(RenderBufferFormat[] formats = null, bool pixelSnapping
private void load(ShaderManager shaders)
{
TextureShader = shaders.Load(VertexShaderDescriptor.TEXTURE_2, FragmentShaderDescriptor.TEXTURE);
- blurShader = shaders.Load(VertexShaderDescriptor.TEXTURE_2_NO_MASKING, FragmentShaderDescriptor.BLUR);
+ blurShader = shaders.Load(VertexShaderDescriptor.TEXTURE_2, FragmentShaderDescriptor.BLUR);
}
protected override DrawNode CreateDrawNode() => new BufferedContainerDrawNode(this, sharedData);
diff --git a/osu.Framework/Graphics/Containers/CompositeDrawable_DrawNode.cs b/osu.Framework/Graphics/Containers/CompositeDrawable_DrawNode.cs
index eb52db9d96..05d0707856 100644
--- a/osu.Framework/Graphics/Containers/CompositeDrawable_DrawNode.cs
+++ b/osu.Framework/Graphics/Containers/CompositeDrawable_DrawNode.cs
@@ -43,7 +43,7 @@ protected class CompositeDrawableDrawNode : DrawNode, ICompositeDrawNode
private MaskingInfo? maskingInfo;
///
- /// The screen-space version of .
+ /// The screen-space version of .
/// Used as cache of screen-space masking quads computed in previous frames.
/// Assign null to reset.
///
@@ -92,11 +92,10 @@ public override void ApplyState()
? null
: new MaskingInfo
{
- ScreenSpaceScissorArea = Source.ScreenSpaceDrawQuad.AABBFloat,
- MaskingArea = Source.DrawRectangle.Normalize(),
+ ScreenSpaceAABB = Source.ScreenSpaceDrawQuad.AABB,
+ MaskingRect = Source.DrawRectangle.Normalize(),
ConservativeScreenSpaceQuad = Quad.FromRectangle(shrunkDrawRectangle) * DrawInfo.Matrix,
ToMaskingSpace = DrawInfo.MatrixInverse,
- ToScissorSpace = Matrix3.Identity,
CornerRadius = Source.effectiveCornerRadius,
CornerExponent = Source.CornerExponent,
BorderThickness = Source.BorderThickness,
@@ -122,13 +121,13 @@ private void drawEdgeEffect(IRenderer renderer)
if (maskingInfo == null || edgeEffect.Type == EdgeEffectType.None || edgeEffect.Radius <= 0.0f || edgeEffect.Colour.Alpha <= 0)
return;
- RectangleF effectRect = maskingInfo.Value.MaskingArea.Inflate(edgeEffect.Radius).Offset(edgeEffect.Offset);
+ RectangleF effectRect = maskingInfo.Value.MaskingRect.Inflate(edgeEffect.Radius).Offset(edgeEffect.Offset);
screenSpaceMaskingQuad ??= Quad.FromRectangle(effectRect) * DrawInfo.Matrix;
MaskingInfo edgeEffectMaskingInfo = maskingInfo.Value;
- edgeEffectMaskingInfo.MaskingArea = effectRect;
- edgeEffectMaskingInfo.ScreenSpaceScissorArea = screenSpaceMaskingQuad.Value.AABBFloat;
+ edgeEffectMaskingInfo.MaskingRect = effectRect;
+ edgeEffectMaskingInfo.ScreenSpaceAABB = screenSpaceMaskingQuad.Value.AABB;
edgeEffectMaskingInfo.CornerRadius = maskingInfo.Value.CornerRadius + edgeEffect.Radius + edgeEffect.Roundness;
edgeEffectMaskingInfo.BorderThickness = 0;
// HACK HACK HACK. We abuse blend range to give us the linear alpha gradient of
diff --git a/osu.Framework/Graphics/Lines/Path_DrawNode.cs b/osu.Framework/Graphics/Lines/Path_DrawNode.cs
index 1432f13ad3..8ab0a46981 100644
--- a/osu.Framework/Graphics/Lines/Path_DrawNode.cs
+++ b/osu.Framework/Graphics/Lines/Path_DrawNode.cs
@@ -72,7 +72,7 @@ public override void Draw(IRenderer renderer)
texture.Bind();
- updateVertexBuffer(renderer);
+ updateVertexBuffer();
pathShader.Unbind();
@@ -88,7 +88,7 @@ private Color4 colourAt(Vector2 localPos) => DrawColourInfo.Colour.TryExtractSin
? colour.SRGB
: DrawColourInfo.Colour.Interpolate(relativePosition(localPos)).SRGB;
- private void addSegmentQuads(IRenderer renderer, Line segment, Line segmentLeft, Line segmentRight, RectangleF texRect)
+ private void addSegmentQuads(Line segment, Line segmentLeft, Line segmentRight, RectangleF texRect)
{
Debug.Assert(triangleBatch != null);
@@ -101,19 +101,19 @@ private void addSegmentQuads(IRenderer renderer, Line segment, Line segmentLeft,
// Each of the quads (mentioned above) is rendered as 2 triangles:
// Outer quad, triangle 1
- triangleBatch.Add(new TexturedVertex3D(renderer)
+ triangleBatch.Add(new TexturedVertex3D
{
Position = new Vector3(segmentRight.EndPoint.X, segmentRight.EndPoint.Y, 0),
TexturePosition = new Vector2(texRect.Left, texRect.Centre.Y),
Colour = colourAt(segmentRight.EndPoint)
});
- triangleBatch.Add(new TexturedVertex3D(renderer)
+ triangleBatch.Add(new TexturedVertex3D
{
Position = new Vector3(segmentRight.StartPoint.X, segmentRight.StartPoint.Y, 0),
TexturePosition = new Vector2(texRect.Left, texRect.Centre.Y),
Colour = colourAt(segmentRight.StartPoint)
});
- triangleBatch.Add(new TexturedVertex3D(renderer)
+ triangleBatch.Add(new TexturedVertex3D
{
Position = firstMiddlePoint,
TexturePosition = new Vector2(texRect.Right, texRect.Centre.Y),
@@ -121,19 +121,19 @@ private void addSegmentQuads(IRenderer renderer, Line segment, Line segmentLeft,
});
// Outer quad, triangle 2
- triangleBatch.Add(new TexturedVertex3D(renderer)
+ triangleBatch.Add(new TexturedVertex3D
{
Position = firstMiddlePoint,
TexturePosition = new Vector2(texRect.Right, texRect.Centre.Y),
Colour = firstMiddleColour
});
- triangleBatch.Add(new TexturedVertex3D(renderer)
+ triangleBatch.Add(new TexturedVertex3D
{
Position = secondMiddlePoint,
TexturePosition = new Vector2(texRect.Right, texRect.Centre.Y),
Colour = secondMiddleColour
});
- triangleBatch.Add(new TexturedVertex3D(renderer)
+ triangleBatch.Add(new TexturedVertex3D
{
Position = new Vector3(segmentRight.EndPoint.X, segmentRight.EndPoint.Y, 0),
TexturePosition = new Vector2(texRect.Left, texRect.Centre.Y),
@@ -141,19 +141,19 @@ private void addSegmentQuads(IRenderer renderer, Line segment, Line segmentLeft,
});
// Inner quad, triangle 1
- triangleBatch.Add(new TexturedVertex3D(renderer)
+ triangleBatch.Add(new TexturedVertex3D
{
Position = firstMiddlePoint,
TexturePosition = new Vector2(texRect.Right, texRect.Centre.Y),
Colour = firstMiddleColour
});
- triangleBatch.Add(new TexturedVertex3D(renderer)
+ triangleBatch.Add(new TexturedVertex3D
{
Position = secondMiddlePoint,
TexturePosition = new Vector2(texRect.Right, texRect.Centre.Y),
Colour = secondMiddleColour
});
- triangleBatch.Add(new TexturedVertex3D(renderer)
+ triangleBatch.Add(new TexturedVertex3D
{
Position = new Vector3(segmentLeft.EndPoint.X, segmentLeft.EndPoint.Y, 0),
TexturePosition = new Vector2(texRect.Left, texRect.Centre.Y),
@@ -161,19 +161,19 @@ private void addSegmentQuads(IRenderer renderer, Line segment, Line segmentLeft,
});
// Inner quad, triangle 2
- triangleBatch.Add(new TexturedVertex3D(renderer)
+ triangleBatch.Add(new TexturedVertex3D
{
Position = new Vector3(segmentLeft.EndPoint.X, segmentLeft.EndPoint.Y, 0),
TexturePosition = new Vector2(texRect.Left, texRect.Centre.Y),
Colour = colourAt(segmentLeft.EndPoint)
});
- triangleBatch.Add(new TexturedVertex3D(renderer)
+ triangleBatch.Add(new TexturedVertex3D
{
Position = new Vector3(segmentLeft.StartPoint.X, segmentLeft.StartPoint.Y, 0),
TexturePosition = new Vector2(texRect.Left, texRect.Centre.Y),
Colour = colourAt(segmentLeft.StartPoint)
});
- triangleBatch.Add(new TexturedVertex3D(renderer)
+ triangleBatch.Add(new TexturedVertex3D
{
Position = firstMiddlePoint,
TexturePosition = new Vector2(texRect.Right, texRect.Centre.Y),
@@ -181,7 +181,7 @@ private void addSegmentQuads(IRenderer renderer, Line segment, Line segmentLeft,
});
}
- private void addSegmentCaps(IRenderer renderer, float thetaDiff, Line segmentLeft, Line segmentRight, Line prevSegmentLeft, Line prevSegmentRight, RectangleF texRect)
+ private void addSegmentCaps(float thetaDiff, Line segmentLeft, Line segmentRight, Line prevSegmentLeft, Line prevSegmentRight, RectangleF texRect)
{
Debug.Assert(triangleBatch != null);
@@ -210,7 +210,7 @@ private void addSegmentCaps(IRenderer renderer, float thetaDiff, Line segmentLef
for (int i = 1; i <= stepCount; i++)
{
// Center point
- triangleBatch.Add(new TexturedVertex3D(renderer)
+ triangleBatch.Add(new TexturedVertex3D
{
Position = new Vector3(origin.X, origin.Y, 1),
TexturePosition = new Vector2(texRect.Right, texRect.Centre.Y),
@@ -218,7 +218,7 @@ private void addSegmentCaps(IRenderer renderer, float thetaDiff, Line segmentLef
});
// First outer point
- triangleBatch.Add(new TexturedVertex3D(renderer)
+ triangleBatch.Add(new TexturedVertex3D
{
Position = new Vector3(current.X, current.Y, 0),
TexturePosition = new Vector2(texRect.Left, texRect.Centre.Y),
@@ -229,7 +229,7 @@ private void addSegmentCaps(IRenderer renderer, float thetaDiff, Line segmentLef
currentColour = colourAt(current);
// Second outer point
- triangleBatch.Add(new TexturedVertex3D(renderer)
+ triangleBatch.Add(new TexturedVertex3D
{
Position = new Vector3(current.X, current.Y, 0),
TexturePosition = new Vector2(texRect.Left, texRect.Centre.Y),
@@ -238,7 +238,7 @@ private void addSegmentCaps(IRenderer renderer, float thetaDiff, Line segmentLef
}
}
- private void updateVertexBuffer(IRenderer renderer)
+ private void updateVertexBuffer()
{
// Explanation of the terms "left" and "right":
// "Left" and "right" are used here in terms of a typical (Cartesian) coordinate system.
@@ -277,7 +277,7 @@ private void updateVertexBuffer(IRenderer renderer)
Line currSegmentLeft = new Line(currSegment.StartPoint + ortho * radius, currSegment.EndPoint + ortho * radius);
Line currSegmentRight = new Line(currSegment.StartPoint - ortho * radius, currSegment.EndPoint - ortho * radius);
- addSegmentQuads(renderer, currSegment, currSegmentLeft, currSegmentRight, texRect);
+ addSegmentQuads(currSegment, currSegmentLeft, currSegmentRight, texRect);
if (prevSegmentLeft is Line psLeft && prevSegmentRight is Line psRight)
{
@@ -285,7 +285,7 @@ private void updateVertexBuffer(IRenderer renderer)
// Connection/filler caps between segment quads
float thetaDiff = currSegment.Theta - segments[i - 1].Theta;
- addSegmentCaps(renderer, thetaDiff, currSegmentLeft, currSegmentRight, psLeft, psRight, texRect);
+ addSegmentCaps(thetaDiff, currSegmentLeft, currSegmentRight, psLeft, psRight, texRect);
}
// Explanation of semi-circle caps:
@@ -300,7 +300,7 @@ private void updateVertexBuffer(IRenderer renderer)
Line flippedLeft = new Line(currSegmentRight.EndPoint, currSegmentRight.StartPoint);
Line flippedRight = new Line(currSegmentLeft.EndPoint, currSegmentLeft.StartPoint);
- addSegmentCaps(renderer, MathF.PI, currSegmentLeft, currSegmentRight, flippedLeft, flippedRight, texRect);
+ addSegmentCaps(MathF.PI, currSegmentLeft, currSegmentRight, flippedLeft, flippedRight, texRect);
}
if (i == segments.Count - 1)
@@ -309,7 +309,7 @@ private void updateVertexBuffer(IRenderer renderer)
Line flippedLeft = new Line(currSegmentRight.EndPoint, currSegmentRight.StartPoint);
Line flippedRight = new Line(currSegmentLeft.EndPoint, currSegmentLeft.StartPoint);
- addSegmentCaps(renderer, MathF.PI, flippedLeft, flippedRight, currSegmentLeft, currSegmentRight, texRect);
+ addSegmentCaps(MathF.PI, flippedLeft, flippedRight, currSegmentLeft, currSegmentRight, texRect);
}
prevSegmentLeft = currSegmentLeft;
diff --git a/osu.Framework/Graphics/OpenGL/GLRenderer.cs b/osu.Framework/Graphics/OpenGL/GLRenderer.cs
index 75b6c7e2d6..f864712d88 100644
--- a/osu.Framework/Graphics/OpenGL/GLRenderer.cs
+++ b/osu.Framework/Graphics/OpenGL/GLRenderer.cs
@@ -283,7 +283,6 @@ public void DrawVertices(PrimitiveType type, int vertexStart, int verticesCount)
var glShader = (GLShader)Shader!;
glShader.BindUniformBlock("g_GlobalUniforms", GlobalUniformBuffer!);
- glShader.BindUniformBlock("g_MaskingBuffer", ShaderMaskingStack!.CurrentBuffer);
int currentUniformBinding = 0;
int currentStorageBinding = 0;
diff --git a/osu.Framework/Graphics/Rendering/Dummy/DummyRenderer.cs b/osu.Framework/Graphics/Rendering/Dummy/DummyRenderer.cs
index a752d0e630..f94221b240 100644
--- a/osu.Framework/Graphics/Rendering/Dummy/DummyRenderer.cs
+++ b/osu.Framework/Graphics/Rendering/Dummy/DummyRenderer.cs
@@ -29,7 +29,6 @@ public sealed class DummyRenderer : IRenderer
public bool IsUvOriginTopLeft => true;
public bool IsClipSpaceYInverted => true;
public ref readonly MaskingInfo CurrentMaskingInfo => ref maskingInfo;
- public int CurrentMaskingIndex => 0;
private readonly MaskingInfo maskingInfo;
public RectangleI Viewport => RectangleI.Empty;
diff --git a/osu.Framework/Graphics/Rendering/FlushBatchSource.cs b/osu.Framework/Graphics/Rendering/FlushBatchSource.cs
index de2c95ef0a..13e557e544 100644
--- a/osu.Framework/Graphics/Rendering/FlushBatchSource.cs
+++ b/osu.Framework/Graphics/Rendering/FlushBatchSource.cs
@@ -12,6 +12,7 @@ public enum FlushBatchSource
SetBlendMask,
SetDepthInfo,
SetFrameBuffer,
+ SetMasking,
SetProjection,
SetScissor,
SetShader,
diff --git a/osu.Framework/Graphics/Rendering/GlobalUniformData.cs b/osu.Framework/Graphics/Rendering/GlobalUniformData.cs
index 7f26e04b6a..51ba8b7e13 100644
--- a/osu.Framework/Graphics/Rendering/GlobalUniformData.cs
+++ b/osu.Framework/Graphics/Rendering/GlobalUniformData.cs
@@ -16,9 +16,23 @@ public record struct GlobalUniformData
public UniformBool IsUvOriginTopLeft;
public UniformMatrix4 ProjMatrix;
+ public UniformMatrix3 ToMaskingSpace;
+ public UniformBool IsMasking;
+ public UniformFloat CornerRadius;
+ public UniformFloat CornerExponent;
+ private readonly UniformPadding4 pad2;
+ public UniformVector4 MaskingRect;
+ public UniformFloat BorderThickness;
+ private readonly UniformPadding12 pad3;
+
+ public UniformMatrix4 BorderColour;
+ public UniformFloat MaskingBlendRange;
+ public UniformFloat AlphaExponent;
+ public UniformVector2 EdgeOffset;
+ public UniformBool DiscardInner;
+ public UniformFloat InnerCornerRadius;
public UniformInt WrapModeS;
public UniformInt WrapModeT;
- private readonly UniformPadding8 pad1;
}
}
diff --git a/osu.Framework/Graphics/Rendering/IRenderer.cs b/osu.Framework/Graphics/Rendering/IRenderer.cs
index 6e0003c7c1..c97e4914ca 100644
--- a/osu.Framework/Graphics/Rendering/IRenderer.cs
+++ b/osu.Framework/Graphics/Rendering/IRenderer.cs
@@ -98,8 +98,6 @@ public interface IRenderer
///
ref readonly MaskingInfo CurrentMaskingInfo { get; }
- int CurrentMaskingIndex { get; }
-
///
/// The current viewport.
///
@@ -278,6 +276,17 @@ public interface IRenderer
///
void PopScissor();
+ ///
+ /// Applies a new scissor offset to the scissor rectangle.
+ ///
+ /// The scissor offset.
+ void PushScissorOffset(Vector2I offset);
+
+ ///
+ /// Restores the last scissor offset.
+ ///
+ void PopScissorOffset();
+
///
/// Applies a new projection matrix.
///
diff --git a/osu.Framework/Graphics/Rendering/MaskingInfo.cs b/osu.Framework/Graphics/Rendering/MaskingInfo.cs
index 1220d15bf2..8198d45b6a 100644
--- a/osu.Framework/Graphics/Rendering/MaskingInfo.cs
+++ b/osu.Framework/Graphics/Rendering/MaskingInfo.cs
@@ -10,34 +10,18 @@ namespace osu.Framework.Graphics.Rendering
{
public struct MaskingInfo : IEquatable
{
- ///
- /// A rectangle that defines the scissor area in screen-space coordinates.
- ///
- public RectangleF ScreenSpaceScissorArea;
-
- ///
- /// A rectangle that defines the masking area in the local-space (i.e. ) of the masking container.
- ///
- public RectangleF MaskingArea;
+ public RectangleI ScreenSpaceAABB;
+ public RectangleF MaskingRect;
- ///
- /// A quad representing the internal "safe" (without borders, corners, and AA smoothening) area of the masking container.
- ///
- ///
- /// This is used to clip drawn polygons during the front-to-back pass such that only areas guaranteed to be visible are drawn.
- ///
public Quad ConservativeScreenSpaceQuad;
///
- /// A matrix that converts from vertex coordinates to the space of .
+ /// This matrix transforms screen space coordinates to masking space (likely the parent
+ /// space of the container doing the masking).
+ /// It is used by a shader to determine which pixels to discard.
///
public Matrix3 ToMaskingSpace;
- ///
- /// A matrix that converts from vertex coordinates to the space of .
- ///
- public Matrix3 ToScissorSpace;
-
public float CornerRadius;
public float CornerExponent;
@@ -55,11 +39,10 @@ public struct MaskingInfo : IEquatable
public readonly bool Equals(MaskingInfo other) => this == other;
public static bool operator ==(in MaskingInfo left, in MaskingInfo right) =>
- left.ScreenSpaceScissorArea == right.ScreenSpaceScissorArea &&
- left.MaskingArea == right.MaskingArea &&
+ left.ScreenSpaceAABB == right.ScreenSpaceAABB &&
+ left.MaskingRect == right.MaskingRect &&
left.ConservativeScreenSpaceQuad.Equals(right.ConservativeScreenSpaceQuad) &&
left.ToMaskingSpace == right.ToMaskingSpace &&
- left.ToScissorSpace == right.ToScissorSpace &&
left.CornerRadius == right.CornerRadius &&
left.CornerExponent == right.CornerExponent &&
left.BorderThickness == right.BorderThickness &&
diff --git a/osu.Framework/Graphics/Rendering/Renderer.cs b/osu.Framework/Graphics/Rendering/Renderer.cs
index 3ad1d47cb7..6fbfaf88fd 100644
--- a/osu.Framework/Graphics/Rendering/Renderer.cs
+++ b/osu.Framework/Graphics/Rendering/Renderer.cs
@@ -59,7 +59,6 @@ protected internal Storage? CacheStorage
public ulong FrameIndex { get; private set; }
public ref readonly MaskingInfo CurrentMaskingInfo => ref currentMaskingInfo;
- public int CurrentMaskingIndex => ShaderMaskingStack?.CurrentOffset ?? 0;
public RectangleI Viewport { get; private set; }
public RectangleI Scissor { get; private set; }
@@ -131,8 +130,6 @@ protected internal Storage? CacheStorage
private readonly LockedWeakList allTextures = new LockedWeakList();
protected IUniformBuffer? GlobalUniformBuffer { get; private set; }
- protected ShaderStorageBufferObjectStack? ShaderMaskingStack { get; private set; }
-
private IVertexBatch? defaultQuadBatch;
private IVertexBatch? currentActiveBatch;
private MaskingInfo currentMaskingInfo;
@@ -199,10 +196,6 @@ protected internal virtual void BeginFrame(Vector2 windowSize)
IsUvOriginTopLeft = IsUvOriginTopLeft
};
- // 60 elements keeps the total data length under 16KiB (16320).
- ShaderMaskingStack ??= new ShaderStorageBufferObjectStack(this, 60, 8192);
- ShaderMaskingStack.Clear();
-
Debug.Assert(defaultQuadBatch != null);
FrameIndex++;
@@ -255,12 +248,12 @@ protected internal virtual void BeginFrame(Vector2 windowSize)
PushScissorState(true);
PushViewport(new RectangleI(0, 0, (int)windowSize.X, (int)windowSize.Y));
PushScissor(new RectangleI(0, 0, (int)windowSize.X, (int)windowSize.Y));
+ PushScissorOffset(Vector2I.Zero);
PushMaskingInfo(new MaskingInfo
{
- ScreenSpaceScissorArea = new RectangleI(0, 0, (int)windowSize.X, (int)windowSize.Y),
- MaskingArea = new RectangleF(0, 0, windowSize.X, windowSize.Y),
+ ScreenSpaceAABB = new RectangleI(0, 0, (int)windowSize.X, (int)windowSize.Y),
+ MaskingRect = new RectangleF(0, 0, windowSize.X, windowSize.Y),
ToMaskingSpace = Matrix3.Identity,
- ToScissorSpace = Matrix3.Identity,
BlendRange = 1,
AlphaExponent = 1,
CornerExponent = 2.5f,
@@ -496,6 +489,12 @@ public void PushScissorState(bool enabled)
setScissorState(enabled);
}
+ public void PushScissorOffset(Vector2I offset)
+ {
+ scissorOffsetStack.Push(offset);
+ setScissorOffset(offset);
+ }
+
public void PopScissor()
{
Trace.Assert(scissorRectStack.Count > 1);
@@ -512,6 +511,14 @@ public void PopScissorState()
setScissorState(scissorStateStack.Peek());
}
+ public void PopScissorOffset()
+ {
+ Trace.Assert(scissorOffsetStack.Count > 1);
+
+ scissorOffsetStack.Pop();
+ setScissorOffset(scissorOffsetStack.Peek());
+ }
+
private void setScissor(RectangleI scissor)
{
if (scissor.Width < 0)
@@ -552,6 +559,15 @@ private void setScissorState(bool enabled)
ScissorState = enabled;
}
+ private void setScissorOffset(Vector2I offset)
+ {
+ if (ScissorOffset == offset)
+ return;
+
+ FlushCurrentBatch(FlushBatchSource.SetScissor);
+ ScissorOffset = offset;
+ }
+
///
/// Updates the graphics device with a new scissor rectangle.
///
@@ -616,74 +632,71 @@ private void setMaskingInfo(MaskingInfo maskingInfo, bool isPushing, bool overwr
if (CurrentMaskingInfo == maskingInfo)
return;
+ FlushCurrentBatch(FlushBatchSource.SetMasking);
+
+ GlobalUniformBuffer!.Data = GlobalUniformBuffer.Data with
+ {
+ IsMasking = IsMaskingActive,
+ MaskingRect = new Vector4(
+ maskingInfo.MaskingRect.Left,
+ maskingInfo.MaskingRect.Top,
+ maskingInfo.MaskingRect.Right,
+ maskingInfo.MaskingRect.Bottom),
+ ToMaskingSpace = maskingInfo.ToMaskingSpace,
+ CornerRadius = maskingInfo.CornerRadius,
+ CornerExponent = maskingInfo.CornerExponent,
+ BorderThickness = maskingInfo.BorderThickness / maskingInfo.BlendRange,
+ BorderColour = maskingInfo.BorderThickness > 0
+ ? new Matrix4(
+ // TopLeft
+ maskingInfo.BorderColour.TopLeft.SRGB.R,
+ maskingInfo.BorderColour.TopLeft.SRGB.G,
+ maskingInfo.BorderColour.TopLeft.SRGB.B,
+ maskingInfo.BorderColour.TopLeft.SRGB.A,
+ // BottomLeft
+ maskingInfo.BorderColour.BottomLeft.SRGB.R,
+ maskingInfo.BorderColour.BottomLeft.SRGB.G,
+ maskingInfo.BorderColour.BottomLeft.SRGB.B,
+ maskingInfo.BorderColour.BottomLeft.SRGB.A,
+ // TopRight
+ maskingInfo.BorderColour.TopRight.SRGB.R,
+ maskingInfo.BorderColour.TopRight.SRGB.G,
+ maskingInfo.BorderColour.TopRight.SRGB.B,
+ maskingInfo.BorderColour.TopRight.SRGB.A,
+ // BottomRight
+ maskingInfo.BorderColour.BottomRight.SRGB.R,
+ maskingInfo.BorderColour.BottomRight.SRGB.G,
+ maskingInfo.BorderColour.BottomRight.SRGB.B,
+ maskingInfo.BorderColour.BottomRight.SRGB.A)
+ : GlobalUniformBuffer.Data.BorderColour,
+ MaskingBlendRange = maskingInfo.BlendRange,
+ AlphaExponent = maskingInfo.AlphaExponent,
+ EdgeOffset = maskingInfo.EdgeOffset,
+ DiscardInner = maskingInfo.Hollow,
+ InnerCornerRadius = maskingInfo.Hollow
+ ? maskingInfo.HollowCornerRadius
+ : GlobalUniformBuffer.Data.InnerCornerRadius
+ };
+
if (isPushing)
{
- RectangleF scissorRect = maskingInfo.ScreenSpaceScissorArea;
+ // When drawing to a viewport that doesn't match the projection size (e.g. via framebuffers), the resultant image will be scaled
+ Vector2 projectionScale = new Vector2(ProjectionMatrix.Row0.X / 2, -ProjectionMatrix.Row1.Y / 2);
+ Vector2 viewportScale = Vector2.Multiply(Viewport.Size, projectionScale);
- if (!overwritePreviousScissor)
- {
- Vector4 currentSmiScissorRectangle = ShaderMaskingStack!.CurrentBuffer[ShaderMaskingStack.CurrentOffset].ScissorRect;
- RectangleF currentScissorRectangle = RectangleF.FromLTRB(
- currentSmiScissorRectangle.X,
- currentSmiScissorRectangle.Y,
- currentSmiScissorRectangle.Z,
- currentSmiScissorRectangle.W);
-
- scissorRect = RectangleF.Intersect(currentScissorRectangle, scissorRect);
- }
+ Vector2 location = (maskingInfo.ScreenSpaceAABB.Location - ScissorOffset) * viewportScale;
+ Vector2 size = maskingInfo.ScreenSpaceAABB.Size * viewportScale;
- ShaderMaskingStack!.Push(new ShaderMaskingInfo
- {
- IsMasking = IsMaskingActive,
- MaskingRect = new Vector4(
- maskingInfo.MaskingArea.Left,
- maskingInfo.MaskingArea.Top,
- maskingInfo.MaskingArea.Right,
- maskingInfo.MaskingArea.Bottom),
- ScissorRect = new Vector4(
- scissorRect.Left,
- scissorRect.Top,
- scissorRect.Right,
- scissorRect.Bottom),
- ToMaskingSpace = new Matrix4(maskingInfo.ToMaskingSpace),
- ToScissorSpace = new Matrix4(maskingInfo.ToScissorSpace),
- CornerRadius = maskingInfo.CornerRadius,
- CornerExponent = maskingInfo.CornerExponent,
- BorderThickness = maskingInfo.BorderThickness / maskingInfo.BlendRange,
- BorderColour = maskingInfo.BorderThickness > 0
- ? new Matrix4(
- // TopLeft
- maskingInfo.BorderColour.TopLeft.SRGB.R,
- maskingInfo.BorderColour.TopLeft.SRGB.G,
- maskingInfo.BorderColour.TopLeft.SRGB.B,
- maskingInfo.BorderColour.TopLeft.SRGB.A,
- // BottomLeft
- maskingInfo.BorderColour.BottomLeft.SRGB.R,
- maskingInfo.BorderColour.BottomLeft.SRGB.G,
- maskingInfo.BorderColour.BottomLeft.SRGB.B,
- maskingInfo.BorderColour.BottomLeft.SRGB.A,
- // TopRight
- maskingInfo.BorderColour.TopRight.SRGB.R,
- maskingInfo.BorderColour.TopRight.SRGB.G,
- maskingInfo.BorderColour.TopRight.SRGB.B,
- maskingInfo.BorderColour.TopRight.SRGB.A,
- // BottomRight
- maskingInfo.BorderColour.BottomRight.SRGB.R,
- maskingInfo.BorderColour.BottomRight.SRGB.G,
- maskingInfo.BorderColour.BottomRight.SRGB.B,
- maskingInfo.BorderColour.BottomRight.SRGB.A)
- : ShaderMaskingStack.CurrentBuffer[ShaderMaskingStack.CurrentOffset].BorderColour,
- MaskingBlendRange = maskingInfo.BlendRange,
- AlphaExponent = maskingInfo.AlphaExponent,
- EdgeOffset = maskingInfo.EdgeOffset,
- DiscardInner = maskingInfo.Hollow,
- InnerCornerRadius = maskingInfo.Hollow
- ? maskingInfo.HollowCornerRadius
- : ShaderMaskingStack.CurrentBuffer[ShaderMaskingStack.CurrentOffset].InnerCornerRadius,
- });
+ RectangleI actualRect = new RectangleI(
+ (int)Math.Floor(location.X),
+ (int)Math.Floor(location.Y),
+ (int)Math.Ceiling(size.X),
+ (int)Math.Ceiling(size.Y));
+
+ PushScissor(overwritePreviousScissor ? actualRect : RectangleI.Intersect(scissorRectStack.Peek(), actualRect));
}
else
- ShaderMaskingStack!.Pop();
+ PopScissor();
currentMaskingInfo = maskingInfo;
}
diff --git a/osu.Framework/Graphics/Rendering/RendererExtensions.cs b/osu.Framework/Graphics/Rendering/RendererExtensions.cs
index e0dae0b7d8..e56c7d0d14 100644
--- a/osu.Framework/Graphics/Rendering/RendererExtensions.cs
+++ b/osu.Framework/Graphics/Rendering/RendererExtensions.cs
@@ -263,14 +263,9 @@ public static void PushOrtho(this IRenderer renderer, RectangleF ortho)
public static void PushLocalMatrix(this IRenderer renderer, Matrix4 matrix)
{
var currentMasking = renderer.CurrentMaskingInfo;
-
- // Normally, ToMaskingSpace is used to convert from screen-space coordinates to local coordinates in the masking-space.
- // But if a local matrix is pushed, then vertices will instead be provided in local-space, such that:
- // 1. To convert to masking-space we need to first convert to screen-space.
- // 2. To convert to scissor-space we need to convert to screen-space.
+ // normally toMaskingSpace is fed vertices already in screen space coordinates,
+ // but since we are modifying the matrix the vertices are in local space
currentMasking.ToMaskingSpace = new Matrix3(matrix) * currentMasking.ToMaskingSpace;
- currentMasking.ToScissorSpace = new Matrix3(matrix);
-
renderer.PushMaskingInfo(currentMasking, true);
renderer.PushProjectionMatrix(matrix * renderer.ProjectionMatrix);
}
@@ -279,13 +274,10 @@ public static void PushLocalMatrix(this IRenderer renderer, Matrix4 matrix)
public static void PushLocalMatrix(this IRenderer renderer, Matrix3 matrix)
{
var currentMasking = renderer.CurrentMaskingInfo;
-
- // Normally, ToMaskingSpace is used to convert from screen-space coordinates to local coordinates in the masking-space.
- // But if a local matrix is pushed, then vertices will instead be provided in local-space, such that:
- // 1. To convert to masking-space we need to first convert to screen-space.
- // 2. To convert to scissor-space we need to convert to screen-space.
+ // normally toMaskingSpace is fed vertices already in screen space coordinates,
+ // but since we are modifying the matrix the vertices are in local space
currentMasking.ToMaskingSpace = matrix * currentMasking.ToMaskingSpace;
- currentMasking.ToScissorSpace = matrix;
+ renderer.PushMaskingInfo(currentMasking, true);
// this makes sure it also works for 3D vertices like the ones path uses
Matrix4 mat = new Matrix4(matrix);
@@ -293,8 +285,6 @@ public static void PushLocalMatrix(this IRenderer renderer, Matrix3 matrix)
mat.Row2.X = 0;
mat.Row3.Y = mat.Row2.Y;
mat.Row2.Y = 0;
-
- renderer.PushMaskingInfo(currentMasking, true);
renderer.PushProjectionMatrix(mat * renderer.ProjectionMatrix);
}
diff --git a/osu.Framework/Graphics/Rendering/ShaderMaskingInfo.cs b/osu.Framework/Graphics/Rendering/ShaderMaskingInfo.cs
deleted file mode 100644
index aa4eb342e5..0000000000
--- a/osu.Framework/Graphics/Rendering/ShaderMaskingInfo.cs
+++ /dev/null
@@ -1,32 +0,0 @@
-// Copyright (c) ppy Pty Ltd . 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.Shaders.Types;
-
-namespace osu.Framework.Graphics.Rendering
-{
- [StructLayout(LayoutKind.Sequential, Pack = 1)]
- public record struct ShaderMaskingInfo
- {
- public UniformMatrix4 ToMaskingSpace;
- public UniformMatrix4 ToScissorSpace;
-
- public UniformBool IsMasking;
- public UniformFloat CornerRadius;
- public UniformFloat CornerExponent;
- public UniformFloat BorderThickness;
-
- public UniformVector4 MaskingRect;
- public UniformVector4 ScissorRect;
-
- public UniformMatrix4 BorderColour;
- public UniformFloat MaskingBlendRange;
- public UniformFloat AlphaExponent;
- public UniformVector2 EdgeOffset;
-
- public UniformBool DiscardInner;
- public UniformFloat InnerCornerRadius;
- private readonly UniformPadding8 pad1;
- }
-}
diff --git a/osu.Framework/Graphics/Rendering/Vertices/TexturedVertex2D.cs b/osu.Framework/Graphics/Rendering/Vertices/TexturedVertex2D.cs
index 073befa2b3..4a31c2bfd4 100644
--- a/osu.Framework/Graphics/Rendering/Vertices/TexturedVertex2D.cs
+++ b/osu.Framework/Graphics/Rendering/Vertices/TexturedVertex2D.cs
@@ -30,9 +30,6 @@ public struct TexturedVertex2D : IEquatable, IVertex
[VertexMember(1, VertexAttribPointerType.Float)]
private readonly float backbufferDrawDepth;
- [VertexMember(1, VertexAttribPointerType.Int)]
- private readonly int maskingIndex;
-
[Obsolete("Initialise this type with an IRenderer instead", true)]
public TexturedVertex2D()
{
@@ -43,7 +40,6 @@ public TexturedVertex2D(IRenderer renderer)
{
this = default; // explicitly initialise all members to default values
backbufferDrawDepth = renderer.BackbufferDrawDepth;
- maskingIndex = renderer.CurrentMaskingIndex;
}
public readonly bool Equals(TexturedVertex2D other) =>
@@ -52,7 +48,6 @@ public readonly bool Equals(TexturedVertex2D other) =>
&& Colour.Equals(other.Colour)
&& TextureRect.Equals(other.TextureRect)
&& BlendRange.Equals(other.BlendRange)
- && backbufferDrawDepth == other.backbufferDrawDepth
- && maskingIndex == other.maskingIndex;
+ && backbufferDrawDepth == other.backbufferDrawDepth;
}
}
diff --git a/osu.Framework/Graphics/Rendering/Vertices/TexturedVertex3D.cs b/osu.Framework/Graphics/Rendering/Vertices/TexturedVertex3D.cs
index 571dddfe34..34bcbac314 100644
--- a/osu.Framework/Graphics/Rendering/Vertices/TexturedVertex3D.cs
+++ b/osu.Framework/Graphics/Rendering/Vertices/TexturedVertex3D.cs
@@ -21,25 +21,6 @@ public struct TexturedVertex3D : IEquatable, IVertex
[VertexMember(2, VertexAttribPointerType.Float)]
public Vector2 TexturePosition;
- [VertexMember(1, VertexAttribPointerType.Int)]
- private readonly int maskingIndex;
-
- [Obsolete("Initialise this type with an IRenderer instead", true)]
- public TexturedVertex3D()
- {
- this = default; // explicitly initialise all members to default values
- }
-
- public TexturedVertex3D(IRenderer renderer)
- {
- this = default; // explicitly initialise all members to default values
- maskingIndex = renderer.CurrentMaskingIndex;
- }
-
- public readonly bool Equals(TexturedVertex3D other)
- => Position.Equals(other.Position)
- && TexturePosition.Equals(other.TexturePosition)
- && Colour.Equals(other.Colour)
- && maskingIndex == other.maskingIndex;
+ public readonly bool Equals(TexturedVertex3D other) => Position.Equals(other.Position) && TexturePosition.Equals(other.TexturePosition) && Colour.Equals(other.Colour);
}
}
diff --git a/osu.Framework/Graphics/Shaders/ShaderManager.cs b/osu.Framework/Graphics/Shaders/ShaderManager.cs
index 0620b004f0..27fa27653e 100644
--- a/osu.Framework/Graphics/Shaders/ShaderManager.cs
+++ b/osu.Framework/Graphics/Shaders/ShaderManager.cs
@@ -149,7 +149,6 @@ protected virtual void Dispose(bool disposing)
public static class VertexShaderDescriptor
{
public const string TEXTURE_2 = "Texture2D";
- public const string TEXTURE_2_NO_MASKING = "Texture2D_NoMasking";
public const string TEXTURE_3 = "Texture3D";
public const string POSITION = "Position";
}
diff --git a/osu.Framework/Graphics/Veldrid/VeldridRenderer.cs b/osu.Framework/Graphics/Veldrid/VeldridRenderer.cs
index a69a1c0406..57ce6ad3ec 100644
--- a/osu.Framework/Graphics/Veldrid/VeldridRenderer.cs
+++ b/osu.Framework/Graphics/Veldrid/VeldridRenderer.cs
@@ -547,7 +547,6 @@ public void DrawVertices(PrimitiveTopology type, int vertexStart, int verticesCo
var veldridShader = (VeldridShader)Shader!;
veldridShader.BindUniformBlock("g_GlobalUniforms", GlobalUniformBuffer!);
- veldridShader.BindUniformBlock("g_MaskingBuffer", ShaderMaskingStack!.CurrentBuffer);
pipeline.PrimitiveTopology = type;
Array.Resize(ref pipeline.ResourceLayouts, veldridShader.LayoutCount);
diff --git a/osu.Framework/Resources/Shaders/Internal/sh_GlobalUniforms.h b/osu.Framework/Resources/Shaders/Internal/sh_GlobalUniforms.h
index d7843cf5f9..514c2dcb88 100644
--- a/osu.Framework/Resources/Shaders/Internal/sh_GlobalUniforms.h
+++ b/osu.Framework/Resources/Shaders/Internal/sh_GlobalUniforms.h
@@ -19,6 +19,19 @@ layout(std140, set = -1, binding = 0) uniform g_GlobalUniforms
bool g_IsUvOriginTopLeft;
mat4 g_ProjMatrix;
+ mat3 g_ToMaskingSpace;
+
+ bool g_IsMasking;
+ highp float g_CornerRadius;
+ highp float g_CornerExponent;
+ highp vec4 g_MaskingRect;
+ highp float g_BorderThickness;
+ lowp mat4 g_BorderColour;
+ mediump float g_MaskingBlendRange;
+ lowp float g_AlphaExponent;
+ highp vec2 g_EdgeOffset;
+ bool g_DiscardInner;
+ highp float g_InnerCornerRadius;
// 0 -> None
// 1 -> ClampToEdge
diff --git a/osu.Framework/Resources/Shaders/Internal/sh_MaskingInfo.h b/osu.Framework/Resources/Shaders/Internal/sh_MaskingInfo.h
deleted file mode 100644
index 64b94cb266..0000000000
--- a/osu.Framework/Resources/Shaders/Internal/sh_MaskingInfo.h
+++ /dev/null
@@ -1,52 +0,0 @@
-#ifndef INTERNAL_MASKING_INFO_H
-#define INTERNAL_MASKING_INFO_H
-
-#extension GL_ARB_shader_storage_buffer_object : enable
-
-struct MaskingInfo
-{
- mat4 ToMaskingSpace;
- mat4 ToScissorSpace;
-
- bool IsMasking;
- highp float CornerRadius;
- highp float CornerExponent;
- highp float BorderThickness;
-
- highp vec4 MaskingRect;
- highp vec4 ScissorRect;
-
- lowp mat4 BorderColour;
- mediump float MaskingBlendRange;
- lowp float AlphaExponent;
- highp vec2 EdgeOffset;
-
- bool DiscardInner;
- highp float InnerCornerRadius;
- vec2 pad1;
-};
-
-MaskingInfo g_MaskingInfo;
-
-#ifndef OSU_GRAPHICS_NO_SSBO
-
-layout(std140, set = -2, binding = 0) readonly buffer g_MaskingBuffer
-{
- MaskingInfo Data[];
-} MaskingBuffer;
-
-#else // OSU_GRAPHICS_NO_SSBO
-
-layout(std140, set = -2, binding = 0) uniform g_MaskingBuffer
-{
- MaskingInfo Data[60];
-} MaskingBuffer;
-
-#endif // OSU_GRAPHICS_NO_SSBO
-
-void InitMasking(int index)
-{
- g_MaskingInfo = MaskingBuffer.Data[index];
-}
-
-#endif // INTERNAL_MASKING_INFO_H
\ No newline at end of file
diff --git a/osu.Framework/Resources/Shaders/sh_Masking.h b/osu.Framework/Resources/Shaders/sh_Masking.h
index cc71a80321..3fdc6c8846 100644
--- a/osu.Framework/Resources/Shaders/sh_Masking.h
+++ b/osu.Framework/Resources/Shaders/sh_Masking.h
@@ -1,8 +1,6 @@
#ifndef MASKING_H
#define MASKING_H
-#include "Internal/sh_MaskingInfo.h"
-
layout(location = 0) in highp vec2 v_MaskingPosition;
layout(location = 1) in lowp vec4 v_Colour;
@@ -13,27 +11,14 @@ layout(location = 1) in lowp vec4 v_Colour;
#endif
layout(location = 4) in mediump vec2 v_BlendRange;
-layout(location = 5) flat in int v_MaskingIndex;
-layout(location = 6) in highp vec2 v_ScissorPosition;
-
-/// Positive if outside the rect, negative if inside the rect.
-highp float distanceFromScissorRect()
-{
- highp vec2 topLeftOffset = g_MaskingInfo.ScissorRect.xy - v_ScissorPosition;
- highp vec2 bottomRightOffset = v_ScissorPosition - g_MaskingInfo.ScissorRect.zw;
-
- highp vec2 distanceFromShrunkRect = max(bottomRightOffset, topLeftOffset);
-
- return max(distanceFromShrunkRect.x, distanceFromShrunkRect.y);
-}
highp float distanceFromRoundedRect(highp vec2 offset, highp float radius)
{
highp vec2 maskingPosition = v_MaskingPosition + offset;
// Compute offset distance from masking rect in masking space.
- highp vec2 topLeftOffset = g_MaskingInfo.MaskingRect.xy - maskingPosition;
- highp vec2 bottomRightOffset = maskingPosition - g_MaskingInfo.MaskingRect.zw;
+ highp vec2 topLeftOffset = g_MaskingRect.xy - maskingPosition;
+ highp vec2 bottomRightOffset = maskingPosition - g_MaskingRect.zw;
highp vec2 distanceFromShrunkRect = max(
bottomRightOffset + vec2(radius),
@@ -48,7 +33,7 @@ highp float distanceFromRoundedRect(highp vec2 offset, highp float radius)
else
{
distanceFromShrunkRect = max(vec2(0.0), distanceFromShrunkRect);
- return pow(pow(distanceFromShrunkRect.x, g_MaskingInfo.CornerExponent) + pow(distanceFromShrunkRect.y, g_MaskingInfo.CornerExponent), 1.0 / g_MaskingInfo.CornerExponent);
+ return pow(pow(distanceFromShrunkRect.x, g_CornerExponent) + pow(distanceFromShrunkRect.y, g_CornerExponent), 1.0 / g_CornerExponent);
}
}
@@ -70,53 +55,46 @@ highp float distanceFromDrawingRect(mediump vec2 texCoord)
lowp vec4 getBorderColour()
{
- highp vec2 relativeTexCoord = v_MaskingPosition / (g_MaskingInfo.MaskingRect.zw - g_MaskingInfo.MaskingRect.xy);
- lowp vec4 top = mix(g_MaskingInfo.BorderColour[0], g_MaskingInfo.BorderColour[2], relativeTexCoord.x);
- lowp vec4 bottom = mix(g_MaskingInfo.BorderColour[1], g_MaskingInfo.BorderColour[3], relativeTexCoord.x);
+ highp vec2 relativeTexCoord = v_MaskingPosition / (g_MaskingRect.zw - g_MaskingRect.xy);
+ lowp vec4 top = mix(g_BorderColour[0], g_BorderColour[2], relativeTexCoord.x);
+ lowp vec4 bottom = mix(g_BorderColour[1], g_BorderColour[3], relativeTexCoord.x);
return mix(top, bottom, relativeTexCoord.y);
}
lowp vec4 getRoundedColor(lowp vec4 texel, mediump vec2 texCoord)
{
- InitMasking(v_MaskingIndex);
-
- if (!g_MaskingInfo.IsMasking && v_BlendRange == vec2(0.0))
+ if (!g_IsMasking && v_BlendRange == vec2(0.0))
{
return v_Colour * texel;
}
- if (distanceFromScissorRect() > 0)
- {
- discard;
- }
-
- highp float dist = distanceFromRoundedRect(vec2(0.0), g_MaskingInfo.CornerRadius);
+ highp float dist = distanceFromRoundedRect(vec2(0.0), g_CornerRadius);
lowp float alphaFactor = 1.0;
// Discard inner pixels
- if (g_MaskingInfo.DiscardInner)
+ if (g_DiscardInner)
{
- highp float innerDist = (g_MaskingInfo.EdgeOffset == vec2(0.0) && g_MaskingInfo.InnerCornerRadius == g_MaskingInfo.CornerRadius) ?
- dist : distanceFromRoundedRect(g_MaskingInfo.EdgeOffset, g_MaskingInfo.InnerCornerRadius);
+ highp float innerDist = (g_EdgeOffset == vec2(0.0) && g_InnerCornerRadius == g_CornerRadius) ?
+ dist : distanceFromRoundedRect(g_EdgeOffset, g_InnerCornerRadius);
- // v_BlendRange is set from outside in a hacky way to tell us the g_MaskingInfo.MaskingBlendRange used for the rounded
+ // v_BlendRange is set from outside in a hacky way to tell us the g_MaskingBlendRange used for the rounded
// corners of the edge effect container itself. We can then derive the alpha factor for smooth inner edge
// effect from that.
- highp float innerBlendFactor = (g_MaskingInfo.InnerCornerRadius - g_MaskingInfo.MaskingBlendRange - innerDist) / v_BlendRange.x;
+ highp float innerBlendFactor = (g_InnerCornerRadius - g_MaskingBlendRange - innerDist) / v_BlendRange.x;
if (innerBlendFactor > 1.0)
{
return vec4(0.0);
}
- // We exponentiate our factor to exactly counteract the later exponentiation by g_MaskingInfo.AlphaExponent for a smoother inner border.
- alphaFactor = pow(min(1.0 - innerBlendFactor, 1.0), 1.0 / g_MaskingInfo.AlphaExponent);
+ // We exponentiate our factor to exactly counteract the later exponentiation by g_AlphaExponent for a smoother inner border.
+ alphaFactor = pow(min(1.0 - innerBlendFactor, 1.0), 1.0 / g_AlphaExponent);
}
- dist /= g_MaskingInfo.MaskingBlendRange;
+ dist /= g_MaskingBlendRange;
// This correction is needed to avoid fading of the alpha value for radii below 1px.
- highp float radiusCorrection = g_MaskingInfo.CornerRadius <= 0.0 ? g_MaskingInfo.MaskingBlendRange : max(0.0, g_MaskingInfo.MaskingBlendRange - g_MaskingInfo.CornerRadius);
- highp float fadeStart = (g_MaskingInfo.CornerRadius + radiusCorrection) / g_MaskingInfo.MaskingBlendRange;
+ highp float radiusCorrection = g_CornerRadius <= 0.0 ? g_MaskingBlendRange : max(0.0, g_MaskingBlendRange - g_CornerRadius);
+ highp float fadeStart = (g_CornerRadius + radiusCorrection) / g_MaskingBlendRange;
alphaFactor *= min(fadeStart - dist, 1.0);
if (v_BlendRange.x > 0.0 || v_BlendRange.y > 0.0)
@@ -130,9 +108,9 @@ lowp vec4 getRoundedColor(lowp vec4 texel, mediump vec2 texCoord)
}
// This ends up softening glow without negatively affecting edge smoothness much.
- alphaFactor = pow(alphaFactor, g_MaskingInfo.AlphaExponent);
+ alphaFactor = pow(alphaFactor, g_AlphaExponent);
- highp float borderStart = 1.0 + fadeStart - g_MaskingInfo.BorderThickness;
+ highp float borderStart = 1.0 + fadeStart - g_BorderThickness;
lowp float colourWeight = min(borderStart - dist, 1.0);
lowp vec4 contentColour = v_Colour * texel;
diff --git a/osu.Framework/Resources/Shaders/sh_Texture2D.vs b/osu.Framework/Resources/Shaders/sh_Texture2D.vs
index b607200ddd..5024d59c47 100644
--- a/osu.Framework/Resources/Shaders/sh_Texture2D.vs
+++ b/osu.Framework/Resources/Shaders/sh_Texture2D.vs
@@ -2,7 +2,6 @@
#define TEXTURE2D_VS
#include "sh_Utils.h"
-#include "Internal/sh_MaskingInfo.h"
layout(location = 0) in highp vec2 m_Position;
layout(location = 1) in lowp vec4 m_Colour;
@@ -10,33 +9,23 @@ layout(location = 2) in highp vec2 m_TexCoord;
layout(location = 3) in highp vec4 m_TexRect;
layout(location = 4) in mediump vec2 m_BlendRange;
layout(location = 5) in highp float m_BackbufferDrawDepth;
-layout(location = 6) in int m_MaskingIndex;
layout(location = 0) out highp vec2 v_MaskingPosition;
layout(location = 1) out lowp vec4 v_Colour;
layout(location = 2) out highp vec2 v_TexCoord;
layout(location = 3) out highp vec4 v_TexRect;
layout(location = 4) out mediump vec2 v_BlendRange;
-layout(location = 5) flat out int v_MaskingIndex;
-layout(location = 6) out highp vec2 v_ScissorPosition;
void main(void)
{
- InitMasking(m_MaskingIndex);
-
// Transform from screen space to masking space.
- highp vec4 maskingPos = g_MaskingInfo.ToMaskingSpace * vec4(m_Position, 1.0, 0.0);
+ highp vec3 maskingPos = g_ToMaskingSpace * vec3(m_Position, 1.0);
v_MaskingPosition = maskingPos.xy / maskingPos.z;
- // Transform from screen space to scissor space.
- highp vec4 scissorPos = g_MaskingInfo.ToScissorSpace * vec4(m_Position, 1.0, 0.0);
- v_ScissorPosition = scissorPos.xy / scissorPos.z;
-
v_Colour = m_Colour;
v_TexCoord = m_TexCoord;
v_TexRect = m_TexRect;
v_BlendRange = m_BlendRange;
- v_MaskingIndex = m_MaskingIndex;
gl_Position = g_ProjMatrix * vec4(m_Position, 1.0, 1.0);
diff --git a/osu.Framework/Resources/Shaders/sh_Texture2D_NoMasking.vs b/osu.Framework/Resources/Shaders/sh_Texture2D_NoMasking.vs
deleted file mode 100644
index 652076e0b9..0000000000
--- a/osu.Framework/Resources/Shaders/sh_Texture2D_NoMasking.vs
+++ /dev/null
@@ -1,32 +0,0 @@
-#ifndef TEXTURE2D_NO_MASKING_VS
-#define TEXTURE2D_NO_MASKING_VS
-
-#include "sh_Utils.h"
-
-layout(location = 0) in highp vec2 m_Position;
-layout(location = 1) in lowp vec4 m_Colour;
-layout(location = 2) in highp vec2 m_TexCoord;
-layout(location = 3) in highp vec4 m_TexRect;
-layout(location = 4) in mediump vec2 m_BlendRange;
-layout(location = 5) in highp float m_BackbufferDrawDepth;
-
-layout(location = 0) out highp vec2 v_MaskingPosition;
-layout(location = 1) out lowp vec4 v_Colour;
-layout(location = 2) out highp vec2 v_TexCoord;
-layout(location = 3) out highp vec4 v_TexRect;
-layout(location = 4) out mediump vec2 v_BlendRange;
-
-void main(void)
-{
- v_Colour = m_Colour;
- v_TexCoord = m_TexCoord;
- v_TexRect = m_TexRect;
- v_BlendRange = m_BlendRange;
-
- gl_Position = g_ProjMatrix * vec4(m_Position, 1.0, 1.0);
-
- if (g_BackbufferDraw)
- gl_Position.z = m_BackbufferDrawDepth;
-}
-
-#endif
\ No newline at end of file
diff --git a/osu.Framework/Resources/Shaders/sh_Texture3D.vs b/osu.Framework/Resources/Shaders/sh_Texture3D.vs
index 4f64e01657..8b565d8008 100644
--- a/osu.Framework/Resources/Shaders/sh_Texture3D.vs
+++ b/osu.Framework/Resources/Shaders/sh_Texture3D.vs
@@ -2,39 +2,28 @@
#define TEXTURE3D_VS
#include "sh_Utils.h"
-#include "Internal/sh_MaskingInfo.h"
layout(location = 0) in highp vec3 m_Position;
layout(location = 1) in lowp vec4 m_Colour;
layout(location = 2) in highp vec2 m_TexCoord;
-layout(location = 3) in int m_MaskingIndex;
layout(location = 0) out highp vec2 v_MaskingPosition;
layout(location = 1) out lowp vec4 v_Colour;
layout(location = 2) out highp vec2 v_TexCoord;
layout(location = 3) out highp vec4 v_TexRect;
layout(location = 4) out mediump vec2 v_BlendRange;
-layout(location = 5) flat out int v_MaskingIndex;
-layout(location = 6) out highp vec2 v_ScissorPosition;
void main(void)
{
- InitMasking(m_MaskingIndex);
-
- // Transform from screen space to masking space.
- highp vec4 maskingPos = g_MaskingInfo.ToMaskingSpace * vec4(m_Position.xy, 1.0, 0.0);
+ // Transform to position to masking space.
+ vec3 maskingPos = g_ToMaskingSpace * vec3(m_Position.xy, 1.0);
v_MaskingPosition = maskingPos.xy / maskingPos.z;
- // Transform from screen space to scissor space.
- highp vec4 scissorPos = g_MaskingInfo.ToScissorSpace * vec4(m_Position.xy, 1.0, 0.0);
- v_ScissorPosition = scissorPos.xy / scissorPos.z;
-
v_TexRect = vec4(0.0);
v_BlendRange = vec2(0.0);
+
v_Colour = m_Colour;
v_TexCoord = m_TexCoord;
- v_MaskingIndex = m_MaskingIndex;
-
gl_Position = g_ProjMatrix * vec4(m_Position, 1.0);
}