update for render pass ABI break

main
cosmonaut 2022-02-24 21:32:44 -08:00
parent 94f463002d
commit a828f510af
5 changed files with 351 additions and 352 deletions

View File

@ -2,7 +2,7 @@
<PropertyGroup> <PropertyGroup>
<OutputType>Exe</OutputType> <OutputType>Exe</OutputType>
<TargetFramework>net5.0</TargetFramework> <TargetFramework>net6.0</TargetFramework>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks> <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup> </PropertyGroup>

@ -1 +1 @@
Subproject commit cb25e6feff2d9ac3f399b3a43cd11d374f90f127 Subproject commit b8b10140a95457a00d658e84d4b67b926f467b15

BIN
moonlibs/lib64/libRefresh.so.0 (Stored with Git LFS)

Binary file not shown.

View File

@ -5,185 +5,184 @@ using MoonWorks.Math;
namespace MoonWorksComputeSpriteBatch namespace MoonWorksComputeSpriteBatch
{ {
[StructLayout(LayoutKind.Sequential)] [StructLayout(LayoutKind.Sequential)]
public struct SpriteBatchUniforms public struct SpriteBatchUniforms
{ {
public uint VertexCount { get; set; } public uint VertexCount { get; set; }
} }
public class SpriteBatch public class SpriteBatch
{ {
public const int MAX_SPRITES = 65536; public const int MAX_SPRITES = 65536;
private const int MAX_VERTICES = MAX_SPRITES * 4; private const int MAX_VERTICES = MAX_SPRITES * 4;
private const int MAX_INDICES = MAX_SPRITES * 6; private const int MAX_INDICES = MAX_SPRITES * 6;
private const int MAX_MATRICES = MAX_SPRITES; private const int MAX_MATRICES = MAX_SPRITES;
private static ComputePipeline ComputePipeline = null; private static ComputePipeline ComputePipeline = null;
private Buffer VertexBuffer { get; } private Buffer VertexBuffer { get; }
private Buffer IndexBuffer { get; } private Buffer IndexBuffer { get; }
private Buffer TransformBuffer { get; } private Buffer TransformBuffer { get; }
private readonly VertexPositionTexcoord[] Vertices; private readonly VertexPositionTexcoord[] Vertices;
private static readonly short[] Indices = GenerateIndexArray(); private static readonly short[] Indices = GenerateIndexArray();
private readonly Matrix4x4[] Transforms; private readonly Matrix4x4[] Transforms;
private Texture CurrentTexture { get; set; } private Texture CurrentTexture { get; set; }
private Sampler CurrentSampler { get; set; } private Sampler CurrentSampler { get; set; }
private uint VertexCount { get; set; } private uint VertexCount { get; set; }
private uint TransformCount { get; set; } private uint TransformCount { get; set; }
public SpriteBatch(GraphicsDevice graphicsDevice) public SpriteBatch(GraphicsDevice graphicsDevice)
{ {
if (ComputePipeline == null) if (ComputePipeline == null)
{ {
var computeShaderModule = new ShaderModule(graphicsDevice, Path.Combine(System.Environment.CurrentDirectory, "Content", "spritebatch.comp.spv")); var computeShaderModule = new ShaderModule(graphicsDevice, Path.Combine(System.Environment.CurrentDirectory, "Content", "spritebatch.comp.spv"));
var computeShaderState = new ShaderStageState var computeShaderState = new ShaderStageState
{ {
ShaderModule = computeShaderModule, ShaderModule = computeShaderModule,
EntryPointName = "main", EntryPointName = "main",
UniformBufferSize = (uint) Marshal.SizeOf<SpriteBatchUniforms>() UniformBufferSize = (uint)Marshal.SizeOf<SpriteBatchUniforms>()
}; };
ComputePipeline = new ComputePipeline(graphicsDevice, computeShaderState, 2, 0); ComputePipeline = new ComputePipeline(graphicsDevice, computeShaderState, 2, 0);
} }
Vertices = new VertexPositionTexcoord[MAX_VERTICES]; Vertices = new VertexPositionTexcoord[MAX_VERTICES];
VertexBuffer = new Buffer( VertexBuffer = new Buffer(
graphicsDevice, graphicsDevice,
BufferUsageFlags.Vertex | BufferUsageFlags.Compute, BufferUsageFlags.Vertex | BufferUsageFlags.Compute,
(uint)(MAX_VERTICES * Marshal.SizeOf<VertexPositionTexcoord>()) (uint)(MAX_VERTICES * Marshal.SizeOf<VertexPositionTexcoord>())
); );
IndexBuffer = new Buffer( IndexBuffer = new Buffer(
graphicsDevice, graphicsDevice,
BufferUsageFlags.Index | BufferUsageFlags.Compute, BufferUsageFlags.Index | BufferUsageFlags.Compute,
MAX_INDICES * sizeof(short) MAX_INDICES * sizeof(short)
); );
Transforms = new Matrix4x4[MAX_MATRICES]; Transforms = new Matrix4x4[MAX_MATRICES];
TransformBuffer = new Buffer( TransformBuffer = new Buffer(
graphicsDevice, graphicsDevice,
BufferUsageFlags.Compute, BufferUsageFlags.Compute,
(uint)(MAX_MATRICES * Marshal.SizeOf<Matrix4x4>()) (uint)(MAX_MATRICES * Marshal.SizeOf<Matrix4x4>())
); );
var commandBuffer = graphicsDevice.AcquireCommandBuffer(); var commandBuffer = graphicsDevice.AcquireCommandBuffer();
commandBuffer.SetBufferData(IndexBuffer, Indices); commandBuffer.SetBufferData(IndexBuffer, Indices);
graphicsDevice.Submit(commandBuffer); graphicsDevice.Submit(commandBuffer);
} }
public void Start(Texture texture, Sampler sampler) public void Start(Texture texture, Sampler sampler)
{ {
TransformCount = 0; TransformCount = 0;
VertexCount = 0; VertexCount = 0;
CurrentTexture = texture; CurrentTexture = texture;
CurrentSampler = sampler; CurrentSampler = sampler;
} }
public void Add(Sprite sprite, Matrix4x4 transform, Color color) public void Add(Sprite sprite, Matrix4x4 transform, Color color)
{ {
Vertices[VertexCount].position.X = 0; Vertices[VertexCount].position.X = 0;
Vertices[VertexCount].position.Y = 0; Vertices[VertexCount].position.Y = 0;
Vertices[VertexCount].texcoord.X = sprite.Texcoord.X; Vertices[VertexCount].texcoord.X = sprite.Texcoord.X;
Vertices[VertexCount].texcoord.Y = sprite.Texcoord.Y; Vertices[VertexCount].texcoord.Y = sprite.Texcoord.Y;
Vertices[VertexCount].color.X = color.R / 255f; Vertices[VertexCount].color.X = color.R / 255f;
Vertices[VertexCount].color.Y = color.G / 255f; Vertices[VertexCount].color.Y = color.G / 255f;
Vertices[VertexCount].color.Z = color.B / 255f; Vertices[VertexCount].color.Z = color.B / 255f;
Vertices[VertexCount].color.W = color.A / 255f; Vertices[VertexCount].color.W = color.A / 255f;
Vertices[VertexCount + 1].position.X = sprite.Width; Vertices[VertexCount + 1].position.X = sprite.Width;
Vertices[VertexCount + 1].position.Y = 0; Vertices[VertexCount + 1].position.Y = 0;
Vertices[VertexCount + 1].texcoord.X = sprite.Texcoord.X + sprite.Texcoord.W; Vertices[VertexCount + 1].texcoord.X = sprite.Texcoord.X + sprite.Texcoord.W;
Vertices[VertexCount + 1].texcoord.Y = sprite.Texcoord.Y; Vertices[VertexCount + 1].texcoord.Y = sprite.Texcoord.Y;
Vertices[VertexCount + 1].color.X = color.R / 255f; Vertices[VertexCount + 1].color.X = color.R / 255f;
Vertices[VertexCount + 1].color.Y = color.G / 255f; Vertices[VertexCount + 1].color.Y = color.G / 255f;
Vertices[VertexCount + 1].color.Z = color.B / 255f; Vertices[VertexCount + 1].color.Z = color.B / 255f;
Vertices[VertexCount + 1].color.W = color.A / 255f; Vertices[VertexCount + 1].color.W = color.A / 255f;
Vertices[VertexCount + 2].position.X = 0; Vertices[VertexCount + 2].position.X = 0;
Vertices[VertexCount + 2].position.Y = sprite.Height; Vertices[VertexCount + 2].position.Y = sprite.Height;
Vertices[VertexCount + 2].texcoord.X = sprite.Texcoord.X; Vertices[VertexCount + 2].texcoord.X = sprite.Texcoord.X;
Vertices[VertexCount + 2].texcoord.Y = sprite.Texcoord.Y + sprite.Texcoord.H; Vertices[VertexCount + 2].texcoord.Y = sprite.Texcoord.Y + sprite.Texcoord.H;
Vertices[VertexCount + 2].color.X = color.R / 255f; Vertices[VertexCount + 2].color.X = color.R / 255f;
Vertices[VertexCount + 2].color.Y = color.G / 255f; Vertices[VertexCount + 2].color.Y = color.G / 255f;
Vertices[VertexCount + 2].color.Z = color.B / 255f; Vertices[VertexCount + 2].color.Z = color.B / 255f;
Vertices[VertexCount + 2].color.W = color.A / 255f; Vertices[VertexCount + 2].color.W = color.A / 255f;
Vertices[VertexCount + 3].position.X = sprite.Width; Vertices[VertexCount + 3].position.X = sprite.Width;
Vertices[VertexCount + 3].position.Y = sprite.Height; Vertices[VertexCount + 3].position.Y = sprite.Height;
Vertices[VertexCount + 3].texcoord.X = sprite.Texcoord.X + sprite.Texcoord.W; Vertices[VertexCount + 3].texcoord.X = sprite.Texcoord.X + sprite.Texcoord.W;
Vertices[VertexCount + 3].texcoord.Y = sprite.Texcoord.Y + sprite.Texcoord.H; Vertices[VertexCount + 3].texcoord.Y = sprite.Texcoord.Y + sprite.Texcoord.H;
Vertices[VertexCount + 3].color.X = color.R / 255f; Vertices[VertexCount + 3].color.X = color.R / 255f;
Vertices[VertexCount + 3].color.Y = color.G / 255f; Vertices[VertexCount + 3].color.Y = color.G / 255f;
Vertices[VertexCount + 3].color.Z = color.B / 255f; Vertices[VertexCount + 3].color.Z = color.B / 255f;
Vertices[VertexCount + 3].color.W = color.A / 255f; Vertices[VertexCount + 3].color.W = color.A / 255f;
VertexCount += 4; VertexCount += 4;
Transforms[TransformCount] = transform; Transforms[TransformCount] = transform;
TransformCount += 1; TransformCount += 1;
} }
public void Flush( public void Flush(
CommandBuffer commandBuffer, CommandBuffer commandBuffer,
RenderPass renderPass, ColorAttachmentInfo colorAttachmentInfo,
Framebuffer framebuffer, GraphicsPipeline graphicsPipeline,
Rect renderArea, CameraUniforms cameraUniforms
GraphicsPipeline graphicsPipeline, )
CameraUniforms cameraUniforms {
) { if (VertexCount == 0)
if (VertexCount == 0) {
{ return;
return; }
}
commandBuffer.SetBufferData(VertexBuffer, Vertices, 0, 0, VertexCount); commandBuffer.SetBufferData(VertexBuffer, Vertices, 0, 0, VertexCount);
commandBuffer.SetBufferData(TransformBuffer, Transforms, 0, 0, TransformCount); commandBuffer.SetBufferData(TransformBuffer, Transforms, 0, 0, TransformCount);
commandBuffer.BindComputePipeline(ComputePipeline); commandBuffer.BindComputePipeline(ComputePipeline);
commandBuffer.BindComputeBuffers(VertexBuffer, TransformBuffer); commandBuffer.BindComputeBuffers(VertexBuffer, TransformBuffer);
var offset = commandBuffer.PushComputeShaderUniforms(new SpriteBatchUniforms var offset = commandBuffer.PushComputeShaderUniforms(new SpriteBatchUniforms
{ {
VertexCount = VertexCount VertexCount = VertexCount
}); });
commandBuffer.DispatchCompute(System.Math.Max(1, VertexCount / 256), 1, 1, offset); commandBuffer.DispatchCompute(System.Math.Max(1, VertexCount / 256), 1, 1, offset);
commandBuffer.BeginRenderPass(renderPass, framebuffer, renderArea, Vector4.Zero); commandBuffer.BeginRenderPass(colorAttachmentInfo);
commandBuffer.BindGraphicsPipeline(graphicsPipeline); commandBuffer.BindGraphicsPipeline(graphicsPipeline);
commandBuffer.BindVertexBuffers(VertexBuffer); commandBuffer.BindVertexBuffers(VertexBuffer);
commandBuffer.BindIndexBuffer(IndexBuffer, IndexElementSize.Sixteen); commandBuffer.BindIndexBuffer(IndexBuffer, IndexElementSize.Sixteen);
commandBuffer.BindFragmentSamplers(new TextureSamplerBinding { Texture = CurrentTexture, Sampler = CurrentSampler }); commandBuffer.BindFragmentSamplers(new TextureSamplerBinding { Texture = CurrentTexture, Sampler = CurrentSampler });
offset = commandBuffer.PushVertexShaderUniforms(cameraUniforms); offset = commandBuffer.PushVertexShaderUniforms(cameraUniforms);
commandBuffer.DrawIndexedPrimitives( commandBuffer.DrawIndexedPrimitives(
0, 0,
0, 0,
VertexCount / 2, VertexCount / 2,
offset, offset,
0 0
); );
commandBuffer.EndRenderPass(); commandBuffer.EndRenderPass();
VertexCount = 0; VertexCount = 0;
TransformCount = 0; TransformCount = 0;
} }
private static short[] GenerateIndexArray() private static short[] GenerateIndexArray()
{ {
var result = new short[MAX_INDICES]; var result = new short[MAX_INDICES];
for (int i = 0, j = 0; i < MAX_INDICES; i += 6, j += 4) for (int i = 0, j = 0; i < MAX_INDICES; i += 6, j += 4)
{ {
result[i] = (short)j; result[i] = (short)j;
result[i + 1] = (short)(j + 1); result[i + 1] = (short)(j + 1);
result[i + 2] = (short)(j + 2); result[i + 2] = (short)(j + 2);
result[i + 3] = (short)(j + 2); result[i + 3] = (short)(j + 2);
result[i + 4] = (short)(j + 1); result[i + 4] = (short)(j + 1);
result[i + 5] = (short)(j + 3); result[i + 5] = (short)(j + 3);
} }
return result; return result;
} }
} }
} }

