From b826ff6a89d770ce9c48afcc65568c431c66a65b Mon Sep 17 00:00:00 2001 From: cosmonaut Date: Thu, 6 Jun 2024 15:11:11 -0700 Subject: [PATCH] RenderTextureMipmapsExample --- Examples/RenderTextureMipmapsExample.cs | 227 ++++++++++++++++++++++++ Examples/RenderTextureMipmapsGame.cs | 187 ------------------- MoonWorksGraphicsTests.csproj | 1 + Program.cs | 3 +- 4 files changed, 230 insertions(+), 188 deletions(-) create mode 100644 Examples/RenderTextureMipmapsExample.cs delete mode 100644 Examples/RenderTextureMipmapsGame.cs diff --git a/Examples/RenderTextureMipmapsExample.cs b/Examples/RenderTextureMipmapsExample.cs new file mode 100644 index 0000000..7a07f90 --- /dev/null +++ b/Examples/RenderTextureMipmapsExample.cs @@ -0,0 +1,227 @@ +using MoonWorks; +using MoonWorks.Graphics; +using MoonWorks.Input; +using MoonWorks.Math.Float; + +namespace MoonWorksGraphicsTests; + +class RenderTextureMipmapsExample : Example +{ + private GraphicsPipeline Pipeline; + private GpuBuffer VertexBuffer; + private GpuBuffer IndexBuffer; + private Texture Texture; + + private Sampler[] Samplers = new Sampler[5]; + + private float scale = 0.5f; + private int currentSamplerIndex = 0; + private Color[] colors = + [ + Color.Red, + Color.Green, + Color.Blue, + Color.Yellow, + ]; + + private string GetSamplerString(int index) + { + switch (index) + { + case 0: + return "PointClamp"; + case 1: + return "LinearClamp"; + case 2: + return "PointClamp with Mip LOD Bias = 0.25"; + case 3: + return "PointClamp with Min LOD = 1"; + case 4: + return "PointClamp with Max LOD = 1"; + default: + throw new System.Exception("Unknown sampler!"); + } + } + + public override void Init(Window window, GraphicsDevice graphicsDevice, Inputs inputs) + { + Window = window; + GraphicsDevice = graphicsDevice; + Inputs = inputs; + + Window.SetTitle("RenderTextureMipmaps"); + + Logger.LogInfo("Press Left and Right to shrink/expand the scale of the quad"); + Logger.LogInfo("Press Down to cycle through sampler states"); + Logger.LogInfo(GetSamplerString(currentSamplerIndex)); + + // Load the shaders + Shader vertShaderModule = new Shader( + GraphicsDevice, + TestUtils.GetShaderPath("TexturedQuadWithMatrix.vert"), + "main", + ShaderStage.Vertex, + ShaderFormat.SPIRV + ); + + Shader fragShaderModule = new Shader( + GraphicsDevice, + TestUtils.GetShaderPath("TexturedQuad.frag"), + "main", + ShaderStage.Fragment, + ShaderFormat.SPIRV + ); + + // Create the graphics pipeline + GraphicsPipelineCreateInfo pipelineCreateInfo = TestUtils.GetStandardGraphicsPipelineCreateInfo( + Window.SwapchainFormat, + vertShaderModule, + fragShaderModule + ); + pipelineCreateInfo.VertexInputState = VertexInputState.CreateSingleBinding(); + pipelineCreateInfo.VertexShaderResourceInfo = new GraphicsPipelineResourceInfo + { + UniformBufferCount = 1 + }; + pipelineCreateInfo.FragmentShaderResourceInfo = new GraphicsPipelineResourceInfo + { + SamplerCount = 1 + }; + Pipeline = new GraphicsPipeline(GraphicsDevice, pipelineCreateInfo); + + // Create samplers + SamplerCreateInfo samplerCreateInfo = SamplerCreateInfo.PointClamp; + Samplers[0] = new Sampler(GraphicsDevice, samplerCreateInfo); + + samplerCreateInfo = SamplerCreateInfo.LinearClamp; + Samplers[1] = new Sampler(GraphicsDevice, samplerCreateInfo); + + samplerCreateInfo = SamplerCreateInfo.PointClamp; + samplerCreateInfo.MipLodBias = 0.25f; + Samplers[2] = new Sampler(GraphicsDevice, samplerCreateInfo); + + samplerCreateInfo = SamplerCreateInfo.PointClamp; + samplerCreateInfo.MinLod = 1; + Samplers[3] = new Sampler(GraphicsDevice, samplerCreateInfo); + + samplerCreateInfo = SamplerCreateInfo.PointClamp; + samplerCreateInfo.MaxLod = 1; + Samplers[4] = new Sampler(GraphicsDevice, samplerCreateInfo); + + // Create and populate the GPU resources + var resourceUploader = new ResourceUploader(GraphicsDevice); + + VertexBuffer = resourceUploader.CreateBuffer( + [ + 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)), + ], + BufferUsageFlags.Vertex + ); + + IndexBuffer = resourceUploader.CreateBuffer( + [ + 0, 1, 2, + 0, 2, 3, + ], + BufferUsageFlags.Index + ); + + resourceUploader.Upload(); + resourceUploader.Dispose(); + + Texture = Texture.CreateTexture2D( + GraphicsDevice, + Window.Width, + Window.Height, + TextureFormat.R8G8B8A8, + TextureUsageFlags.ColorTarget | TextureUsageFlags.Sampler, + 4 + ); + + CommandBuffer cmdbuf = GraphicsDevice.AcquireCommandBuffer(); + + // Clear each mip level to a different color + for (uint i = 0; i < Texture.LevelCount; i += 1) + { + ColorAttachmentInfo attachmentInfo = new ColorAttachmentInfo + { + TextureSlice = new TextureSlice + { + Texture = Texture, + Layer = 0, + MipLevel = i + }, + ClearColor = colors[i], + LoadOp = LoadOp.Clear, + StoreOp = StoreOp.Store, + Cycle = false + }; + var renderPass = cmdbuf.BeginRenderPass(attachmentInfo); + cmdbuf.EndRenderPass(renderPass); + } + + GraphicsDevice.Submit(cmdbuf); + } + + public override void Update(System.TimeSpan delta) + { + if (TestUtils.CheckButtonDown(Inputs, TestUtils.ButtonType.Left)) + { + scale = System.MathF.Max(0.01f, scale - 0.01f); + } + + if (TestUtils.CheckButtonDown(Inputs, TestUtils.ButtonType.Right)) + { + scale = System.MathF.Min(1f, scale + 0.01f); + } + + if (TestUtils.CheckButtonPressed(Inputs, TestUtils.ButtonType.Bottom)) + { + currentSamplerIndex = (currentSamplerIndex + 1) % Samplers.Length; + Logger.LogInfo(GetSamplerString(currentSamplerIndex)); + } + } + + public override void Draw(double alpha) + { + TransformVertexUniform vertUniforms = new TransformVertexUniform(Matrix4x4.CreateScale(scale, scale, 1)); + + CommandBuffer cmdbuf = GraphicsDevice.AcquireCommandBuffer(); + Texture swapchainTexture = cmdbuf.AcquireSwapchainTexture(Window); + if (swapchainTexture != null) + { + var renderPass = cmdbuf.BeginRenderPass( + new ColorAttachmentInfo( + swapchainTexture, + false, + Color.Black + ) + ); + renderPass.BindGraphicsPipeline(Pipeline); + renderPass.BindVertexBuffer(VertexBuffer); + renderPass.BindIndexBuffer(IndexBuffer, IndexElementSize.Sixteen); + renderPass.BindFragmentSampler(new TextureSamplerBinding(Texture, Samplers[currentSamplerIndex])); + renderPass.PushVertexUniformData(vertUniforms); + renderPass.DrawIndexedPrimitives(0, 0, 2); + cmdbuf.EndRenderPass(renderPass); + } + + GraphicsDevice.Submit(cmdbuf); + } + + public override void Destroy() + { + Pipeline.Dispose(); + VertexBuffer.Dispose(); + IndexBuffer.Dispose(); + Texture.Dispose(); + + for (var i = 0; i < 5; i += 1) + { + Samplers[i].Dispose(); + } + } +} diff --git a/Examples/RenderTextureMipmapsGame.cs b/Examples/RenderTextureMipmapsGame.cs deleted file mode 100644 index d5bcf95..0000000 --- a/Examples/RenderTextureMipmapsGame.cs +++ /dev/null @@ -1,187 +0,0 @@ -using MoonWorks.Graphics; -using MoonWorks.Math.Float; - -namespace MoonWorks.Test -{ - class RenderTextureMipmapsGame : Game - { - private GraphicsPipeline pipeline; - private GpuBuffer vertexBuffer; - private GpuBuffer indexBuffer; - private Texture texture; - - private Sampler[] samplers = new Sampler[5]; - - private float scale = 0.5f; - private int currentSamplerIndex = 0; - private Color[] colors = new Color[] - { - Color.Red, - Color.Green, - Color.Blue, - Color.Yellow, - }; - - private string GetSamplerString(int index) - { - switch (index) - { - case 0: - return "PointClamp"; - case 1: - return "LinearClamp"; - case 2: - return "PointClamp with Mip LOD Bias = 0.25"; - case 3: - return "PointClamp with Min LOD = 1"; - case 4: - return "PointClamp with Max LOD = 1"; - default: - throw new System.Exception("Unknown sampler!"); - } - } - - public RenderTextureMipmapsGame() : base(TestUtils.GetStandardWindowCreateInfo(), TestUtils.GetStandardFrameLimiterSettings(), TestUtils.PreferredBackends, 60, true) - { - Logger.LogInfo("Press Left and Right to shrink/expand the scale of the quad"); - Logger.LogInfo("Press Down to cycle through sampler states"); - Logger.LogInfo(GetSamplerString(currentSamplerIndex)); - - // Load the shaders - ShaderModule vertShaderModule = new ShaderModule(GraphicsDevice, TestUtils.GetShaderPath("TexturedQuadWithMatrix.vert")); - ShaderModule fragShaderModule = new ShaderModule(GraphicsDevice, TestUtils.GetShaderPath("TexturedQuad.frag")); - - // Create the graphics pipeline - GraphicsPipelineCreateInfo pipelineCreateInfo = TestUtils.GetStandardGraphicsPipelineCreateInfo( - MainWindow.SwapchainFormat, - vertShaderModule, - fragShaderModule - ); - pipelineCreateInfo.VertexInputState = VertexInputState.CreateSingleBinding(); - pipelineCreateInfo.VertexShaderInfo = GraphicsShaderInfo.Create(vertShaderModule, "main", 0); - pipelineCreateInfo.FragmentShaderInfo.SamplerBindingCount = 1; - pipeline = new GraphicsPipeline(GraphicsDevice, pipelineCreateInfo); - - // Create samplers - SamplerCreateInfo samplerCreateInfo = SamplerCreateInfo.PointClamp; - samplers[0] = new Sampler(GraphicsDevice, samplerCreateInfo); - - samplerCreateInfo = SamplerCreateInfo.LinearClamp; - samplers[1] = new Sampler(GraphicsDevice, samplerCreateInfo); - - samplerCreateInfo = SamplerCreateInfo.PointClamp; - samplerCreateInfo.MipLodBias = 0.25f; - samplers[2] = new Sampler(GraphicsDevice, samplerCreateInfo); - - samplerCreateInfo = SamplerCreateInfo.PointClamp; - samplerCreateInfo.MinLod = 1; - samplers[3] = new Sampler(GraphicsDevice, samplerCreateInfo); - - samplerCreateInfo = SamplerCreateInfo.PointClamp; - samplerCreateInfo.MaxLod = 1; - samplers[4] = new Sampler(GraphicsDevice, samplerCreateInfo); - - // Create and populate the GPU resources - var resourceUploader = new ResourceUploader(GraphicsDevice); - - vertexBuffer = resourceUploader.CreateBuffer( - [ - 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)), - ], - BufferUsageFlags.Vertex - ); - - indexBuffer = resourceUploader.CreateBuffer( - [ - 0, 1, 2, - 0, 2, 3, - ], - BufferUsageFlags.Index - ); - - resourceUploader.Upload(); - resourceUploader.Dispose(); - - texture = Texture.CreateTexture2D( - GraphicsDevice, - MainWindow.Width, - MainWindow.Height, - TextureFormat.R8G8B8A8, - TextureUsageFlags.ColorTarget | TextureUsageFlags.Sampler, - 4 - ); - - CommandBuffer cmdbuf = GraphicsDevice.AcquireCommandBuffer(); - - // Clear each mip level to a different color - for (uint i = 0; i < texture.LevelCount; i += 1) - { - ColorAttachmentInfo attachmentInfo = new ColorAttachmentInfo - { - TextureSlice = new TextureSlice - { - Texture = texture, - Layer = 0, - MipLevel = i - }, - ClearColor = colors[i], - LoadOp = LoadOp.Clear, - StoreOp = StoreOp.Store, - WriteOption = WriteOptions.Safe - }; - cmdbuf.BeginRenderPass(attachmentInfo); - cmdbuf.EndRenderPass(); - } - - GraphicsDevice.Submit(cmdbuf); - } - - protected override void Update(System.TimeSpan delta) - { - if (TestUtils.CheckButtonDown(Inputs, TestUtils.ButtonType.Left)) - { - scale = System.MathF.Max(0.01f, scale - 0.01f); - } - - if (TestUtils.CheckButtonDown(Inputs, TestUtils.ButtonType.Right)) - { - scale = System.MathF.Min(1f, scale + 0.01f); - } - - if (TestUtils.CheckButtonPressed(Inputs, TestUtils.ButtonType.Bottom)) - { - currentSamplerIndex = (currentSamplerIndex + 1) % samplers.Length; - Logger.LogInfo(GetSamplerString(currentSamplerIndex)); - } - } - - protected override void Draw(double alpha) - { - TransformVertexUniform vertUniforms = new TransformVertexUniform(Matrix4x4.CreateScale(scale, scale, 1)); - - CommandBuffer cmdbuf = GraphicsDevice.AcquireCommandBuffer(); - Texture? backbuffer = cmdbuf.AcquireSwapchainTexture(MainWindow); - if (backbuffer != null) - { - cmdbuf.BeginRenderPass(new ColorAttachmentInfo(backbuffer, WriteOptions.Cycle, Color.Black)); - cmdbuf.BindGraphicsPipeline(pipeline); - cmdbuf.BindVertexBuffers(vertexBuffer); - cmdbuf.BindIndexBuffer(indexBuffer, IndexElementSize.Sixteen); - cmdbuf.BindFragmentSamplers(new TextureSamplerBinding(texture, samplers[currentSamplerIndex])); - cmdbuf.PushVertexShaderUniforms(vertUniforms); - cmdbuf.DrawIndexedPrimitives(0, 0, 2); - cmdbuf.EndRenderPass(); - } - GraphicsDevice.Submit(cmdbuf); - } - - public static void Main(string[] args) - { - RenderTextureMipmapsGame game = new RenderTextureMipmapsGame(); - game.Run(); - } - } -} diff --git a/MoonWorksGraphicsTests.csproj b/MoonWorksGraphicsTests.csproj index e47c7f3..53a6410 100644 --- a/MoonWorksGraphicsTests.csproj +++ b/MoonWorksGraphicsTests.csproj @@ -43,6 +43,7 @@ + diff --git a/Program.cs b/Program.cs index 13c29f9..6319e34 100644 --- a/Program.cs +++ b/Program.cs @@ -26,7 +26,8 @@ class Program : Game new MSAAExample(), new RenderTexture2DArrayExample(), new RenderTexture2DExample(), - new RenderTextureCubeExample() + new RenderTextureCubeExample(), + new RenderTextureMipmapsExample() ]; int ExampleIndex = 0;