247 lines
6.7 KiB
C#
247 lines
6.7 KiB
C#
using System;
|
|
using System.Diagnostics;
|
|
using System.IO;
|
|
using System.Runtime.InteropServices;
|
|
using MoonWorks;
|
|
using MoonWorks.Graphics;
|
|
using MoonWorks.Math;
|
|
using MoonWorks.Window;
|
|
|
|
namespace MoonWorksComputeSpriteBatch
|
|
{
|
|
public class TestGame : Game
|
|
{
|
|
private RenderTarget mainColorTarget;
|
|
|
|
private GraphicsPipeline spritePipeline;
|
|
|
|
private SpriteBatch spriteBatch;
|
|
|
|
private Texture whitePixel;
|
|
private Sampler sampler;
|
|
|
|
private const int SPRITECOUNT = SpriteBatch.MAX_SPRITES;
|
|
private Vector3[] positions = new Vector3[SPRITECOUNT];
|
|
|
|
private uint windowWidth;
|
|
private uint windowHeight;
|
|
|
|
private Random random = new Random();
|
|
|
|
public TestGame(WindowCreateInfo windowCreateInfo, PresentMode presentMode, int targetTimestep = 60, bool debugMode = false) : base(windowCreateInfo, presentMode, targetTimestep, debugMode)
|
|
{
|
|
windowWidth = windowCreateInfo.WindowWidth;
|
|
windowHeight = windowCreateInfo.WindowHeight;
|
|
|
|
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"));
|
|
|
|
mainColorTarget = RenderTarget.CreateBackedRenderTarget(
|
|
GraphicsDevice,
|
|
windowWidth,
|
|
windowHeight,
|
|
TextureFormat.R8G8B8A8,
|
|
false
|
|
);
|
|
|
|
/* Pipeline */
|
|
|
|
ColorTargetBlendState[] colorTargetBlendStates = new ColorTargetBlendState[1]
|
|
{
|
|
ColorTargetBlendState.None
|
|
};
|
|
|
|
ColorBlendState colorBlendState = new ColorBlendState
|
|
{
|
|
LogicOpEnable = false,
|
|
LogicOp = LogicOp.NoOp,
|
|
BlendConstants = new BlendConstants(),
|
|
ColorTargetBlendStates = colorTargetBlendStates
|
|
};
|
|
|
|
DepthStencilState depthStencilState = DepthStencilState.Disable;
|
|
|
|
ShaderStageState vertexShaderState = new ShaderStageState
|
|
{
|
|
ShaderModule = vertexShaderModule,
|
|
EntryPointName = "main",
|
|
UniformBufferSize = (uint)Marshal.SizeOf<CameraUniforms>()
|
|
};
|
|
|
|
ShaderStageState fragmentShaderState = new ShaderStageState
|
|
{
|
|
ShaderModule = fragmentShaderModule,
|
|
EntryPointName = "main",
|
|
UniformBufferSize = 0
|
|
};
|
|
|
|
MultisampleState multisampleState = MultisampleState.None;
|
|
|
|
GraphicsPipelineLayoutInfo pipelineLayoutInfo = new GraphicsPipelineLayoutInfo
|
|
{
|
|
VertexSamplerBindingCount = 0,
|
|
FragmentSamplerBindingCount = 1
|
|
};
|
|
|
|
RasterizerState rasterizerState = RasterizerState.CCW_CullNone;
|
|
|
|
var vertexBindings = new VertexBinding[1]
|
|
{
|
|
new VertexBinding
|
|
{
|
|
Binding = 0,
|
|
InputRate = VertexInputRate.Vertex,
|
|
Stride = (uint) Marshal.SizeOf<VertexPositionTexcoord>()
|
|
}
|
|
};
|
|
|
|
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")
|
|
}
|
|
};
|
|
|
|
VertexInputState vertexInputState = new VertexInputState
|
|
{
|
|
VertexBindings = vertexBindings,
|
|
VertexAttributes = vertexAttributes
|
|
};
|
|
|
|
var viewports = new Viewport[1]
|
|
{
|
|
new Viewport
|
|
{
|
|
X = 0,
|
|
Y = 0,
|
|
W = windowWidth,
|
|
H = windowHeight,
|
|
MinDepth = 0,
|
|
MaxDepth = 1
|
|
}
|
|
};
|
|
|
|
var scissors = new Rect[1]
|
|
{
|
|
new Rect
|
|
{
|
|
X = 0,
|
|
Y = 0,
|
|
W = (int) windowWidth,
|
|
H = (int) windowHeight
|
|
}
|
|
};
|
|
|
|
ViewportState viewportState = new ViewportState
|
|
{
|
|
Viewports = viewports,
|
|
Scissors = scissors
|
|
};
|
|
|
|
var colorAttachmentDescriptions = new ColorAttachmentDescription[1]
|
|
{
|
|
new ColorAttachmentDescription
|
|
{
|
|
format = TextureFormat.R8G8B8A8,
|
|
sampleCount = SampleCount.One
|
|
}
|
|
};
|
|
|
|
GraphicsPipelineAttachmentInfo graphicsPipelineAttachmentInfo = new GraphicsPipelineAttachmentInfo
|
|
{
|
|
colorAttachmentDescriptions = colorAttachmentDescriptions,
|
|
colorAttachmentCount = 1,
|
|
hasDepthStencilAttachment = false,
|
|
depthStencilFormat = 0
|
|
};
|
|
|
|
var graphicsPipelineCreateInfo = new GraphicsPipelineCreateInfo
|
|
{
|
|
ColorBlendState = colorBlendState,
|
|
DepthStencilState = depthStencilState,
|
|
VertexShaderState = vertexShaderState,
|
|
FragmentShaderState = fragmentShaderState,
|
|
MultisampleState = multisampleState,
|
|
PipelineLayoutInfo = pipelineLayoutInfo,
|
|
RasterizerState = rasterizerState,
|
|
PrimitiveType = PrimitiveType.TriangleList,
|
|
VertexInputState = vertexInputState,
|
|
ViewportState = viewportState,
|
|
AttachmentInfo = graphicsPipelineAttachmentInfo
|
|
};
|
|
|
|
spritePipeline = new GraphicsPipeline(GraphicsDevice, graphicsPipelineCreateInfo);
|
|
|
|
spriteBatch = new SpriteBatch(GraphicsDevice);
|
|
|
|
whitePixel = Texture.CreateTexture2D(GraphicsDevice, 1, 1, TextureFormat.R8G8B8A8, TextureUsageFlags.Sampler);
|
|
|
|
var commandBuffer = GraphicsDevice.AcquireCommandBuffer();
|
|
commandBuffer.SetTextureData(whitePixel, new Color[] { Color.White });
|
|
GraphicsDevice.Submit(commandBuffer);
|
|
|
|
sampler = new Sampler(GraphicsDevice, SamplerCreateInfo.PointWrap);
|
|
}
|
|
|
|
protected override void Update(TimeSpan dt)
|
|
{
|
|
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)
|
|
{
|
|
var commandBuffer = GraphicsDevice.AcquireCommandBuffer();
|
|
|
|
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)
|
|
{
|
|
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 colorAttachmentInfo = new ColorAttachmentInfo
|
|
{
|
|
renderTarget = mainColorTarget,
|
|
clearColor = Color.Black,
|
|
loadOp = LoadOp.Clear,
|
|
storeOp = StoreOp.DontCare
|
|
};
|
|
|
|
spriteBatch.Flush(commandBuffer, colorAttachmentInfo, spritePipeline, new CameraUniforms { viewProjectionMatrix = viewProjection });
|
|
|
|
commandBuffer.QueuePresent(mainColorTarget.TextureSlice, Filter.Nearest, Window);
|
|
GraphicsDevice.Submit(commandBuffer);
|
|
}
|
|
|
|
protected override void OnDestroy()
|
|
{
|
|
|
|
}
|
|
}
|
|
}
|