diff --git a/Examples/MSAACubeExample.cs b/Examples/MSAACubeExample.cs new file mode 100644 index 0000000..d3dcbcc --- /dev/null +++ b/Examples/MSAACubeExample.cs @@ -0,0 +1,278 @@ +using MoonWorks; +using MoonWorks.Graphics; +using MoonWorks.Math.Float; +using MoonWorks.Math; +using System.Runtime.InteropServices; +using MoonWorks.Input; + +namespace MoonWorksGraphicsTests; + +class MSAACubeExample : Example +{ + private GraphicsPipeline[] MsaaPipelines = new GraphicsPipeline[4]; + private GraphicsPipeline CubemapPipeline; + + private Texture[] RenderTargets = new Texture[4]; + private GpuBuffer VertexBuffer; + private GpuBuffer IndexBuffer; + private Sampler Sampler; + + private Vector3 camPos; + private SampleCount currentSampleCount; + + public override void Init(Window window, GraphicsDevice graphicsDevice, Inputs inputs) + { + Window = window; + GraphicsDevice = graphicsDevice; + Inputs = inputs; + + Window.SetTitle("MSAACube"); + + Logger.LogInfo("Press Down to view the other side of the cubemap"); + Logger.LogInfo("Press Left and Right to cycle between sample counts"); + Logger.LogInfo("Setting sample count to: " + currentSampleCount); + + camPos = new Vector3(0, 0, 4); + currentSampleCount = SampleCount.Four; + + // Create the MSAA pipelines + Shader triangleVertShader = new Shader( + GraphicsDevice, + TestUtils.GetShaderPath("RawTriangle.vert"), + "main", + ShaderStage.Vertex, + ShaderFormat.SPIRV + ); + + Shader triangleFragShader = new Shader( + GraphicsDevice, + TestUtils.GetShaderPath("SolidColor.frag"), + "main", + ShaderStage.Fragment, + ShaderFormat.SPIRV + ); + + GraphicsPipelineCreateInfo pipelineCreateInfo = TestUtils.GetStandardGraphicsPipelineCreateInfo( + TextureFormat.R8G8B8A8, + triangleVertShader, + triangleFragShader + ); + for (int i = 0; i < MsaaPipelines.Length; i += 1) + { + pipelineCreateInfo.MultisampleState.MultisampleCount = (SampleCount)i; + MsaaPipelines[i] = new GraphicsPipeline(GraphicsDevice, pipelineCreateInfo); + } + + // Create the cubemap pipeline + Shader cubemapVertShader = new Shader( + GraphicsDevice, + TestUtils.GetShaderPath("Skybox.vert"), + "main", + ShaderStage.Vertex, + ShaderFormat.SPIRV + ); + + Shader cubemapFragShader = new Shader( + GraphicsDevice, + TestUtils.GetShaderPath("Skybox.frag"), + "main", + ShaderStage.Fragment, + ShaderFormat.SPIRV + ); + + pipelineCreateInfo = TestUtils.GetStandardGraphicsPipelineCreateInfo( + Window.SwapchainFormat, + cubemapVertShader, + cubemapFragShader + ); + pipelineCreateInfo.VertexInputState = VertexInputState.CreateSingleBinding(); + pipelineCreateInfo.VertexShaderResourceInfo = new GraphicsPipelineResourceInfo + { + UniformBufferCount = 1 + }; + pipelineCreateInfo.FragmentShaderResourceInfo = new GraphicsPipelineResourceInfo + { + SamplerCount = 1, + }; + CubemapPipeline = new GraphicsPipeline(GraphicsDevice, pipelineCreateInfo); + + // Create the MSAA render targets + for (int i = 0; i < RenderTargets.Length; i++) + { + TextureCreateInfo cubeCreateInfo = new TextureCreateInfo + { + Width = 16, + Height = 16, + Format = TextureFormat.R8G8B8A8, + Depth = 1, + LevelCount = 1, + SampleCount = (SampleCount)i, + UsageFlags = TextureUsageFlags.ColorTarget | TextureUsageFlags.Sampler, + IsCube = true, + LayerCount = 6 + }; + RenderTargets[i] = new Texture(GraphicsDevice, cubeCreateInfo); + } + + // Create samplers + Sampler = new Sampler(GraphicsDevice, SamplerCreateInfo.PointClamp); + + // Create and populate the GPU resources + var resourceUploader = new ResourceUploader(GraphicsDevice); + + VertexBuffer = resourceUploader.CreateBuffer( + [ + new PositionVertex(new Vector3(-10, -10, -10)), + new PositionVertex(new Vector3(10, -10, -10)), + new PositionVertex(new Vector3(10, 10, -10)), + new PositionVertex(new Vector3(-10, 10, -10)), + + new PositionVertex(new Vector3(-10, -10, 10)), + new PositionVertex(new Vector3(10, -10, 10)), + new PositionVertex(new Vector3(10, 10, 10)), + new PositionVertex(new Vector3(-10, 10, 10)), + + new PositionVertex(new Vector3(-10, -10, -10)), + new PositionVertex(new Vector3(-10, 10, -10)), + new PositionVertex(new Vector3(-10, 10, 10)), + new PositionVertex(new Vector3(-10, -10, 10)), + + new PositionVertex(new Vector3(10, -10, -10)), + new PositionVertex(new Vector3(10, 10, -10)), + new PositionVertex(new Vector3(10, 10, 10)), + new PositionVertex(new Vector3(10, -10, 10)), + + new PositionVertex(new Vector3(-10, -10, -10)), + new PositionVertex(new Vector3(-10, -10, 10)), + new PositionVertex(new Vector3(10, -10, 10)), + new PositionVertex(new Vector3(10, -10, -10)), + + new PositionVertex(new Vector3(-10, 10, -10)), + new PositionVertex(new Vector3(-10, 10, 10)), + new PositionVertex(new Vector3(10, 10, 10)), + new PositionVertex(new Vector3(10, 10, -10)) + ], + BufferUsageFlags.Vertex + ); + + IndexBuffer = resourceUploader.CreateBuffer( + [ + 0, 1, 2, 0, 2, 3, + 6, 5, 4, 7, 6, 4, + 8, 9, 10, 8, 10, 11, + 14, 13, 12, 15, 14, 12, + 16, 17, 18, 16, 18, 19, + 22, 21, 20, 23, 22, 20 + ], + BufferUsageFlags.Index + ); + + resourceUploader.Upload(); + resourceUploader.Dispose(); + } + + public override void Update(System.TimeSpan delta) + { + if (TestUtils.CheckButtonPressed(Inputs, TestUtils.ButtonType.Bottom)) + { + camPos.Z *= -1; + } + + SampleCount prevSampleCount = currentSampleCount; + + if (TestUtils.CheckButtonPressed(Inputs, TestUtils.ButtonType.Left)) + { + currentSampleCount -= 1; + if (currentSampleCount < 0) + { + currentSampleCount = SampleCount.Eight; + } + } + if (TestUtils.CheckButtonPressed(Inputs, TestUtils.ButtonType.Right)) + { + currentSampleCount += 1; + if (currentSampleCount > SampleCount.Eight) + { + currentSampleCount = SampleCount.One; + } + } + + if (prevSampleCount != currentSampleCount) + { + Logger.LogInfo("Setting sample count to: " + currentSampleCount); + } + } + + public override void Draw(double alpha) + { + Matrix4x4 proj = Matrix4x4.CreatePerspectiveFieldOfView( + MathHelper.ToRadians(75f), + (float)Window.Width / Window.Height, + 0.01f, + 100f + ); + Matrix4x4 view = Matrix4x4.CreateLookAt( + camPos, + Vector3.Zero, + Vector3.Up + ); + TransformVertexUniform vertUniforms = new TransformVertexUniform(view * proj); + + CommandBuffer cmdbuf = GraphicsDevice.AcquireCommandBuffer(); + Texture swapchainTexture = cmdbuf.AcquireSwapchainTexture(Window); + if (swapchainTexture != null) + { + // Get a reference to the RT for the given sample count + int rtIndex = (int) currentSampleCount; + Texture rt = RenderTargets[rtIndex]; + ColorAttachmentInfo rtAttachmentInfo = new ColorAttachmentInfo( + rt, + true, + Color.Black + ); + + RenderPass renderPass; + + // Render a triangle to each slice of the cubemap + for (uint i = 0; i < 6; i += 1) + { + rtAttachmentInfo.TextureSlice.Layer = i; + + renderPass = cmdbuf.BeginRenderPass(rtAttachmentInfo); + renderPass.BindGraphicsPipeline(MsaaPipelines[rtIndex]); + renderPass.DrawPrimitives(0, 1); + cmdbuf.EndRenderPass(renderPass); + } + + renderPass = cmdbuf.BeginRenderPass( + new ColorAttachmentInfo( + swapchainTexture, + false, + Color.Black + ) + ); + renderPass.BindGraphicsPipeline(CubemapPipeline); + renderPass.BindVertexBuffer(VertexBuffer); + renderPass.BindIndexBuffer(IndexBuffer, IndexElementSize.Sixteen); + renderPass.BindFragmentSampler(new TextureSamplerBinding(rt, Sampler)); + renderPass.PushVertexUniformData(vertUniforms); + renderPass.DrawIndexedPrimitives(0, 0, 12); + cmdbuf.EndRenderPass(renderPass); + } + GraphicsDevice.Submit(cmdbuf); + } + + public override void Destroy() + { + for (var i = 0; i < 4; i += 1) + { + MsaaPipelines[i].Dispose(); + RenderTargets[i].Dispose(); + } + + CubemapPipeline.Dispose(); + VertexBuffer.Dispose(); + IndexBuffer.Dispose(); + Sampler.Dispose(); + } +} diff --git a/Examples/MSAACubeGame.cs b/Examples/MSAACubeGame.cs deleted file mode 100644 index 0bffa6c..0000000 --- a/Examples/MSAACubeGame.cs +++ /dev/null @@ -1,222 +0,0 @@ -using MoonWorks; -using MoonWorks.Graphics; -using MoonWorks.Math.Float; -using MoonWorks.Math; -using System.Runtime.InteropServices; - -namespace MoonWorks.Test -{ - class MSAACubeGame : Game - { - private GraphicsPipeline[] msaaPipelines = new GraphicsPipeline[4]; - private GraphicsPipeline cubemapPipeline; - - private Texture[] renderTargets = new Texture[4]; - private GpuBuffer vertexBuffer; - private GpuBuffer indexBuffer; - private Sampler sampler; - - private Vector3 camPos = new Vector3(0, 0, 4f); - - private SampleCount currentSampleCount = SampleCount.Four; - - public MSAACubeGame() : base(TestUtils.GetStandardWindowCreateInfo(), TestUtils.GetStandardFrameLimiterSettings(), TestUtils.PreferredBackends, 60, true) - { - Logger.LogInfo("Press Down to view the other side of the cubemap"); - Logger.LogInfo("Press Left and Right to cycle between sample counts"); - Logger.LogInfo("Setting sample count to: " + currentSampleCount); - - // Create the MSAA pipelines - ShaderModule triangleVertShaderModule = new ShaderModule(GraphicsDevice, TestUtils.GetShaderPath("RawTriangle.vert")); - ShaderModule triangleFragShaderModule = new ShaderModule(GraphicsDevice, TestUtils.GetShaderPath("SolidColor.frag")); - - GraphicsPipelineCreateInfo pipelineCreateInfo = TestUtils.GetStandardGraphicsPipelineCreateInfo( - TextureFormat.R8G8B8A8, - triangleVertShaderModule, - triangleFragShaderModule - ); - for (int i = 0; i < msaaPipelines.Length; i += 1) - { - pipelineCreateInfo.MultisampleState.MultisampleCount = (SampleCount)i; - msaaPipelines[i] = new GraphicsPipeline(GraphicsDevice, pipelineCreateInfo); - } - - // Create the cubemap pipeline - ShaderModule cubemapVertShaderModule = new ShaderModule(GraphicsDevice, TestUtils.GetShaderPath("Skybox.vert")); - ShaderModule cubemapFragShaderModule = new ShaderModule(GraphicsDevice, TestUtils.GetShaderPath("Skybox.frag")); - - pipelineCreateInfo = TestUtils.GetStandardGraphicsPipelineCreateInfo( - MainWindow.SwapchainFormat, - cubemapVertShaderModule, - cubemapFragShaderModule - ); - pipelineCreateInfo.VertexInputState = VertexInputState.CreateSingleBinding(); - pipelineCreateInfo.VertexShaderInfo.UniformBufferSize = (uint)Marshal.SizeOf(); - pipelineCreateInfo.FragmentShaderInfo.SamplerBindingCount = 1; - cubemapPipeline = new GraphicsPipeline(GraphicsDevice, pipelineCreateInfo); - - // Create the MSAA render targets - for (int i = 0; i < renderTargets.Length; i++) - { - TextureCreateInfo cubeCreateInfo = new TextureCreateInfo - { - Width = 16, - Height = 16, - Format = TextureFormat.R8G8B8A8, - Depth = 1, - LevelCount = 1, - SampleCount = (SampleCount)i, - UsageFlags = TextureUsageFlags.ColorTarget | TextureUsageFlags.Sampler, - IsCube = true, - LayerCount = 6 - }; - renderTargets[i] = new Texture(GraphicsDevice, cubeCreateInfo); - } - - // Create samplers - sampler = new Sampler(GraphicsDevice, SamplerCreateInfo.PointClamp); - - // Create and populate the GPU resources - var resourceUploader = new ResourceUploader(GraphicsDevice); - - vertexBuffer = resourceUploader.CreateBuffer( - [ - new PositionVertex(new Vector3(-10, -10, -10)), - new PositionVertex(new Vector3(10, -10, -10)), - new PositionVertex(new Vector3(10, 10, -10)), - new PositionVertex(new Vector3(-10, 10, -10)), - - new PositionVertex(new Vector3(-10, -10, 10)), - new PositionVertex(new Vector3(10, -10, 10)), - new PositionVertex(new Vector3(10, 10, 10)), - new PositionVertex(new Vector3(-10, 10, 10)), - - new PositionVertex(new Vector3(-10, -10, -10)), - new PositionVertex(new Vector3(-10, 10, -10)), - new PositionVertex(new Vector3(-10, 10, 10)), - new PositionVertex(new Vector3(-10, -10, 10)), - - new PositionVertex(new Vector3(10, -10, -10)), - new PositionVertex(new Vector3(10, 10, -10)), - new PositionVertex(new Vector3(10, 10, 10)), - new PositionVertex(new Vector3(10, -10, 10)), - - new PositionVertex(new Vector3(-10, -10, -10)), - new PositionVertex(new Vector3(-10, -10, 10)), - new PositionVertex(new Vector3(10, -10, 10)), - new PositionVertex(new Vector3(10, -10, -10)), - - new PositionVertex(new Vector3(-10, 10, -10)), - new PositionVertex(new Vector3(-10, 10, 10)), - new PositionVertex(new Vector3(10, 10, 10)), - new PositionVertex(new Vector3(10, 10, -10)) - ], - BufferUsageFlags.Vertex - ); - - indexBuffer = resourceUploader.CreateBuffer( - [ - 0, 1, 2, 0, 2, 3, - 6, 5, 4, 7, 6, 4, - 8, 9, 10, 8, 10, 11, - 14, 13, 12, 15, 14, 12, - 16, 17, 18, 16, 18, 19, - 22, 21, 20, 23, 22, 20 - ], - BufferUsageFlags.Index - ); - - resourceUploader.Upload(); - resourceUploader.Dispose(); - } - - protected override void Update(System.TimeSpan delta) - { - if (TestUtils.CheckButtonPressed(Inputs, TestUtils.ButtonType.Bottom)) - { - camPos.Z *= -1; - } - - SampleCount prevSampleCount = currentSampleCount; - - if (TestUtils.CheckButtonPressed(Inputs, TestUtils.ButtonType.Left)) - { - currentSampleCount -= 1; - if (currentSampleCount < 0) - { - currentSampleCount = SampleCount.Eight; - } - } - if (TestUtils.CheckButtonPressed(Inputs, TestUtils.ButtonType.Right)) - { - currentSampleCount += 1; - if (currentSampleCount > SampleCount.Eight) - { - currentSampleCount = SampleCount.One; - } - } - - if (prevSampleCount != currentSampleCount) - { - Logger.LogInfo("Setting sample count to: " + currentSampleCount); - } - } - - protected override void Draw(double alpha) - { - Matrix4x4 proj = Matrix4x4.CreatePerspectiveFieldOfView( - MathHelper.ToRadians(75f), - (float)MainWindow.Width / MainWindow.Height, - 0.01f, - 100f - ); - Matrix4x4 view = Matrix4x4.CreateLookAt( - camPos, - Vector3.Zero, - Vector3.Up - ); - TransformVertexUniform vertUniforms = new TransformVertexUniform(view * proj); - - CommandBuffer cmdbuf = GraphicsDevice.AcquireCommandBuffer(); - Texture? backbuffer = cmdbuf.AcquireSwapchainTexture(MainWindow); - if (backbuffer != null) - { - // Get a reference to the RT for the given sample count - int rtIndex = (int) currentSampleCount; - Texture rt = renderTargets[rtIndex]; - ColorAttachmentInfo rtAttachmentInfo = new ColorAttachmentInfo( - rt, - WriteOptions.Cycle, - Color.Black - ); - - // Render a triangle to each slice of the cubemap - for (uint i = 0; i < 6; i += 1) - { - rtAttachmentInfo.TextureSlice.Layer = i; - - cmdbuf.BeginRenderPass(rtAttachmentInfo); - cmdbuf.BindGraphicsPipeline(msaaPipelines[rtIndex]); - cmdbuf.DrawPrimitives(0, 1); - cmdbuf.EndRenderPass(); - } - - cmdbuf.BeginRenderPass(new ColorAttachmentInfo(backbuffer, WriteOptions.Cycle, Color.Black)); - cmdbuf.BindGraphicsPipeline(cubemapPipeline); - cmdbuf.BindVertexBuffers(vertexBuffer); - cmdbuf.BindIndexBuffer(indexBuffer, IndexElementSize.Sixteen); - cmdbuf.BindFragmentSamplers(new TextureSamplerBinding(rt, sampler)); - cmdbuf.PushVertexShaderUniforms(vertUniforms); - cmdbuf.DrawIndexedPrimitives(0, 0, 12); - cmdbuf.EndRenderPass(); - } - GraphicsDevice.Submit(cmdbuf); - } - - public static void Main(string[] args) - { - MSAACubeGame game = new MSAACubeGame(); - game.Run(); - } - } -} diff --git a/MoonWorksGraphicsTests.csproj b/MoonWorksGraphicsTests.csproj index daab783..545d9f8 100644 --- a/MoonWorksGraphicsTests.csproj +++ b/MoonWorksGraphicsTests.csproj @@ -38,6 +38,7 @@ + diff --git a/Program.cs b/Program.cs index 0db2320..d031660 100644 --- a/Program.cs +++ b/Program.cs @@ -21,7 +21,8 @@ class Program : Game new DepthMSAAExample(), new DrawIndirectExample(), new GetBufferDataExample(), - new InstancingAndOffsetsExample() + new InstancingAndOffsetsExample(), + new MSAACubeExample() ]; int ExampleIndex = 0;