-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathSpriteRenderer.cs
96 lines (85 loc) · 3.97 KB
/
SpriteRenderer.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
using System;
using Veldrid;
using VeldridGen.Example.Engine;
using VeldridGen.Example.Engine.Visual;
using VeldridGen.Example.Engine.Visual.Sprites;
using VeldridGen.Interfaces;
namespace VeldridGen.Example.SpriteRenderer
{
public sealed class SpriteRenderer : Component, IRenderer, IDisposable
{
readonly MultiBuffer<Vertex2DTextured> _vertexBuffer;
readonly MultiBuffer<ushort> _indexBuffer;
readonly SpritePipeline _pipeline;
readonly SpritePipeline _noCullPipeline;
static readonly ushort[] Indices = { 0, 1, 2, 2, 1, 3 };
static readonly Vertex2DTextured[] Vertices =
{
new(-0.5f, 0.0f, 0.0f, 0.0f), new(0.5f, 0.0f, 1.0f, 0.0f),
new(-0.5f, 1.0f, 0.0f, 1.0f), new(0.5f, 1.0f, 1.0f, 1.0f),
};
public SpriteRenderer(IFramebufferHolder framebuffer)
{
_vertexBuffer = new MultiBuffer<Vertex2DTextured>(Vertices, BufferUsage.VertexBuffer, "SpriteVertexBuffer");
_indexBuffer = new MultiBuffer<ushort>(Indices, BufferUsage.IndexBuffer, "SpriteIndexBuffer");
_pipeline = BuildPipeline(DepthStencilStateDescription.DepthOnlyLessEqual, framebuffer);
_noCullPipeline = BuildPipeline(DepthStencilStateDescription.Disabled, framebuffer);
AttachChild(_vertexBuffer);
AttachChild(_indexBuffer);
AttachChild(_pipeline);
AttachChild(_noCullPipeline);
}
static SpritePipeline BuildPipeline(DepthStencilStateDescription depthMode, IFramebufferHolder framebuffer)
{
return new()
{
Name = "P:Sprite",
AlphaBlend = BlendStateDescription.SingleAlphaBlend,
CullMode = FaceCullMode.None,
DepthStencilMode = depthMode,
FillMode = PolygonFillMode.Solid,
Framebuffer = framebuffer,
Topology = PrimitiveTopology.TriangleList,
UseDepthTest = true,
UseScissorTest = true,
Winding = FrontFace.Clockwise,
};
}
public void Render(IRenderable renderable, CommonSet commonSet, IFramebufferHolder framebuffer, CommandList cl,
GraphicsDevice device)
{
if (cl == null) throw new ArgumentNullException(nameof(cl));
if (commonSet == null) throw new ArgumentNullException(nameof(commonSet));
if (framebuffer == null) throw new ArgumentNullException(nameof(framebuffer));
if (renderable is not VeldridSpriteBatch batch)
throw new ArgumentException($"{GetType().Name} was passed renderable of unexpected type {renderable?.GetType().Name ?? "null"}", nameof(renderable));
cl.PushDebugGroup(batch.Name);
if (batch.Key.ScissorRegion.HasValue)
{
var rect = batch.Key.ScissorRegion.Value;
cl.SetScissorRect(0, (uint)rect.X, (uint)rect.Y, (uint)rect.Width, (uint)rect.Height);
}
cl.SetPipeline(
(batch.Key.Flags & SpriteKeyFlags.NoDepthTest) != 0
? _noCullPipeline.Pipeline
: _pipeline.Pipeline);
cl.SetGraphicsResourceSet(0, commonSet.ResourceSet);
cl.SetGraphicsResourceSet(1, batch.SpriteResources.ResourceSet);
cl.SetVertexBuffer(0, _vertexBuffer.DeviceBuffer);
cl.SetVertexBuffer(1, batch.Instances.DeviceBuffer);
cl.SetIndexBuffer(_indexBuffer.DeviceBuffer, IndexFormat.UInt16);
cl.SetFramebuffer(framebuffer.Framebuffer);
cl.DrawIndexed((uint)Indices.Length, (uint)batch.ActiveInstances, 0, 0, 0);
if (batch.Key.ScissorRegion.HasValue)
cl.SetFullScissorRect(0);
cl.PopDebugGroup();
}
public void Dispose()
{
_vertexBuffer.Dispose();
_indexBuffer.Dispose();
_pipeline.Dispose();
_noCullPipeline.Dispose();
}
}
}