diff --git a/.gitignore b/.gitignore index 03c9b93..796b6e5 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ bin/ obj/ .vs/ +*.csproj.user diff --git a/MoonWorks.csproj b/MoonWorks.csproj index a20c72a..8c55535 100644 --- a/MoonWorks.csproj +++ b/MoonWorks.csproj @@ -7,7 +7,7 @@ - $(DefaultItemExcludes);lib\**\* + $(DefaultItemExcludes);lib\**\*;tests\**\* diff --git a/MoonWorks.sln b/MoonWorks.sln index 748c5d4..c5e500c 100644 --- a/MoonWorks.sln +++ b/MoonWorks.sln @@ -5,6 +5,26 @@ VisualStudioVersion = 16.0.30717.126 MinimumVisualStudioVersion = 15.0.26124.0 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MoonWorks", "MoonWorks.csproj", "{DDC9BA9B-4440-4CB3-BDB4-D5F91DE1686B}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{734B6C25-40FE-4688-9B3C-7B3D3A343257}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MoonWorks.Test.Common", "tests\MoonWorks.Test.Common\MoonWorks.Test.Common.csproj", "{47BC8A83-B1A5-454C-AED0-461B535D664B}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ClearScreen", "tests\ClearScreen\ClearScreen.csproj", "{C37E4CF1-4899-48BC-BF58-2074420077BC}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BasicTriangle", "tests\BasicTriangle\BasicTriangle.csproj", "{F34E6D95-887D-49C0-AC74-560EBD0D23C5}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TriangleVertexBuffer", "tests\TriangleVertexBuffer\TriangleVertexBuffer.csproj", "{944D4FDC-1635-46B6-84FA-8161F8E43AC4}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TexturedQuad", "tests\TexturedQuad\TexturedQuad.csproj", "{845DA751-5072-43C8-B9E6-4E2A32D99161}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CullFace", "tests\CullFace\CullFace.csproj", "{96986050-5136-4680-B388-EDD1207F9212}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ClearScreen_MultiWindow", "tests\ClearScreen_MultiWindow\ClearScreen_MultiWindow.csproj", "{F6283B5C-051B-427C-AE7E-9DB9E0313769}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TexturedAnimatedQuad", "tests\TexturedAnimatedQuad\TexturedAnimatedQuad.csproj", "{F022FB5F-FD61-4956-A7CE-7B428DB80A39}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MSAA", "tests\MSAA\MSAA.csproj", "{D97DED9B-4CC4-45F6-A9A9-E8C589036A85}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|x64 = Debug|x64 @@ -15,10 +35,50 @@ Global {DDC9BA9B-4440-4CB3-BDB4-D5F91DE1686B}.Debug|x64.Build.0 = Debug|x64 {DDC9BA9B-4440-4CB3-BDB4-D5F91DE1686B}.Release|x64.ActiveCfg = Release|x64 {DDC9BA9B-4440-4CB3-BDB4-D5F91DE1686B}.Release|x64.Build.0 = Release|x64 + {47BC8A83-B1A5-454C-AED0-461B535D664B}.Debug|x64.ActiveCfg = Debug|x64 + {47BC8A83-B1A5-454C-AED0-461B535D664B}.Debug|x64.Build.0 = Debug|x64 + {47BC8A83-B1A5-454C-AED0-461B535D664B}.Release|x64.ActiveCfg = Release|x64 + {C37E4CF1-4899-48BC-BF58-2074420077BC}.Debug|x64.ActiveCfg = Debug|x64 + {C37E4CF1-4899-48BC-BF58-2074420077BC}.Debug|x64.Build.0 = Debug|x64 + {C37E4CF1-4899-48BC-BF58-2074420077BC}.Release|x64.ActiveCfg = Release|x64 + {F34E6D95-887D-49C0-AC74-560EBD0D23C5}.Debug|x64.ActiveCfg = Debug|x64 + {F34E6D95-887D-49C0-AC74-560EBD0D23C5}.Debug|x64.Build.0 = Debug|x64 + {F34E6D95-887D-49C0-AC74-560EBD0D23C5}.Release|x64.ActiveCfg = Release|x64 + {944D4FDC-1635-46B6-84FA-8161F8E43AC4}.Debug|x64.ActiveCfg = Debug|x64 + {944D4FDC-1635-46B6-84FA-8161F8E43AC4}.Debug|x64.Build.0 = Debug|x64 + {944D4FDC-1635-46B6-84FA-8161F8E43AC4}.Release|x64.ActiveCfg = Release|x64 + {845DA751-5072-43C8-B9E6-4E2A32D99161}.Debug|x64.ActiveCfg = Debug|x64 + {845DA751-5072-43C8-B9E6-4E2A32D99161}.Debug|x64.Build.0 = Debug|x64 + {845DA751-5072-43C8-B9E6-4E2A32D99161}.Release|x64.ActiveCfg = Release|x64 + {96986050-5136-4680-B388-EDD1207F9212}.Debug|x64.ActiveCfg = Debug|x64 + {96986050-5136-4680-B388-EDD1207F9212}.Debug|x64.Build.0 = Debug|x64 + {96986050-5136-4680-B388-EDD1207F9212}.Release|x64.ActiveCfg = Release|x64 + {F6283B5C-051B-427C-AE7E-9DB9E0313769}.Debug|x64.ActiveCfg = Debug|x64 + {F6283B5C-051B-427C-AE7E-9DB9E0313769}.Debug|x64.Build.0 = Debug|x64 + {F6283B5C-051B-427C-AE7E-9DB9E0313769}.Release|x64.ActiveCfg = Release|x64 + {F022FB5F-FD61-4956-A7CE-7B428DB80A39}.Debug|x64.ActiveCfg = Debug|x64 + {F022FB5F-FD61-4956-A7CE-7B428DB80A39}.Debug|x64.Build.0 = Debug|x64 + {F022FB5F-FD61-4956-A7CE-7B428DB80A39}.Release|x64.ActiveCfg = Release|Any CPU + {F022FB5F-FD61-4956-A7CE-7B428DB80A39}.Release|x64.Build.0 = Release|Any CPU + {D97DED9B-4CC4-45F6-A9A9-E8C589036A85}.Debug|x64.ActiveCfg = Debug|x64 + {D97DED9B-4CC4-45F6-A9A9-E8C589036A85}.Debug|x64.Build.0 = Debug|x64 + {D97DED9B-4CC4-45F6-A9A9-E8C589036A85}.Release|x64.ActiveCfg = Release|Any CPU + {D97DED9B-4CC4-45F6-A9A9-E8C589036A85}.Release|x64.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {47BC8A83-B1A5-454C-AED0-461B535D664B} = {734B6C25-40FE-4688-9B3C-7B3D3A343257} + {C37E4CF1-4899-48BC-BF58-2074420077BC} = {734B6C25-40FE-4688-9B3C-7B3D3A343257} + {F34E6D95-887D-49C0-AC74-560EBD0D23C5} = {734B6C25-40FE-4688-9B3C-7B3D3A343257} + {944D4FDC-1635-46B6-84FA-8161F8E43AC4} = {734B6C25-40FE-4688-9B3C-7B3D3A343257} + {845DA751-5072-43C8-B9E6-4E2A32D99161} = {734B6C25-40FE-4688-9B3C-7B3D3A343257} + {96986050-5136-4680-B388-EDD1207F9212} = {734B6C25-40FE-4688-9B3C-7B3D3A343257} + {F6283B5C-051B-427C-AE7E-9DB9E0313769} = {734B6C25-40FE-4688-9B3C-7B3D3A343257} + {F022FB5F-FD61-4956-A7CE-7B428DB80A39} = {734B6C25-40FE-4688-9B3C-7B3D3A343257} + {D97DED9B-4CC4-45F6-A9A9-E8C589036A85} = {734B6C25-40FE-4688-9B3C-7B3D3A343257} + EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {C3D68FAA-3165-43C7-95B3-D845F0DAA918} EndGlobalSection diff --git a/tests/BasicTriangle/BasicTriangle.csproj b/tests/BasicTriangle/BasicTriangle.csproj new file mode 100644 index 0000000..9538ed1 --- /dev/null +++ b/tests/BasicTriangle/BasicTriangle.csproj @@ -0,0 +1,22 @@ + + + + + + + + + Exe + net6.0 + enable + x64 + + + + + Content\%(RecursiveDir)%(Filename)%(Extension) + Always + + + + diff --git a/tests/BasicTriangle/BasicTriangleGame.cs b/tests/BasicTriangle/BasicTriangleGame.cs new file mode 100644 index 0000000..2986993 --- /dev/null +++ b/tests/BasicTriangle/BasicTriangleGame.cs @@ -0,0 +1,85 @@ +using MoonWorks; +using MoonWorks.Graphics; + +namespace MoonWorks.Test +{ + class BasicTriangleGame : Game + { + private GraphicsPipeline fillPipeline; + private GraphicsPipeline linePipeline; + private ShaderModule vertShaderModule; + private ShaderModule fragShaderModule; + + private Viewport smallViewport = new Viewport(160, 120, 320, 240); + private Rect scissorRect = new Rect(320, 240, 320, 240); + + private bool useWireframeMode; + private bool useSmallViewport; + private bool useScissorRect; + + public BasicTriangleGame() : base(TestUtils.GetStandardWindowCreateInfo(), TestUtils.GetStandardFrameLimiterSettings(), 60, true) + { + Logger.LogInfo("Press A to toggle wireframe mode\nPress S to toggle small viewport\nPress D to toggle scissor rect"); + + vertShaderModule = new ShaderModule(GraphicsDevice, TestUtils.GetShaderPath("RawTriangleVertices.spv")); + fragShaderModule = new ShaderModule(GraphicsDevice, TestUtils.GetShaderPath("SolidColor.spv")); + + GraphicsPipelineCreateInfo pipelineCreateInfo = TestUtils.GetStandardGraphicsPipelineCreateInfo(vertShaderModule, fragShaderModule); + fillPipeline = new GraphicsPipeline(GraphicsDevice, pipelineCreateInfo); + + pipelineCreateInfo.RasterizerState.FillMode = FillMode.Line; + linePipeline = new GraphicsPipeline(GraphicsDevice, pipelineCreateInfo); + } + + protected override void Update(System.TimeSpan delta) + { + if (Inputs.Keyboard.IsPressed(Input.KeyCode.A)) + { + useWireframeMode = !useWireframeMode; + Logger.LogInfo("Using wireframe mode: " + useWireframeMode); + } + + if (Inputs.Keyboard.IsPressed(Input.KeyCode.S)) + { + useSmallViewport = !useSmallViewport; + Logger.LogInfo("Using small viewport: " + useSmallViewport); + } + + if (Inputs.Keyboard.IsPressed(Input.KeyCode.D)) + { + useScissorRect = !useScissorRect; + Logger.LogInfo("Using scissor rect: " + useScissorRect); + } + } + + protected override void Draw(double alpha) + { + CommandBuffer cmdbuf = GraphicsDevice.AcquireCommandBuffer(); + Texture? backbuffer = cmdbuf.AcquireSwapchainTexture(MainWindow); + if (backbuffer != null) + { + cmdbuf.BeginRenderPass(new ColorAttachmentInfo(backbuffer, Color.Black)); + cmdbuf.BindGraphicsPipeline(useWireframeMode ? linePipeline : fillPipeline); + + if (useSmallViewport) + { + cmdbuf.SetViewport(smallViewport); + } + if (useScissorRect) + { + cmdbuf.SetScissor(scissorRect); + } + + cmdbuf.DrawPrimitives(0, 1, 0, 0); + cmdbuf.EndRenderPass(); + } + GraphicsDevice.Submit(cmdbuf); + } + + public static void Main(string[] args) + { + BasicTriangleGame game = new BasicTriangleGame(); + game.Run(); + } + } +} diff --git a/tests/ClearScreen/ClearScreen.csproj b/tests/ClearScreen/ClearScreen.csproj new file mode 100644 index 0000000..fd2ff3e --- /dev/null +++ b/tests/ClearScreen/ClearScreen.csproj @@ -0,0 +1,15 @@ + + + + + + + + + Exe + net6.0 + enable + x64 + + + diff --git a/tests/ClearScreen/ClearScreenGame.cs b/tests/ClearScreen/ClearScreenGame.cs new file mode 100644 index 0000000..63ac285 --- /dev/null +++ b/tests/ClearScreen/ClearScreenGame.cs @@ -0,0 +1,29 @@ +using MoonWorks; +using MoonWorks.Graphics; + +namespace MoonWorks.Test +{ + class ClearScreenGame : Game + { + public ClearScreenGame() : base(TestUtils.GetStandardWindowCreateInfo(), TestUtils.GetStandardFrameLimiterSettings(), 60, true) { } + protected override void Update(System.TimeSpan delta) { } + + protected override void Draw(double alpha) + { + CommandBuffer cmdbuf = GraphicsDevice.AcquireCommandBuffer(); + Texture? backbuffer = cmdbuf.AcquireSwapchainTexture(MainWindow); + if (backbuffer != null) + { + cmdbuf.BeginRenderPass(new ColorAttachmentInfo(backbuffer, Color.CornflowerBlue)); + cmdbuf.EndRenderPass(); + } + GraphicsDevice.Submit(cmdbuf); + } + + public static void Main(string[] args) + { + ClearScreenGame game = new ClearScreenGame(); + game.Run(); + } + } +} diff --git a/tests/ClearScreen_MultiWindow/ClearScreen_MultiWindow.csproj b/tests/ClearScreen_MultiWindow/ClearScreen_MultiWindow.csproj new file mode 100644 index 0000000..fd2ff3e --- /dev/null +++ b/tests/ClearScreen_MultiWindow/ClearScreen_MultiWindow.csproj @@ -0,0 +1,15 @@ + + + + + + + + + Exe + net6.0 + enable + x64 + + + diff --git a/tests/ClearScreen_MultiWindow/ClearScreen_MultiWindowGame.cs b/tests/ClearScreen_MultiWindow/ClearScreen_MultiWindowGame.cs new file mode 100644 index 0000000..fa955fd --- /dev/null +++ b/tests/ClearScreen_MultiWindow/ClearScreen_MultiWindowGame.cs @@ -0,0 +1,51 @@ +using MoonWorks; +using MoonWorks.Graphics; + +namespace MoonWorks.Test +{ + class ClearScreen_MultiWindowGame : Game + { + private Window secondaryWindow; + + public ClearScreen_MultiWindowGame() : base(TestUtils.GetStandardWindowCreateInfo(), TestUtils.GetStandardFrameLimiterSettings(), 60, true) + { + secondaryWindow = new Window( + new WindowCreateInfo("Secondary Window", 640, 480, ScreenMode.Windowed, PresentMode.FIFO, false, false), + GraphicsDevice.WindowFlags + ); + GraphicsDevice.ClaimWindow(secondaryWindow, PresentMode.FIFO); + } + + protected override void Update(System.TimeSpan delta) { } + + protected override void Draw(double alpha) + { + CommandBuffer cmdbuf; + Texture? backbuffer; + + cmdbuf = GraphicsDevice.AcquireCommandBuffer(); + backbuffer = cmdbuf.AcquireSwapchainTexture(MainWindow); + if (backbuffer != null) + { + cmdbuf.BeginRenderPass(new ColorAttachmentInfo(backbuffer, Color.CornflowerBlue)); + cmdbuf.EndRenderPass(); + } + GraphicsDevice.Submit(cmdbuf); + + cmdbuf = GraphicsDevice.AcquireCommandBuffer(); + backbuffer = cmdbuf.AcquireSwapchainTexture(secondaryWindow); + if (backbuffer != null) + { + cmdbuf.BeginRenderPass(new ColorAttachmentInfo(backbuffer, Color.Aquamarine)); + cmdbuf.EndRenderPass(); + } + GraphicsDevice.Submit(cmdbuf); + } + + public static void Main(string[] args) + { + ClearScreen_MultiWindowGame game = new ClearScreen_MultiWindowGame(); + game.Run(); + } + } +} diff --git a/tests/CullFace/CullFace.csproj b/tests/CullFace/CullFace.csproj new file mode 100644 index 0000000..9538ed1 --- /dev/null +++ b/tests/CullFace/CullFace.csproj @@ -0,0 +1,22 @@ + + + + + + + + + Exe + net6.0 + enable + x64 + + + + + Content\%(RecursiveDir)%(Filename)%(Extension) + Always + + + + diff --git a/tests/CullFace/CullFaceGame.cs b/tests/CullFace/CullFaceGame.cs new file mode 100644 index 0000000..81beb3e --- /dev/null +++ b/tests/CullFace/CullFaceGame.cs @@ -0,0 +1,144 @@ +using MoonWorks; +using MoonWorks.Graphics; +using MoonWorks.Math.Float; + +namespace MoonWorks.Test +{ + internal class CullFaceGame : Game + { + private GraphicsPipeline CW_CullNonePipeline; + private GraphicsPipeline CW_CullFrontPipeline; + private GraphicsPipeline CW_CullBackPipeline; + private GraphicsPipeline CCW_CullNonePipeline; + private GraphicsPipeline CCW_CullFrontPipeline; + private GraphicsPipeline CCW_CullBackPipeline; + private ShaderModule vertShaderModule; + private ShaderModule fragShaderModule; + private Buffer cwVertexBuffer; + private Buffer ccwVertexBuffer; + + private bool useClockwiseWinding; + + public CullFaceGame() : base(TestUtils.GetStandardWindowCreateInfo(), TestUtils.GetStandardFrameLimiterSettings(), 60, true) + { + Logger.LogInfo("Press A to toggle the winding order of the triangles (default is counter-clockwise)"); + + // Load the shaders + vertShaderModule = new ShaderModule(GraphicsDevice, "Content/Shaders/Compiled/PositionColorVert.spv"); + fragShaderModule = new ShaderModule(GraphicsDevice, "Content/Shaders/Compiled/SolidColor.spv"); + + // Create the graphics pipelines + GraphicsPipelineCreateInfo pipelineCreateInfo = TestUtils.GetStandardGraphicsPipelineCreateInfo(vertShaderModule, fragShaderModule); + pipelineCreateInfo.VertexInputState = new VertexInputState( + VertexBinding.Create(), + VertexAttribute.Create("Position", 0), + VertexAttribute.Create("Color", 1) + ); + + pipelineCreateInfo.RasterizerState = RasterizerState.CW_CullNone; + CW_CullNonePipeline = new GraphicsPipeline(GraphicsDevice, pipelineCreateInfo); + + pipelineCreateInfo.RasterizerState = RasterizerState.CW_CullFront; + CW_CullFrontPipeline = new GraphicsPipeline(GraphicsDevice, pipelineCreateInfo); + + pipelineCreateInfo.RasterizerState = RasterizerState.CW_CullBack; + CW_CullBackPipeline = new GraphicsPipeline(GraphicsDevice, pipelineCreateInfo); + + pipelineCreateInfo.RasterizerState = RasterizerState.CCW_CullNone; + CCW_CullNonePipeline = new GraphicsPipeline(GraphicsDevice, pipelineCreateInfo); + + pipelineCreateInfo.RasterizerState = RasterizerState.CCW_CullFront; + CCW_CullFrontPipeline = new GraphicsPipeline(GraphicsDevice, pipelineCreateInfo); + + pipelineCreateInfo.RasterizerState = RasterizerState.CCW_CullBack; + CCW_CullBackPipeline = new GraphicsPipeline(GraphicsDevice, pipelineCreateInfo); + + // Create and populate the vertex buffers + cwVertexBuffer = Buffer.Create(GraphicsDevice, BufferUsageFlags.Vertex, 3); + ccwVertexBuffer = Buffer.Create(GraphicsDevice, BufferUsageFlags.Vertex, 3); + + CommandBuffer cmdbuf = GraphicsDevice.AcquireCommandBuffer(); + cmdbuf.SetBufferData( + cwVertexBuffer, + new PositionColorVertex[] + { + new PositionColorVertex(new Vector3(0, -1, 0), Color.Blue), + new PositionColorVertex(new Vector3(1, 1, 0), Color.Green), + new PositionColorVertex(new Vector3(-1, 1, 0), Color.Red), + } + ); + cmdbuf.SetBufferData( + ccwVertexBuffer, + new PositionColorVertex[] + { + new PositionColorVertex(new Vector3(-1, 1, 0), Color.Red), + new PositionColorVertex(new Vector3(1, 1, 0), Color.Green), + new PositionColorVertex(new Vector3(0, -1, 0), Color.Blue), + } + ); + GraphicsDevice.Submit(cmdbuf); + GraphicsDevice.Wait(); + } + + protected override void Update(System.TimeSpan delta) + { + if (Inputs.Keyboard.IsPressed(Input.KeyCode.A)) + { + useClockwiseWinding = !useClockwiseWinding; + Logger.LogInfo("Using clockwise winding: " + useClockwiseWinding); + } + } + + protected override void Draw(double alpha) + { + CommandBuffer cmdbuf = GraphicsDevice.AcquireCommandBuffer(); + Texture? backbuffer = cmdbuf.AcquireSwapchainTexture(MainWindow); + if (backbuffer != null) + { + cmdbuf.BeginRenderPass(new ColorAttachmentInfo(backbuffer, Color.Black)); + + if (useClockwiseWinding) + { + cmdbuf.BindVertexBuffers(cwVertexBuffer); + } + else + { + cmdbuf.BindVertexBuffers(ccwVertexBuffer); + } + + cmdbuf.SetViewport(new Viewport(0, 0, 213, 240)); + cmdbuf.BindGraphicsPipeline(CW_CullNonePipeline); + cmdbuf.DrawPrimitives(0, 1, 0, 0); + + cmdbuf.SetViewport(new Viewport(213, 0, 213, 240)); + cmdbuf.BindGraphicsPipeline(CW_CullFrontPipeline); + cmdbuf.DrawPrimitives(0, 1, 0, 0); + + cmdbuf.SetViewport(new Viewport(426, 0, 213, 240)); + cmdbuf.BindGraphicsPipeline(CW_CullBackPipeline); + cmdbuf.DrawPrimitives(0, 1, 0, 0); + + cmdbuf.SetViewport(new Viewport(0, 240, 213, 240)); + cmdbuf.BindGraphicsPipeline(CCW_CullNonePipeline); + cmdbuf.DrawPrimitives(0, 1, 0, 0); + + cmdbuf.SetViewport(new Viewport(213, 240, 213, 240)); + cmdbuf.BindGraphicsPipeline(CCW_CullFrontPipeline); + cmdbuf.DrawPrimitives(0, 1, 0, 0); + + cmdbuf.SetViewport(new Viewport(426, 240, 213, 240)); + cmdbuf.BindGraphicsPipeline(CCW_CullBackPipeline); + cmdbuf.DrawPrimitives(0, 1, 0, 0); + + cmdbuf.EndRenderPass(); + } + GraphicsDevice.Submit(cmdbuf); + } + + public static void Main(string[] args) + { + CullFaceGame game = new CullFaceGame(); + game.Run(); + } + } +} diff --git a/tests/MSAA/MSAA.csproj b/tests/MSAA/MSAA.csproj new file mode 100644 index 0000000..9538ed1 --- /dev/null +++ b/tests/MSAA/MSAA.csproj @@ -0,0 +1,22 @@ + + + + + + + + + Exe + net6.0 + enable + x64 + + + + + Content\%(RecursiveDir)%(Filename)%(Extension) + Always + + + + diff --git a/tests/MSAA/MSAAGame.cs b/tests/MSAA/MSAAGame.cs new file mode 100644 index 0000000..b98e1f5 --- /dev/null +++ b/tests/MSAA/MSAAGame.cs @@ -0,0 +1,159 @@ +using MoonWorks; +using MoonWorks.Math.Float; +using MoonWorks.Graphics; + +namespace MoonWorks.Test +{ + class MSAAGame : Game + { + private GraphicsPipeline[] msaaPipelines = new GraphicsPipeline[4]; + + private ShaderModule triangleVertShaderModule; + private ShaderModule triangleFragShaderModule; + + private GraphicsPipeline blitPipeline; + private ShaderModule blitVertShaderModule; + private ShaderModule blitFragShaderModule; + + private Texture rt; + private Sampler rtSampler; + private Buffer quadVertexBuffer; + private Buffer quadIndexBuffer; + + private SampleCount currentSampleCount = SampleCount.Four; + + public MSAAGame() : base(TestUtils.GetStandardWindowCreateInfo(), TestUtils.GetStandardFrameLimiterSettings(), 60, true) + { + Logger.LogInfo("Press A and D to cycle between sample counts"); + Logger.LogInfo("Setting sample count to: " + currentSampleCount); + + // Create the MSAA pipelines + triangleVertShaderModule = new ShaderModule(GraphicsDevice, TestUtils.GetShaderPath("RawTriangleVertices.spv")); + triangleFragShaderModule = new ShaderModule(GraphicsDevice, TestUtils.GetShaderPath("SolidColor.spv")); + + GraphicsPipelineCreateInfo pipelineCreateInfo = TestUtils.GetStandardGraphicsPipelineCreateInfo( + triangleVertShaderModule, + triangleFragShaderModule + ); + for (int i = 0; i < msaaPipelines.Length; i += 1) + { + pipelineCreateInfo.MultisampleState.MultisampleCount = (SampleCount) i; + msaaPipelines[i] = new GraphicsPipeline(GraphicsDevice, pipelineCreateInfo); + } + + // Create the blit pipeline + blitVertShaderModule = new ShaderModule(GraphicsDevice, TestUtils.GetShaderPath("TexturedQuadVert.spv")); + blitFragShaderModule = new ShaderModule(GraphicsDevice, TestUtils.GetShaderPath("TexturedQuadFrag.spv")); + + pipelineCreateInfo = TestUtils.GetStandardGraphicsPipelineCreateInfo( + blitVertShaderModule, + blitFragShaderModule + ); + pipelineCreateInfo.VertexInputState = new VertexInputState( + VertexBinding.Create(), + VertexAttribute.Create("Position", 0), + VertexAttribute.Create("TexCoord", 1) + ); + pipelineCreateInfo.FragmentShaderInfo.SamplerBindingCount = 1; + blitPipeline = new GraphicsPipeline(GraphicsDevice, pipelineCreateInfo); + + // Create the MSAA render texture and sampler + rt = Texture.CreateTexture2D( + GraphicsDevice, + MainWindow.Width, + MainWindow.Height, + TextureFormat.R8G8B8A8, + TextureUsageFlags.ColorTarget | TextureUsageFlags.Sampler + ); + rtSampler = new Sampler(GraphicsDevice, SamplerCreateInfo.PointClamp); + + // Create and populate the vertex and index buffers + quadVertexBuffer = Buffer.Create(GraphicsDevice, BufferUsageFlags.Vertex, 4); + quadIndexBuffer = Buffer.Create(GraphicsDevice, BufferUsageFlags.Index, 6); + + CommandBuffer cmdbuf = GraphicsDevice.AcquireCommandBuffer(); + cmdbuf.SetBufferData( + quadVertexBuffer, + new PositionTextureVertex[] + { + new PositionTextureVertex(new Vector3(-1, -1, 0), new Vector2(0, 0)), + new PositionTextureVertex(new Vector3(1, -1, 0), new Vector2(1, 0)), + new PositionTextureVertex(new Vector3(1, 1, 0), new Vector2(1, 1)), + new PositionTextureVertex(new Vector3(-1, 1, 0), new Vector2(0, 1)), + } + ); + cmdbuf.SetBufferData( + quadIndexBuffer, + new ushort[] + { + 0, 1, 2, + 0, 2, 3, + } + ); + GraphicsDevice.Submit(cmdbuf); + GraphicsDevice.Wait(); + } + + protected override void Update(System.TimeSpan delta) + { + SampleCount prevSampleCount = currentSampleCount; + + if (Inputs.Keyboard.IsPressed(Input.KeyCode.A)) + { + currentSampleCount -= 1; + if (currentSampleCount < 0) + { + currentSampleCount = SampleCount.Eight; + } + } + if (Inputs.Keyboard.IsPressed(Input.KeyCode.D)) + { + 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) + { + CommandBuffer cmdbuf = GraphicsDevice.AcquireCommandBuffer(); + Texture? backbuffer = cmdbuf.AcquireSwapchainTexture(MainWindow); + if (backbuffer != null) + { + cmdbuf.BeginRenderPass( + new ColorAttachmentInfo( + rt, + Color.Black, + currentSampleCount, + StoreOp.DontCare + ) + ); + cmdbuf.BindGraphicsPipeline(msaaPipelines[(int) currentSampleCount]); + cmdbuf.DrawPrimitives(0, 1, 0, 0); + cmdbuf.EndRenderPass(); + + cmdbuf.BeginRenderPass(new ColorAttachmentInfo(backbuffer, LoadOp.DontCare)); + cmdbuf.BindGraphicsPipeline(blitPipeline); + cmdbuf.BindFragmentSamplers(new TextureSamplerBinding(rt, rtSampler)); + cmdbuf.BindVertexBuffers(quadVertexBuffer); + cmdbuf.BindIndexBuffer(quadIndexBuffer, IndexElementSize.Sixteen); + cmdbuf.DrawIndexedPrimitives(0, 0, 2, 0, 0); + cmdbuf.EndRenderPass(); + } + GraphicsDevice.Submit(cmdbuf); + } + + public static void Main(string[] args) + { + MSAAGame game = new MSAAGame(); + game.Run(); + } + } +} diff --git a/tests/MoonWorks.Test.Common/Content/Shaders/Compiled/PositionColorVert.spv b/tests/MoonWorks.Test.Common/Content/Shaders/Compiled/PositionColorVert.spv new file mode 100644 index 0000000..0852ff8 Binary files /dev/null and b/tests/MoonWorks.Test.Common/Content/Shaders/Compiled/PositionColorVert.spv differ diff --git a/tests/MoonWorks.Test.Common/Content/Shaders/Compiled/RawTriangleVertices.spv b/tests/MoonWorks.Test.Common/Content/Shaders/Compiled/RawTriangleVertices.spv new file mode 100644 index 0000000..917342f Binary files /dev/null and b/tests/MoonWorks.Test.Common/Content/Shaders/Compiled/RawTriangleVertices.spv differ diff --git a/tests/MoonWorks.Test.Common/Content/Shaders/Compiled/SolidColor.spv b/tests/MoonWorks.Test.Common/Content/Shaders/Compiled/SolidColor.spv new file mode 100644 index 0000000..211b356 Binary files /dev/null and b/tests/MoonWorks.Test.Common/Content/Shaders/Compiled/SolidColor.spv differ diff --git a/tests/MoonWorks.Test.Common/Content/Shaders/Compiled/TexturedQuadAnimatedFrag.spv b/tests/MoonWorks.Test.Common/Content/Shaders/Compiled/TexturedQuadAnimatedFrag.spv new file mode 100644 index 0000000..fa849a9 Binary files /dev/null and b/tests/MoonWorks.Test.Common/Content/Shaders/Compiled/TexturedQuadAnimatedFrag.spv differ diff --git a/tests/MoonWorks.Test.Common/Content/Shaders/Compiled/TexturedQuadAnimatedVert.spv b/tests/MoonWorks.Test.Common/Content/Shaders/Compiled/TexturedQuadAnimatedVert.spv new file mode 100644 index 0000000..e43dee2 Binary files /dev/null and b/tests/MoonWorks.Test.Common/Content/Shaders/Compiled/TexturedQuadAnimatedVert.spv differ diff --git a/tests/MoonWorks.Test.Common/Content/Shaders/Compiled/TexturedQuadFrag.spv b/tests/MoonWorks.Test.Common/Content/Shaders/Compiled/TexturedQuadFrag.spv new file mode 100644 index 0000000..d19ad27 Binary files /dev/null and b/tests/MoonWorks.Test.Common/Content/Shaders/Compiled/TexturedQuadFrag.spv differ diff --git a/tests/MoonWorks.Test.Common/Content/Shaders/Compiled/TexturedQuadVert.spv b/tests/MoonWorks.Test.Common/Content/Shaders/Compiled/TexturedQuadVert.spv new file mode 100644 index 0000000..c565481 Binary files /dev/null and b/tests/MoonWorks.Test.Common/Content/Shaders/Compiled/TexturedQuadVert.spv differ diff --git a/tests/MoonWorks.Test.Common/Content/Shaders/Source/PositionColorVert.vert b/tests/MoonWorks.Test.Common/Content/Shaders/Source/PositionColorVert.vert new file mode 100644 index 0000000..99d5237 --- /dev/null +++ b/tests/MoonWorks.Test.Common/Content/Shaders/Source/PositionColorVert.vert @@ -0,0 +1,12 @@ +#version 450 + +layout (location = 0) in vec3 Position; +layout (location = 1) in vec4 Color; + +layout (location = 0) out vec4 outColor; + +void main() +{ + outColor = Color; + gl_Position = vec4(Position, 1); +} diff --git a/tests/MoonWorks.Test.Common/Content/Shaders/Source/RawTriangleVertices.vert b/tests/MoonWorks.Test.Common/Content/Shaders/Source/RawTriangleVertices.vert new file mode 100644 index 0000000..fba105d --- /dev/null +++ b/tests/MoonWorks.Test.Common/Content/Shaders/Source/RawTriangleVertices.vert @@ -0,0 +1,26 @@ +#version 450 + +layout (location = 0) out vec4 outColor; + +void main() +{ + vec2 pos; + + if (gl_VertexIndex == 0) + { + pos = vec2(-1, 1); + outColor = vec4(1, 0, 0, 1); + } + else if (gl_VertexIndex == 1) + { + pos = vec2(1, 1); + outColor = vec4(0, 1, 0, 1); + } + else if (gl_VertexIndex == 2) + { + pos = vec2(0, -1); + outColor = vec4(0, 0, 1, 1); + } + + gl_Position = vec4(pos, 0, 1); +} diff --git a/tests/MoonWorks.Test.Common/Content/Shaders/Source/SolidColor.frag b/tests/MoonWorks.Test.Common/Content/Shaders/Source/SolidColor.frag new file mode 100644 index 0000000..ec2d430 --- /dev/null +++ b/tests/MoonWorks.Test.Common/Content/Shaders/Source/SolidColor.frag @@ -0,0 +1,10 @@ +#version 450 + +layout (location = 0) in vec4 Color; + +layout (location = 0) out vec4 FragColor; + +void main() +{ + FragColor = Color; +} diff --git a/tests/MoonWorks.Test.Common/Content/Shaders/Source/TexturedQuadAnimatedFrag.frag b/tests/MoonWorks.Test.Common/Content/Shaders/Source/TexturedQuadAnimatedFrag.frag new file mode 100644 index 0000000..5e0db2e --- /dev/null +++ b/tests/MoonWorks.Test.Common/Content/Shaders/Source/TexturedQuadAnimatedFrag.frag @@ -0,0 +1,17 @@ +#version 450 + +layout (location = 0) in vec2 TexCoord; + +layout (location = 0) out vec4 FragColor; + +layout(binding = 0, set = 1) uniform sampler2D Sampler; + +layout (binding = 0, set = 3) uniform UniformBlock +{ + vec4 MultiplyColor; +}; + +void main() +{ + FragColor = MultiplyColor * texture(Sampler, TexCoord); +} diff --git a/tests/MoonWorks.Test.Common/Content/Shaders/Source/TexturedQuadAnimatedVert.vert b/tests/MoonWorks.Test.Common/Content/Shaders/Source/TexturedQuadAnimatedVert.vert new file mode 100644 index 0000000..080dfb5 --- /dev/null +++ b/tests/MoonWorks.Test.Common/Content/Shaders/Source/TexturedQuadAnimatedVert.vert @@ -0,0 +1,17 @@ +#version 450 + +layout (location = 0) in vec3 Position; +layout (location = 1) in vec2 TexCoord; + +layout (location = 0) out vec2 outTexCoord; + +layout (binding = 0, set = 2) uniform UniformBlock +{ + mat4x4 MatrixTransform; +}; + +void main() +{ + outTexCoord = TexCoord; + gl_Position = MatrixTransform * vec4(Position, 1); +} diff --git a/tests/MoonWorks.Test.Common/Content/Shaders/Source/TexturedQuadFrag.frag b/tests/MoonWorks.Test.Common/Content/Shaders/Source/TexturedQuadFrag.frag new file mode 100644 index 0000000..c4237bd --- /dev/null +++ b/tests/MoonWorks.Test.Common/Content/Shaders/Source/TexturedQuadFrag.frag @@ -0,0 +1,12 @@ +#version 450 + +layout (location = 0) in vec2 TexCoord; + +layout (location = 0) out vec4 FragColor; + +layout(binding = 0, set = 1) uniform sampler2D Sampler; + +void main() +{ + FragColor = texture(Sampler, TexCoord); +} diff --git a/tests/MoonWorks.Test.Common/Content/Shaders/Source/TexturedQuadVert.vert b/tests/MoonWorks.Test.Common/Content/Shaders/Source/TexturedQuadVert.vert new file mode 100644 index 0000000..ff0d240 --- /dev/null +++ b/tests/MoonWorks.Test.Common/Content/Shaders/Source/TexturedQuadVert.vert @@ -0,0 +1,12 @@ +#version 450 + +layout (location = 0) in vec3 Position; +layout (location = 1) in vec2 TexCoord; + +layout (location = 0) out vec2 outTexCoord; + +void main() +{ + outTexCoord = TexCoord; + gl_Position = vec4(Position, 1); +} diff --git a/tests/MoonWorks.Test.Common/Content/Shaders/compileShaders.ps1 b/tests/MoonWorks.Test.Common/Content/Shaders/compileShaders.ps1 new file mode 100644 index 0000000..aa16bf5 --- /dev/null +++ b/tests/MoonWorks.Test.Common/Content/Shaders/compileShaders.ps1 @@ -0,0 +1,5 @@ +Get-ChildItem "Source" | +Foreach-Object { + $filename = $_.Basename + glslc $_.FullName -o Compiled/$filename.spv +} diff --git a/tests/MoonWorks.Test.Common/Content/Textures/ravioli.png b/tests/MoonWorks.Test.Common/Content/Textures/ravioli.png new file mode 100644 index 0000000..f202cb2 Binary files /dev/null and b/tests/MoonWorks.Test.Common/Content/Textures/ravioli.png differ diff --git a/tests/MoonWorks.Test.Common/CopyMoonlibs.targets b/tests/MoonWorks.Test.Common/CopyMoonlibs.targets new file mode 100644 index 0000000..c1b4245 --- /dev/null +++ b/tests/MoonWorks.Test.Common/CopyMoonlibs.targets @@ -0,0 +1,43 @@ + + + + + + + + + + %(RecursiveDir)%(Filename)%(Extension) + PreserveNewest + + + %(RecursiveDir)%(Filename)%(Extension) + PreserveNewest + + + %(RecursiveDir)%(Filename)%(Extension) + PreserveNewest + + + + + %(RecursiveDir)%(Filename)%(Extension) + PreserveNewest + + + %(RecursiveDir)%(Filename)%(Extension) + PreserveNewest + + + %(RecursiveDir)%(Filename)%(Extension) + PreserveNewest + + + + + %(RecursiveDir)%(Filename)%(Extension) + PreserveNewest + + + + diff --git a/tests/MoonWorks.Test.Common/MoonWorks.Test.Common.csproj b/tests/MoonWorks.Test.Common/MoonWorks.Test.Common.csproj new file mode 100644 index 0000000..5c33609 --- /dev/null +++ b/tests/MoonWorks.Test.Common/MoonWorks.Test.Common.csproj @@ -0,0 +1,16 @@ + + + + + + + + library + net6.0 + enable + x64 + + + + + diff --git a/tests/MoonWorks.Test.Common/TestUtils.cs b/tests/MoonWorks.Test.Common/TestUtils.cs new file mode 100644 index 0000000..801b467 --- /dev/null +++ b/tests/MoonWorks.Test.Common/TestUtils.cs @@ -0,0 +1,53 @@ +using MoonWorks.Graphics; + +namespace MoonWorks.Test +{ + public static class TestUtils + { + public static WindowCreateInfo GetStandardWindowCreateInfo() + { + return new WindowCreateInfo( + "Main Window", + 640, + 480, + ScreenMode.Windowed, + PresentMode.FIFO + ); + } + + public static FrameLimiterSettings GetStandardFrameLimiterSettings() + { + return new FrameLimiterSettings( + FrameLimiterMode.Capped, + 60 + ); + } + + public static GraphicsPipelineCreateInfo GetStandardGraphicsPipelineCreateInfo( + ShaderModule vertShaderModule, + ShaderModule fragShaderModule + ) { + return new GraphicsPipelineCreateInfo + { + AttachmentInfo = new GraphicsPipelineAttachmentInfo( + new ColorAttachmentDescription( + TextureFormat.R8G8B8A8, + ColorAttachmentBlendState.Opaque + ) + ), + DepthStencilState = DepthStencilState.Disable, + MultisampleState = MultisampleState.None, + PrimitiveType = PrimitiveType.TriangleList, + RasterizerState = RasterizerState.CW_CullNone, + VertexInputState = VertexInputState.Empty, + VertexShaderInfo = GraphicsShaderInfo.Create(vertShaderModule, "main", 0), + FragmentShaderInfo = GraphicsShaderInfo.Create(fragShaderModule, "main", 0) + }; + } + + public static string GetShaderPath(string shaderName) + { + return SDL2.SDL.SDL_GetBasePath() + "Content/Shaders/Compiled/" + shaderName; + } + } +} diff --git a/tests/MoonWorks.Test.Common/VertexTypes.cs b/tests/MoonWorks.Test.Common/VertexTypes.cs new file mode 100644 index 0000000..fe7c1c9 --- /dev/null +++ b/tests/MoonWorks.Test.Common/VertexTypes.cs @@ -0,0 +1,32 @@ +using System.Runtime.InteropServices; +using MoonWorks.Graphics; +using MoonWorks.Math.Float; + +namespace MoonWorks.Test +{ + [StructLayout(LayoutKind.Sequential)] + public struct PositionColorVertex + { + public Vector3 Position; + public Color Color; + + public PositionColorVertex(Vector3 position, Color color) + { + Position = position; + Color = color; + } + } + + [StructLayout(LayoutKind.Sequential)] + public struct PositionTextureVertex + { + public Vector3 Position; + public Vector2 TexCoord; + + public PositionTextureVertex(Vector3 position, Vector2 texCoord) + { + Position = position; + TexCoord = texCoord; + } + } +} diff --git a/tests/TexturedAnimatedQuad/TexturedAnimatedQuad.csproj b/tests/TexturedAnimatedQuad/TexturedAnimatedQuad.csproj new file mode 100644 index 0000000..e0a93fd --- /dev/null +++ b/tests/TexturedAnimatedQuad/TexturedAnimatedQuad.csproj @@ -0,0 +1,22 @@ + + + + + + + + + Exe + net6.0 + enable + x64 + + + + + Content\%(RecursiveDir)%(Filename)%(Extension) + Always + + + + diff --git a/tests/TexturedAnimatedQuad/TexturedAnimatedQuadGame.cs b/tests/TexturedAnimatedQuad/TexturedAnimatedQuadGame.cs new file mode 100644 index 0000000..e1ee4d9 --- /dev/null +++ b/tests/TexturedAnimatedQuad/TexturedAnimatedQuadGame.cs @@ -0,0 +1,121 @@ +using System.Runtime.InteropServices; +using MoonWorks; +using MoonWorks.Graphics; +using MoonWorks.Math.Float; + +namespace MoonWorks.Test +{ + class TexturedAnimatedQuadGame : Game + { + private GraphicsPipeline pipeline; + private ShaderModule vertShaderModule; + private ShaderModule fragShaderModule; + private Buffer vertexBuffer; + private Buffer indexBuffer; + private Texture texture; + private Sampler sampler; + + private float t; + + [StructLayout(LayoutKind.Sequential)] + private struct VertexUniforms + { + public Matrix4x4 TransformMatrix; + + public VertexUniforms(Matrix4x4 transformMatrix) + { + TransformMatrix = transformMatrix; + } + } + + [StructLayout(LayoutKind.Sequential)] + private struct FragmentUniforms + { + public Vector4 MultiplyColor; + + public FragmentUniforms(Vector4 multiplyColor) + { + MultiplyColor = multiplyColor; + } + } + + public TexturedAnimatedQuadGame() : base(TestUtils.GetStandardWindowCreateInfo(), TestUtils.GetStandardFrameLimiterSettings(), 60, true) + { + // Load the shaders + vertShaderModule = new ShaderModule(GraphicsDevice, TestUtils.GetShaderPath("TexturedQuadAnimatedVert.spv")); + fragShaderModule = new ShaderModule(GraphicsDevice, TestUtils.GetShaderPath("TexturedQuadAnimatedFrag.spv")); + + // Create the graphics pipeline + GraphicsPipelineCreateInfo pipelineCreateInfo = TestUtils.GetStandardGraphicsPipelineCreateInfo(vertShaderModule, fragShaderModule); + pipelineCreateInfo.VertexInputState = new VertexInputState( + VertexBinding.Create(), + VertexAttribute.Create("Position", 0), + VertexAttribute.Create("TexCoord", 1) + ); + pipelineCreateInfo.VertexShaderInfo = GraphicsShaderInfo.Create(vertShaderModule, "main", 0); + pipelineCreateInfo.FragmentShaderInfo = GraphicsShaderInfo.Create(fragShaderModule, "main", 1); + pipeline = new GraphicsPipeline(GraphicsDevice, pipelineCreateInfo); + + // Create and populate the GPU resources + vertexBuffer = Buffer.Create(GraphicsDevice, BufferUsageFlags.Vertex, 4); + indexBuffer = Buffer.Create(GraphicsDevice, BufferUsageFlags.Index, 6); + sampler = new Sampler(GraphicsDevice, SamplerCreateInfo.PointClamp); + + CommandBuffer cmdbuf = GraphicsDevice.AcquireCommandBuffer(); + cmdbuf.SetBufferData( + vertexBuffer, + new PositionTextureVertex[] + { + new PositionTextureVertex(new Vector3(-1, -1, 0), new Vector2(0, 0)), + new PositionTextureVertex(new Vector3(1, -1, 0), new Vector2(1, 0)), + new PositionTextureVertex(new Vector3(1, 1, 0), new Vector2(1, 1)), + new PositionTextureVertex(new Vector3(-1, 1, 0), new Vector2(0, 1)), + } + ); + cmdbuf.SetBufferData( + indexBuffer, + new ushort[] + { + 0, 1, 2, + 0, 2, 3, + } + ); + texture = Texture.LoadPNG(GraphicsDevice, cmdbuf, "Content/Textures/ravioli.png"); + GraphicsDevice.Submit(cmdbuf); + GraphicsDevice.Wait(); + } + + protected override void Update(System.TimeSpan delta) + { + t += (float) delta.TotalSeconds; + } + + protected override void Draw(double alpha) + { + VertexUniforms vertUniforms = new VertexUniforms(Matrix4x4.CreateRotationZ(t)); + FragmentUniforms fragUniforms = new FragmentUniforms(new Vector4(1f, 0.5f + System.MathF.Sin(t) * 0.5f, 1f, 1f)); + + CommandBuffer cmdbuf = GraphicsDevice.AcquireCommandBuffer(); + Texture? backbuffer = cmdbuf.AcquireSwapchainTexture(MainWindow); + if (backbuffer != null) + { + cmdbuf.BeginRenderPass(new ColorAttachmentInfo(backbuffer, Color.Black)); + cmdbuf.BindGraphicsPipeline(pipeline); + cmdbuf.BindVertexBuffers(vertexBuffer); + cmdbuf.BindIndexBuffer(indexBuffer, IndexElementSize.Sixteen); + cmdbuf.PushVertexShaderUniforms(vertUniforms); + cmdbuf.BindFragmentSamplers(new TextureSamplerBinding(texture, sampler)); + cmdbuf.PushFragmentShaderUniforms(fragUniforms); + cmdbuf.DrawIndexedPrimitives(0, 0, 2, 0, 0); + cmdbuf.EndRenderPass(); + } + GraphicsDevice.Submit(cmdbuf); + } + + public static void Main(string[] args) + { + TexturedAnimatedQuadGame game = new TexturedAnimatedQuadGame(); + game.Run(); + } + } +} diff --git a/tests/TexturedQuad/TexturedQuad.csproj b/tests/TexturedQuad/TexturedQuad.csproj new file mode 100644 index 0000000..9538ed1 --- /dev/null +++ b/tests/TexturedQuad/TexturedQuad.csproj @@ -0,0 +1,22 @@ + + + + + + + + + Exe + net6.0 + enable + x64 + + + + + Content\%(RecursiveDir)%(Filename)%(Extension) + Always + + + + diff --git a/tests/TexturedQuad/TexturedQuadGame.cs b/tests/TexturedQuad/TexturedQuadGame.cs new file mode 100644 index 0000000..e2e3086 --- /dev/null +++ b/tests/TexturedQuad/TexturedQuadGame.cs @@ -0,0 +1,134 @@ +using MoonWorks; +using MoonWorks.Graphics; +using MoonWorks.Math.Float; + +namespace MoonWorks.Test +{ + class TexturedQuadGame : Game + { + private GraphicsPipeline pipeline; + private ShaderModule vertShaderModule; + private ShaderModule fragShaderModule; + private Buffer vertexBuffer; + private Buffer indexBuffer; + private Texture texture; + private Sampler[] samplers = new Sampler[6]; + private string[] samplerNames = new string[] + { + "PointClamp", + "PointWrap", + "LinearClamp", + "LinearWrap", + "AnisotropicClamp", + "AnisotropicWrap" + }; + + private int currentSamplerIndex; + + public TexturedQuadGame() : base(TestUtils.GetStandardWindowCreateInfo(), TestUtils.GetStandardFrameLimiterSettings(), 60, true) + { + Logger.LogInfo("Press A and D to cycle between sampler states"); + Logger.LogInfo("Setting sampler state to: " + samplerNames[0]); + + // Load the shaders + vertShaderModule = new ShaderModule(GraphicsDevice, TestUtils.GetShaderPath("TexturedQuadVert.spv")); + fragShaderModule = new ShaderModule(GraphicsDevice, TestUtils.GetShaderPath("TexturedQuadFrag.spv")); + + // Create the graphics pipeline + GraphicsPipelineCreateInfo pipelineCreateInfo = TestUtils.GetStandardGraphicsPipelineCreateInfo(vertShaderModule, fragShaderModule); + pipelineCreateInfo.VertexInputState = new VertexInputState( + VertexBinding.Create(), + VertexAttribute.Create("Position", 0), + VertexAttribute.Create("TexCoord", 1) + ); + pipelineCreateInfo.FragmentShaderInfo.SamplerBindingCount = 1; + pipeline = new GraphicsPipeline(GraphicsDevice, pipelineCreateInfo); + + // Create samplers + samplers[0] = new Sampler(GraphicsDevice, SamplerCreateInfo.PointClamp); + samplers[1] = new Sampler(GraphicsDevice, SamplerCreateInfo.PointWrap); + samplers[2] = new Sampler(GraphicsDevice, SamplerCreateInfo.LinearClamp); + samplers[3] = new Sampler(GraphicsDevice, SamplerCreateInfo.LinearWrap); + samplers[4] = new Sampler(GraphicsDevice, SamplerCreateInfo.AnisotropicClamp); + samplers[5] = new Sampler(GraphicsDevice, SamplerCreateInfo.AnisotropicWrap); + + // Create and populate the GPU resources + vertexBuffer = Buffer.Create(GraphicsDevice, BufferUsageFlags.Vertex, 4); + indexBuffer = Buffer.Create(GraphicsDevice, BufferUsageFlags.Index, 6); + + CommandBuffer cmdbuf = GraphicsDevice.AcquireCommandBuffer(); + cmdbuf.SetBufferData( + vertexBuffer, + new PositionTextureVertex[] + { + new PositionTextureVertex(new Vector3(-1, -1, 0), new Vector2(0, 0)), + new PositionTextureVertex(new Vector3(1, -1, 0), new Vector2(4, 0)), + new PositionTextureVertex(new Vector3(1, 1, 0), new Vector2(4, 4)), + new PositionTextureVertex(new Vector3(-1, 1, 0), new Vector2(0, 4)), + } + ); + cmdbuf.SetBufferData( + indexBuffer, + new ushort[] + { + 0, 1, 2, + 0, 2, 3, + } + ); + texture = Texture.LoadPNG(GraphicsDevice, cmdbuf, "Content/Textures/ravioli.png"); + GraphicsDevice.Submit(cmdbuf); + GraphicsDevice.Wait(); + } + + protected override void Update(System.TimeSpan delta) + { + int prevSamplerIndex = currentSamplerIndex; + + if (Inputs.Keyboard.IsPressed(Input.KeyCode.A)) + { + currentSamplerIndex -= 1; + if (currentSamplerIndex < 0) + { + currentSamplerIndex = samplers.Length - 1; + } + } + + if (Inputs.Keyboard.IsPressed(Input.KeyCode.D)) + { + currentSamplerIndex += 1; + if (currentSamplerIndex >= samplers.Length) + { + currentSamplerIndex = 0; + } + } + + if (prevSamplerIndex != currentSamplerIndex) + { + Logger.LogInfo("Setting sampler state to: " + samplerNames[currentSamplerIndex]); + } + } + + protected override void Draw(double alpha) + { + CommandBuffer cmdbuf = GraphicsDevice.AcquireCommandBuffer(); + Texture? backbuffer = cmdbuf.AcquireSwapchainTexture(MainWindow); + if (backbuffer != null) + { + cmdbuf.BeginRenderPass(new ColorAttachmentInfo(backbuffer, Color.Black)); + cmdbuf.BindGraphicsPipeline(pipeline); + cmdbuf.BindVertexBuffers(vertexBuffer); + cmdbuf.BindIndexBuffer(indexBuffer, IndexElementSize.Sixteen); + cmdbuf.BindFragmentSamplers(new TextureSamplerBinding(texture, samplers[currentSamplerIndex])); + cmdbuf.DrawIndexedPrimitives(0, 0, 2, 0, 0); + cmdbuf.EndRenderPass(); + } + GraphicsDevice.Submit(cmdbuf); + } + + public static void Main(string[] args) + { + TexturedQuadGame game = new TexturedQuadGame(); + game.Run(); + } + } +} diff --git a/tests/TriangleVertexBuffer/TriangleVertexBuffer.csproj b/tests/TriangleVertexBuffer/TriangleVertexBuffer.csproj new file mode 100644 index 0000000..9538ed1 --- /dev/null +++ b/tests/TriangleVertexBuffer/TriangleVertexBuffer.csproj @@ -0,0 +1,22 @@ + + + + + + + + + Exe + net6.0 + enable + x64 + + + + + Content\%(RecursiveDir)%(Filename)%(Extension) + Always + + + + diff --git a/tests/TriangleVertexBuffer/TriangleVertexBufferGame.cs b/tests/TriangleVertexBuffer/TriangleVertexBufferGame.cs new file mode 100644 index 0000000..8e7eab0 --- /dev/null +++ b/tests/TriangleVertexBuffer/TriangleVertexBufferGame.cs @@ -0,0 +1,69 @@ +using MoonWorks; +using MoonWorks.Graphics; +using MoonWorks.Math.Float; + +namespace MoonWorks.Test +{ + class TriangleVertexBufferGame : Game + { + private GraphicsPipeline pipeline; + private ShaderModule vertShaderModule; + private ShaderModule fragShaderModule; + private Buffer vertexBuffer; + + public TriangleVertexBufferGame() : base(TestUtils.GetStandardWindowCreateInfo(), TestUtils.GetStandardFrameLimiterSettings(), 60, true) + { + // Load the shaders + vertShaderModule = new ShaderModule(GraphicsDevice, "Content/Shaders/Compiled/PositionColorVert.spv"); + fragShaderModule = new ShaderModule(GraphicsDevice, "Content/Shaders/Compiled/SolidColor.spv"); + + // Create the graphics pipeline + GraphicsPipelineCreateInfo pipelineCreateInfo = TestUtils.GetStandardGraphicsPipelineCreateInfo(vertShaderModule, fragShaderModule); + pipelineCreateInfo.VertexInputState = new VertexInputState( + VertexBinding.Create(), + VertexAttribute.Create("Position", 0), + VertexAttribute.Create("Color", 1) + ); + pipeline = new GraphicsPipeline(GraphicsDevice, pipelineCreateInfo); + + // Create and populate the vertex buffer + vertexBuffer = Buffer.Create(GraphicsDevice, BufferUsageFlags.Vertex, 3); + + CommandBuffer cmdbuf = GraphicsDevice.AcquireCommandBuffer(); + cmdbuf.SetBufferData( + vertexBuffer, + new PositionColorVertex[] + { + new PositionColorVertex(new Vector3(-1, 1, 0), Color.Red), + new PositionColorVertex(new Vector3(1, 1, 0), Color.Lime), + new PositionColorVertex(new Vector3(0, -1, 0), Color.Blue), + } + ); + GraphicsDevice.Submit(cmdbuf); + GraphicsDevice.Wait(); + } + + protected override void Update(System.TimeSpan delta) { } + + protected override void Draw(double alpha) + { + CommandBuffer cmdbuf = GraphicsDevice.AcquireCommandBuffer(); + Texture? backbuffer = cmdbuf.AcquireSwapchainTexture(MainWindow); + if (backbuffer != null) + { + cmdbuf.BeginRenderPass(new ColorAttachmentInfo(backbuffer, Color.Black)); + cmdbuf.BindGraphicsPipeline(pipeline); + cmdbuf.BindVertexBuffers(vertexBuffer); + cmdbuf.DrawPrimitives(0, 1, 0, 0); + cmdbuf.EndRenderPass(); + } + GraphicsDevice.Submit(cmdbuf); + } + + public static void Main(string[] args) + { + TriangleVertexBufferGame p = new TriangleVertexBufferGame(); + p.Run(); + } + } +}