using System; using System.Diagnostics; using System.IO; using System.Runtime.InteropServices; using MoonWorks; using MoonWorks.Graphics; using MoonWorks.Math; namespace MoonWorksComputeSpriteBatch { public class TestGame : Game { 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")); /* Pipeline */ spritePipeline = new GraphicsPipeline( GraphicsDevice, new GraphicsPipelineCreateInfo { AttachmentInfo = new GraphicsPipelineAttachmentInfo( new ColorAttachmentDescription( GraphicsDevice.GetSwapchainFormat(Window), ColorAttachmentBlendState.None ) ), DepthStencilState = DepthStencilState.Disable, VertexShaderInfo = GraphicsShaderInfo.Create(vertexShaderModule, "main", 0), VertexInputState = new VertexInputState( VertexBinding.Create(), VertexAttribute.Create("position", 0), VertexAttribute.Create("texcoord", 1), VertexAttribute.Create("color", 2) ), PrimitiveType = PrimitiveType.TriangleList, FragmentShaderInfo = GraphicsShaderInfo.Create(fragmentShaderModule, "main", 1), RasterizerState = RasterizerState.CW_CullBack, MultisampleState = MultisampleState.None } ); 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 swapchainTexture = commandBuffer.AcquireSwapchainTexture(Window); 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); } spriteBatch.Flush( commandBuffer, new ColorAttachmentInfo(swapchainTexture, Color.Black), spritePipeline, new CameraUniforms { viewProjectionMatrix = viewProjection } ); GraphicsDevice.Submit(commandBuffer); } protected override void OnDestroy() { } } }