diff --git a/Cube/CubeGame.cs b/Cube/CubeGame.cs index d7c3fe8..c97c425 100644 --- a/Cube/CubeGame.cs +++ b/Cube/CubeGame.cs @@ -140,12 +140,12 @@ namespace MoonWorks.Test GraphicsPipelineCreateInfo cubePipelineCreateInfo = new GraphicsPipelineCreateInfo { AttachmentInfo = new GraphicsPipelineAttachmentInfo( - TextureFormat.D16, - new ColorAttachmentDescription( - MainWindow.SwapchainFormat, - ColorAttachmentBlendState.Opaque - ) - ), + TextureFormat.D16, + new ColorAttachmentDescription( + MainWindow.SwapchainFormat, + ColorAttachmentBlendState.Opaque + ) + ), DepthStencilState = DepthStencilState.DepthReadWrite, VertexShaderInfo = GraphicsShaderInfo.Create(cubeVertShaderModule, "main", 0), VertexInputState = VertexInputState.CreateSingleBinding(), @@ -277,9 +277,9 @@ namespace MoonWorks.Test indexBuffer, new uint[] { - 0, 1, 2, 0, 2, 3, - 6, 5, 4, 7, 6, 4, - 8, 9, 10, 8, 10, 11, + 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 diff --git a/DepthMSAA/DepthMSAAGame.cs b/DepthMSAA/DepthMSAAGame.cs index cc879bd..40194b9 100644 --- a/DepthMSAA/DepthMSAAGame.cs +++ b/DepthMSAA/DepthMSAAGame.cs @@ -185,12 +185,12 @@ namespace MoonWorks.Test cubeIndexBuffer, new uint[] { - 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 + 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 } ); diff --git a/MSAACube/MSAACube.csproj b/MSAACube/MSAACube.csproj new file mode 100644 index 0000000..7ce1c70 --- /dev/null +++ b/MSAACube/MSAACube.csproj @@ -0,0 +1,16 @@ + + + + + + + + + Exe + net8.0 + enable + + + + + diff --git a/MSAACube/MSAACubeGame.cs b/MSAACube/MSAACubeGame.cs new file mode 100644 index 0000000..ec51e88 --- /dev/null +++ b/MSAACube/MSAACubeGame.cs @@ -0,0 +1,223 @@ +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 Buffer vertexBuffer; + private Buffer indexBuffer; + private Sampler sampler; + + private Vector3 camPos = new Vector3(0, 0, 4f); + + private SampleCount currentSampleCount = SampleCount.Four; + + public MSAACubeGame() : base(TestUtils.GetStandardWindowCreateInfo(), TestUtils.GetStandardFrameLimiterSettings(), 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 + }; + renderTargets[i] = new Texture(GraphicsDevice, cubeCreateInfo); + } + + // Create samplers + sampler = new Sampler(GraphicsDevice, SamplerCreateInfo.PointClamp); + + // Create and populate the GPU resources + vertexBuffer = Buffer.Create(GraphicsDevice, BufferUsageFlags.Vertex, 24); + indexBuffer = Buffer.Create(GraphicsDevice, BufferUsageFlags.Index, 36); + + CommandBuffer cmdbuf = GraphicsDevice.AcquireCommandBuffer(); + cmdbuf.SetBufferData( + vertexBuffer, + new PositionVertex[] + { + 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)) + } + ); + + cmdbuf.SetBufferData( + indexBuffer, + new ushort[] + { + 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 + } + ); + + GraphicsDevice.Submit(cmdbuf); + } + + 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, + Color.Black + ); + + // Render a triangle to each slice of the cubemap + for (uint i = 0; i < 6; i += 1) + { + rtAttachmentInfo.Layer = i; + + cmdbuf.BeginRenderPass(rtAttachmentInfo); + cmdbuf.BindGraphicsPipeline(msaaPipelines[rtIndex]); + cmdbuf.DrawPrimitives(0, 1, 0, 0); + cmdbuf.EndRenderPass(); + } + + cmdbuf.BeginRenderPass(new ColorAttachmentInfo(backbuffer, Color.Black)); + cmdbuf.BindGraphicsPipeline(cubemapPipeline); + cmdbuf.BindVertexBuffers(vertexBuffer); + cmdbuf.BindIndexBuffer(indexBuffer, IndexElementSize.Sixteen); + cmdbuf.BindFragmentSamplers(new TextureSamplerBinding(rt, sampler)); + uint vertexUniformOffset = cmdbuf.PushVertexShaderUniforms(vertUniforms); + cmdbuf.DrawIndexedPrimitives(0, 0, 12, vertexUniformOffset, 0); + cmdbuf.EndRenderPass(); + } + GraphicsDevice.Submit(cmdbuf); + } + + public static void Main(string[] args) + { + MSAACubeGame game = new MSAACubeGame(); + game.Run(); + } + } +} diff --git a/MoonWorksGraphicsTests.sln b/MoonWorksGraphicsTests.sln index f3b6948..70b2b9f 100644 --- a/MoonWorksGraphicsTests.sln +++ b/MoonWorksGraphicsTests.sln @@ -61,7 +61,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WindowResizing", "WindowRes EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "StoreLoad", "StoreLoad\StoreLoad.csproj", "{CD31F1B5-C76A-428A-A812-8DFD6CAB20A9}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RenderTexture2D", "RenderTexture2D\RenderTexture2D.csproj", "{F9C9E15D-1000-46DA-BA39-1D4C0D43F023}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RenderTexture2D", "RenderTexture2D\RenderTexture2D.csproj", "{F9C9E15D-1000-46DA-BA39-1D4C0D43F023}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MSAACube", "MSAACube\MSAACube.csproj", "{A1568AAF-DD02-4A6E-9C68-9AE07130A60D}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -189,6 +191,10 @@ Global {F9C9E15D-1000-46DA-BA39-1D4C0D43F023}.Debug|Any CPU.Build.0 = Debug|Any CPU {F9C9E15D-1000-46DA-BA39-1D4C0D43F023}.Release|Any CPU.ActiveCfg = Release|Any CPU {F9C9E15D-1000-46DA-BA39-1D4C0D43F023}.Release|Any CPU.Build.0 = Release|Any CPU + {A1568AAF-DD02-4A6E-9C68-9AE07130A60D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A1568AAF-DD02-4A6E-9C68-9AE07130A60D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A1568AAF-DD02-4A6E-9C68-9AE07130A60D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A1568AAF-DD02-4A6E-9C68-9AE07130A60D}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/README.md b/README.md index 1cfd774..cad22cd 100644 --- a/README.md +++ b/README.md @@ -108,6 +108,10 @@ Demonstrates stencil masking using two triangles. Tests stencil buffers and basi Displays two cubes floating around each other on a multisampled surface. Tests multisampled depth buffers. +**MSAACube** + +Same as RenderTextureCube, but with MSAA cube RTs. Draws triangles to each cubemap face so there's something to see. Tests cube render target MSAA. + **WindowResizing** Tests resizing the window to various resolutions. diff --git a/RenderTextureCube/RenderTextureCubeGame.cs b/RenderTextureCube/RenderTextureCubeGame.cs index 87d58dc..63bef07 100644 --- a/RenderTextureCube/RenderTextureCubeGame.cs +++ b/RenderTextureCube/RenderTextureCubeGame.cs @@ -99,9 +99,9 @@ namespace MoonWorks.Test indexBuffer, new ushort[] { - 0, 1, 2, 0, 2, 3, - 6, 5, 4, 7, 6, 4, - 8, 9, 10, 8, 10, 11, + 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