2022.805.0
Thanks for following along! This is a tagged release (2022.805.0).
Breaking changes
IRenderer
added as parameter to DrawNode
In order to allow the framework to interoperate with different rendering backends, all rendering functions are now performed through a new IRenderer
interface and parameter.
- DrawNode.Draw(Action<TexturedVertex2D> vertexAction);
+ DrawNode.Draw(IRenderer renderer);
- DrawNode.DrawOpaqueInterior(Action<TexturedVertex2D> vertexAction);
+ DrawNode.DrawOpaqueInterior(IRenderer renderer);
In places where the vertexAction
parameter was previously used (e.g. to draw textures), null
can be given as a parameter instead.
GLWrapper
removed, replaced by calls through IRenderer
The static GLWrapper
class has been removed, and all drawing functions should be performed via the new DrawNode
parameter instead. There is a 1-1 API correlation between the classes.
public class MyDrawNode : DrawNode
{
public override void Draw(IRenderer renderer)
{
base.Draw(renderer);
- GLWrapper.PushDepthInfo(...);
+ renderer.PushDepthInfo(...);
- GLWrapper.SetBlend(...);
+ renderer.SetBlend(...);
- GLWrapper.PopDepthInfo();
+ renderer.PopDepthInfo();
}
}
Texture.WhitePixel
has moved to IRenderer
For cases where it's used as a fallback texture, it can be retrieved by resolving an IRenderer
into the Drawable
class and accessing IRenderer.WhitePixel
.
public class MyDrawable : Drawable
{
+ [BackgroundDependencyLoader]
+ private void load(IRenderer renderer)
+ {
+ texture ??= renderer.WhitePixel;
+ }
private Texture texture;
public Texture Texture
{
- get => texture ?? Texture.WhitePixel;
+ get => texture;
set => texture = value;
}
}
Texture drawing methods moved from DrawNode
to IRenderer
extension methods
Appearing alongside IRenderer
is the new RendererExtensions
class providing helper methods for common drawing procedures.
public class MyDrawNode : DrawNode
{
public override void Draw(IRenderer renderer)
{
base.Draw(renderer);
- DrawQuad(renderer.WhitePixel, ...);
+ renderer.DrawQuad(renderer.WhitePixel, ...);
}
}
All of the following methods have been moved to this class:
DrawTriangle()
DrawQuad()
DrawClipped()
DrawFrameBuffer()
Textures must be created through the IRenderer
Resolve an IRenderer
into the Drawable
class and use IRenderer.CreateTexture()
method to create textures.
public class MyDrawable : Drawable
{
- private readonly Texture texture;
- public MyDrawable()
- {
- texture = new Texture(100, 100);
- texture.SetData(...);
- }
+ private Texture texture;
+ [BackgroundDependencyLoader]
+ private void load(IRenderer renderer)
+ {
+ texture = renderer.CreateTexture(100, 100);
+ texture.SetData(...);
+ }
}
DummyRenderer
may be used for cases where textures need to be created and neither an IRenderer
nor GameHost
is accessible:
[TestFixture]
public class MyTestFixture
{
public void CreateATexture()
{
- Texture texture = new Texture(1, 1);
+ Texture texture = new DummyRenderer().CreateTexture(1, 1);
}
}
TextureGL
is no longer accessible
Properties such as TextureGL.BypassTextureUploadQueueing
have been moved to Texture
itself, and Texture
can be used for all rendering procedures. When rendering, textures are now bound to different sampling units via an integer value.
public class MyDrawable : Drawable
{
private Texture texture;
[BackgroundDependencyLoader]
private void load(IRenderer renderer)
{
texture = renderer.CreateTexture(100, 100);
- texture.TextureGL.BypassUploadQueueing = true;
+ texture.BypassUploadQueueing = true;
texture.SetData(...);
}
}
public class MyDrawNode : DrawNode
{
private Texture texture;
public override void Draw(IRenderer renderer)
{
base.Draw(renderer);
- texture.TextureGL.Bind();
- texture.TextureGL.Bind(TextureUnit.Texture1);
+ texture.Bind();
+ texture.Bind(1);
// Note: The texture binding above isn't required in either case for the call below.
- DrawQuad(texture.TextureGL, ...);
+ renderer.DrawQuad(texture, ...);
}
}
The QuadBatch<T>
and LinearBatch<T>
classes are no longer accessible
Create vertex batches via the IRenderer
and store as an IVertexBatch<T>
instead:
public class MyDrawNode : DrawNode
{
- private readonly QuadBatch<TexturedVertex2D> quadBatch = new QuadBatch<TexturedVertex2D>(1, 1);
- private readonly LinearBatch<TexturedVertex2D> linearBatch = new LinearBatch<TexturedVertex2D>(1, 1, PrimitiveType.Triangles);
+ private IVertexBatch<TexturedVertex2D> quadBatch;
+ private IVertexBatch<TexturedVertex2D> linearBatch;
public override void Draw(IRenderer renderer)
{
base.Draw(renderer);
+ quadBatch ??= renderer.CreateQuadBatch<TexturedVertex2D>(1, 1);
+ linearBatch ??= renderer.CreateLinearBatch<TexturedVertex2D>(1, 1, PrimitiveTopology.Triangles);
}
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
batch?.Dispose();
}
}
Beware that when creating linear batches, the type parameter has changed from PrimitiveType
to PrimitiveTopology
!
The FrameBuffer
class is no longer accessible
Create frame buffers via the IRenderer
and store as an IFrameBuffer
.
public class MyDrawNode : DrawNode
{
- private readonly FrameBuffer myFrameBuffer = new FrameBuffer(new[] { RenderbufferInternalFormat.DepthComponent16 }, All.Nearest);
+ private IFrameBuffer myFrameBuffer;
public override void Draw(IRenderer renderer)
{
base.Draw(renderer);
+ myFrameBuffer ??= renderer.CreateFrameBuffer(new[] { RenderBufferFormat.D16 }, TextureFilteringMode.Nearest);
}
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
myFrameBuffer?.Dispose();
}
}
Beware that the render buffer type parameter has changed from RenderbufferInternalFormat
to RenderBufferFormat
!
The Shader
class is no longer accessible
Shaders are still created via the ShaderManager
, but are now returned as IShader
s.
public class MyDrawable : Drawable
{
- private Shader shader;
+ private IShader shader;
[BackgroundDependencyLoader]
private void load(ShaderManager shaders)
{
shader = shaders.Load("a", "b");
}
}
TextureStore
, FontStore
and LargeTextureStore
require an IRenderer
constructor parameter
One common use case is to provide a new texture store from inside a derived Game
, for which the following change is required:
public class TestGame : osu.Framework.Game
{
private DependencyContainer dependencies;
protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent) =>
dependencies = new DependencyContainer(base.CreateChildDependencies(parent));
[BackgroundDependencyLoader]
private void load()
{
- var largeStore = new LargeTextureStore(Host.CreateTextureLoaderStore(new NamespacedResourceStore<byte[]>(Resources, @"Textures")), All.Nearest);
+ var largeStore = new LargeTextureStore(Host.Renderer, Host.CreateTextureLoaderStore(new NamespacedResourceStore<byte[]>(Resources, @"Textures")), TextureFilteringMode.Nearest);
largeStore.AddTextureSource(Host.CreateTextureLoaderStore(new OnlineStore()));
dependencies.Cache(largeStore);
}
}
Beware that the filter mode parameter has changed from All
to TextureFilteringMode
!
Some TexturedShaderDrawNode
members now take an IRenderer
parameter
public class MyDrawNode : TexturedShaderDrawNode
{
public override void Draw(IRenderer renderer)
{
base.Draw(renderer);
- Shader.Bind();
+ var shader = GetAppropriateShader(renderer);
+ shader.Bind();
// ...
- Shader.Unbind();
+ shader.Unbind();
}
- protected override bool RequiresRoundedShader => ...;
+ protected override bool RequiresRoundedShader(IRenderer renderer) => ...;
}
IVertex
, TexturedVertex2D
, et al. have been re-namespaced
They are now placed under the osu.Framework.Graphics.Rendering.Vertices
namespace
Several enums have been re-namespaced
WrapMode -> osu.Framework.Graphics.Textures.WrapMode
Opacity -> osu.Framework.Graphics.Textures.Opacity
ClearInfo -> osu.Framework.Graphics.Rendering.ClearInfo
MaskingInfo -> osu.Framework.Graphics.Rendering.MaskingInfo
DepthInfo -> osu.Framework.Graphics.Rendering.DepthInfo
What's Changed
- Add
IRenderer
and adjustDrawNode
signature by @smoogipoo in #5324 - Fix
ModelBackedDrawable
attempting to mutate children after disposal by @peppy in #5329 - Internalise vertex batches and expose via
IVertexBatch
by @smoogipoo in #5325 - Internalise
FrameBuffer
and expose viaIFrameBuffer
by @smoogipoo in #5326 - Internalise
Shader
and expose viaIShader
by @smoogipoo in #5327 - Guard against work being queued on an already-disposed
ThreadedTaskScheduler
by @peppy in #5320 - Fix textbox initial commit of empty string being considered "new" due to null equality by @peppy in #5331
- Internalise
TextureGL
and rewriteTexture
to take its role by @smoogipoo in #5330 - Fix GetLocalisableDescription() crashing on unnamed enum values by @smoogipoo in #5335
- Remove
GLWrapper
and move implementation toIRenderer
by @smoogipoo in #5332 - Fix
TestBrowser
potentially crashing from null ref on quickly switching scenes by @peppy in #5333 - Safely restore TPL capacity after test failures by @smoogipoo in #5334
- Android input handlers refactor by @Susko3 in #5317
- Move vertices out of the OpenGL namespace by @smoogipoo in #5336
Full Changelog: 2022.730.0...2022.805.0