View File

@ -9,238 +9,238 @@ using MoonWorks.Window;
namespace MoonWorksComputeSpriteBatch namespace MoonWorksComputeSpriteBatch
{ {
public class TestGame : Game public class TestGame : Game
{ {
private RenderPass mainRenderPass; private RenderTarget mainColorTarget;
private RenderTarget mainColorTarget;
private Framebuffer mainFramebuffer;
private Rect mainRenderArea;
private GraphicsPipeline spritePipeline; private GraphicsPipeline spritePipeline;
private SpriteBatch spriteBatch; private SpriteBatch spriteBatch;
private Texture whitePixel; private Texture whitePixel;
private Sampler sampler; private Sampler sampler;
private const int SPRITECOUNT = SpriteBatch.MAX_SPRITES; private const int SPRITECOUNT = SpriteBatch.MAX_SPRITES;
private Vector3[] positions = new Vector3[SPRITECOUNT]; private Vector3[] positions = new Vector3[SPRITECOUNT];
private uint windowWidth; private uint windowWidth;
private uint windowHeight; private uint windowHeight;
private Random random = new Random(); private Random random = new Random();
public TestGame(WindowCreateInfo windowCreateInfo, PresentMode presentMode, int targetTimestep = 60, bool debugMode = false) : base(windowCreateInfo, presentMode, targetTimestep, debugMode) public TestGame(WindowCreateInfo windowCreateInfo, PresentMode presentMode, int targetTimestep = 60, bool debugMode = false) : base(windowCreateInfo, presentMode, targetTimestep, debugMode)
{ {
windowWidth = windowCreateInfo.WindowWidth; windowWidth = windowCreateInfo.WindowWidth;
windowHeight = windowCreateInfo.WindowHeight; windowHeight = windowCreateInfo.WindowHeight;
var vertexShaderModule = new ShaderModule(GraphicsDevice, Path.Combine(Environment.CurrentDirectory, "Content", "sprite.vert.spv")); var vertexShaderModule = new ShaderModule(GraphicsDevice, Path.Combine(Environment.CurrentDirectory, "Content", "sprite.vert.spv"));
var fragmentShaderModule = new ShaderModule(GraphicsDevice, Path.Combine(Environment.CurrentDirectory, "Content", "sprite.frag.spv")); var fragmentShaderModule = new ShaderModule(GraphicsDevice, Path.Combine(Environment.CurrentDirectory, "Content", "sprite.frag.spv"));
ColorTargetDescription colorTargetDescription = new ColorTargetDescription mainColorTarget = RenderTarget.CreateBackedRenderTarget(
{ GraphicsDevice,
Format = TextureFormat.R8G8B8A8, windowWidth,
MultisampleCount = SampleCount.One, windowHeight,
LoadOp = LoadOp.Clear, TextureFormat.R8G8B8A8,
StoreOp = StoreOp.Store false
}; );
mainRenderPass = new RenderPass(GraphicsDevice, colorTargetDescription); /* Pipeline */
mainColorTarget = RenderTarget.CreateBackedRenderTarget( ColorTargetBlendState[] colorTargetBlendStates = new ColorTargetBlendState[1]
GraphicsDevice, {
windowWidth, ColorTargetBlendState.None
windowHeight, };
TextureFormat.R8G8B8A8,
false
);
mainFramebuffer = new Framebuffer( ColorBlendState colorBlendState = new ColorBlendState
GraphicsDevice, {
windowWidth, LogicOpEnable = false,
windowHeight, LogicOp = LogicOp.NoOp,
mainRenderPass, BlendConstants = new BlendConstants(),
null, ColorTargetBlendStates = colorTargetBlendStates
mainColorTarget };
);
mainRenderArea = new Rect DepthStencilState depthStencilState = DepthStencilState.Disable;
{
X = 0,
Y = 0,
W = (int) windowWidth,
H = (int) windowHeight
};
/* Pipeline */ ShaderStageState vertexShaderState = new ShaderStageState
{
ShaderModule = vertexShaderModule,
EntryPointName = "main",
UniformBufferSize = (uint)Marshal.SizeOf<CameraUniforms>()
};
ColorTargetBlendState[] colorTargetBlendStates = new ColorTargetBlendState[1] ShaderStageState fragmentShaderState = new ShaderStageState
{ {
ColorTargetBlendState.None ShaderModule = fragmentShaderModule,
}; EntryPointName = "main",
UniformBufferSize = 0
};
ColorBlendState colorBlendState = new ColorBlendState MultisampleState multisampleState = MultisampleState.None;
{
LogicOpEnable = false,
LogicOp = LogicOp.NoOp,
BlendConstants = new BlendConstants(),
ColorTargetBlendStates = colorTargetBlendStates
};
DepthStencilState depthStencilState = DepthStencilState.Disable; GraphicsPipelineLayoutInfo pipelineLayoutInfo = new GraphicsPipelineLayoutInfo
{
VertexSamplerBindingCount = 0,
FragmentSamplerBindingCount = 1
};
ShaderStageState vertexShaderState = new ShaderStageState RasterizerState rasterizerState = RasterizerState.CCW_CullNone;
{
ShaderModule = vertexShaderModule,
EntryPointName = "main",
UniformBufferSize = (uint) Marshal.SizeOf<CameraUniforms>()
};
ShaderStageState fragmentShaderState = new ShaderStageState var vertexBindings = new VertexBinding[1]
{ {
ShaderModule = fragmentShaderModule, new VertexBinding
EntryPointName = "main", {
UniformBufferSize = 0 Binding = 0,
}; InputRate = VertexInputRate.Vertex,
Stride = (uint) Marshal.SizeOf<VertexPositionTexcoord>()
}
};
MultisampleState multisampleState = MultisampleState.None; var vertexAttributes = new VertexAttribute[3]
{
new VertexAttribute
{
Binding = 0,
Location = 0,
Format = VertexElementFormat.Vector3,
Offset = 0
},
new VertexAttribute
{
Binding = 0,
Location = 1,
Format = VertexElementFormat.Vector2,
Offset = (uint) Marshal.OffsetOf<VertexPositionTexcoord>("texcoord")
},
new VertexAttribute
{
Binding = 0,
Location = 2,
Format = VertexElementFormat.Vector4,
Offset = (uint) Marshal.OffsetOf<VertexPositionTexcoord>("color")
}
};
GraphicsPipelineLayoutInfo pipelineLayoutInfo = new GraphicsPipelineLayoutInfo VertexInputState vertexInputState = new VertexInputState
{ {
VertexSamplerBindingCount = 0, VertexBindings = vertexBindings,
FragmentSamplerBindingCount = 1 VertexAttributes = vertexAttributes
}; };
RasterizerState rasterizerState = RasterizerState.CCW_CullNone; var viewports = new Viewport[1]
{
new Viewport
{
X = 0,
Y = 0,
W = windowWidth,
H = windowHeight,
MinDepth = 0,
MaxDepth = 1
}
};
var vertexBindings = new VertexBinding[1] var scissors = new Rect[1]
{ {
new VertexBinding new Rect
{ {
Binding = 0, X = 0,
InputRate = VertexInputRate.Vertex, Y = 0,
Stride = (uint) Marshal.SizeOf<VertexPositionTexcoord>() W = (int) windowWidth,
} H = (int) windowHeight
}; }
};
var vertexAttributes = new VertexAttribute[3] ViewportState viewportState = new ViewportState
{ {
new VertexAttribute Viewports = viewports,
{ Scissors = scissors
Binding = 0, };
Location = 0,
Format = VertexElementFormat.Vector3,
Offset = 0
},
new VertexAttribute
{
Binding = 0,
Location = 1,
Format = VertexElementFormat.Vector2,
Offset = (uint) Marshal.OffsetOf<VertexPositionTexcoord>("texcoord")
},
new VertexAttribute
{
Binding = 0,
Location = 2,
Format = VertexElementFormat.Vector4,
Offset = (uint) Marshal.OffsetOf<VertexPositionTexcoord>("color")
}
};
VertexInputState vertexInputState = new VertexInputState var colorAttachmentDescriptions = new ColorAttachmentDescription[1]
{ {
VertexBindings = vertexBindings, new ColorAttachmentDescription
VertexAttributes = vertexAttributes {
}; format = TextureFormat.R8G8B8A8,
sampleCount = SampleCount.One
}
};
var viewports = new Viewport[1] GraphicsPipelineAttachmentInfo graphicsPipelineAttachmentInfo = new GraphicsPipelineAttachmentInfo
{ {
new Viewport colorAttachmentDescriptions = colorAttachmentDescriptions,
{ colorAttachmentCount = 1,
X = 0, hasDepthStencilAttachment = false,
Y = 0, depthStencilFormat = 0
W = windowWidth, };
H = windowHeight,
MinDepth = 0,
MaxDepth = 1
}
};
var scissors = new Rect[1] var graphicsPipelineCreateInfo = new GraphicsPipelineCreateInfo
{ {
new Rect ColorBlendState = colorBlendState,
{ DepthStencilState = depthStencilState,
X = 0, VertexShaderState = vertexShaderState,
Y = 0, FragmentShaderState = fragmentShaderState,
W = (int) windowWidth, MultisampleState = multisampleState,
H = (int) windowHeight PipelineLayoutInfo = pipelineLayoutInfo,
} RasterizerState = rasterizerState,
}; PrimitiveType = PrimitiveType.TriangleList,
VertexInputState = vertexInputState,
ViewportState = viewportState,
AttachmentInfo = graphicsPipelineAttachmentInfo
};
ViewportState viewportState = new ViewportState spritePipeline = new GraphicsPipeline(GraphicsDevice, graphicsPipelineCreateInfo);
{
Viewports = viewports,
Scissors = scissors
};
var graphicsPipelineCreateInfo = new GraphicsPipelineCreateInfo spriteBatch = new SpriteBatch(GraphicsDevice);
{
ColorBlendState = colorBlendState,
DepthStencilState = depthStencilState,
VertexShaderState = vertexShaderState,
FragmentShaderState = fragmentShaderState,
MultisampleState = multisampleState,
PipelineLayoutInfo = pipelineLayoutInfo,
RasterizerState = rasterizerState,
PrimitiveType = PrimitiveType.TriangleList,
VertexInputState = vertexInputState,
ViewportState = viewportState,
RenderPass = mainRenderPass
};
spritePipeline = new GraphicsPipeline(GraphicsDevice, graphicsPipelineCreateInfo); whitePixel = Texture.CreateTexture2D(GraphicsDevice, 1, 1, TextureFormat.R8G8B8A8, TextureUsageFlags.Sampler);
spriteBatch = new SpriteBatch(GraphicsDevice); var commandBuffer = GraphicsDevice.AcquireCommandBuffer();
commandBuffer.SetTextureData(whitePixel, new Color[] { Color.White });
GraphicsDevice.Submit(commandBuffer);
whitePixel = Texture.CreateTexture2D(GraphicsDevice, 1, 1, TextureFormat.R8G8B8A8, TextureUsageFlags.Sampler); sampler = new Sampler(GraphicsDevice, SamplerCreateInfo.PointWrap);
}
var commandBuffer = GraphicsDevice.AcquireCommandBuffer(); protected override void Update(TimeSpan dt)
commandBuffer.SetTextureData(whitePixel, new Color[] { Color.White }); {
GraphicsDevice.Submit(commandBuffer); for (var i = 0; i < SPRITECOUNT; i += 1)
{
positions[i].X = (float)(random.NextDouble() * windowWidth) - 64;
positions[i].Y = (float)(random.NextDouble() * windowHeight) - 64;
}
}
sampler = new Sampler(GraphicsDevice, SamplerCreateInfo.PointWrap); protected override void Draw(TimeSpan dt, double alpha)
} {
var commandBuffer = GraphicsDevice.AcquireCommandBuffer();
protected override void Update(TimeSpan dt) var viewProjection = Matrix4x4.CreateLookAt(new Vector3(windowWidth / 2, windowHeight / 2, 1), new Vector3(windowWidth / 2, windowHeight / 2, 0), Vector3.Up) * Matrix4x4.CreateOrthographic(windowWidth, windowHeight, 0.1f, 1000);
{ spriteBatch.Start(whitePixel, sampler);
for (var i = 0; i < SPRITECOUNT; i += 1)
{
positions[i].X = (float) (random.NextDouble() * windowWidth) - 64;
positions[i].Y = (float) (random.NextDouble() * windowHeight) - 64;
}
}
protected override void Draw(TimeSpan dt, double alpha) for (var i = 0; i < SPRITECOUNT; i += 1)
{ {
var commandBuffer = GraphicsDevice.AcquireCommandBuffer(); var transform = Matrix4x4.CreateTranslation(positions[i]);
var color = new Color((float)random.NextDouble(), (float)random.NextDouble(), (float)random.NextDouble(), 255f);
spriteBatch.Add(new Sprite(new Rect { X = 0, Y = 0, W = 0, H = 0 }, 128, 128), transform, color);
}
var viewProjection = Matrix4x4.CreateLookAt(new Vector3(windowWidth / 2, windowHeight / 2, 1), new Vector3(windowWidth / 2, windowHeight / 2, 0), Vector3.Up) * Matrix4x4.CreateOrthographic(windowWidth, windowHeight, 0.1f, 1000); var colorAttachmentInfo = new ColorAttachmentInfo
spriteBatch.Start(whitePixel, sampler); {
renderTarget = mainColorTarget,
clearColor = Color.Black,
loadOp = LoadOp.Clear,
storeOp = StoreOp.DontCare
};
for (var i = 0; i < SPRITECOUNT; i += 1) spriteBatch.Flush(commandBuffer, colorAttachmentInfo, spritePipeline, new CameraUniforms { viewProjectionMatrix = viewProjection });
{
var transform = Matrix4x4.CreateTranslation(positions[i]);
var color = new Color((float)random.NextDouble(), (float)random.NextDouble(), (float)random.NextDouble(), 255f);
spriteBatch.Add(new Sprite(new Rect { X = 0, Y = 0, W = 0, H = 0 }, 128, 128), transform, color);
}
spriteBatch.Flush(commandBuffer, mainRenderPass, mainFramebuffer, mainRenderArea, spritePipeline, new CameraUniforms { viewProjectionMatrix = viewProjection }); commandBuffer.QueuePresent(mainColorTarget.TextureSlice, Filter.Nearest, Window);
GraphicsDevice.Submit(commandBuffer);
}
commandBuffer.QueuePresent(mainColorTarget.TextureSlice, Filter.Nearest, Window); protected override void OnDestroy()
GraphicsDevice.Submit(commandBuffer); {
}
} }
}
} }