diff --git a/MoonWorksGraphicsTests.sln b/MoonWorksGraphicsTests.sln index d151083..f8d2716 100644 --- a/MoonWorksGraphicsTests.sln +++ b/MoonWorksGraphicsTests.sln @@ -43,7 +43,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Texture3D", "Texture3D\Text EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "InstancingAndOffsets", "InstancingAndOffsets\InstancingAndOffsets.csproj", "{5CDA8D41-F96C-4DE7-AD53-5A76C4C0CC31}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VertexSampler", "VertexSampler\VertexSampler.csproj", "{C525B6DE-3003-45D5-BB83-89679B108C08}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "VertexSampler", "VertexSampler\VertexSampler.csproj", "{C525B6DE-3003-45D5-BB83-89679B108C08}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RenderTexture3D", "RenderTexture3D\RenderTexture3D.csproj", "{6D625A4C-8618-4DFC-A6AD-AA3BE3488D70}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -135,6 +137,10 @@ Global {C525B6DE-3003-45D5-BB83-89679B108C08}.Debug|x64.Build.0 = Debug|x64 {C525B6DE-3003-45D5-BB83-89679B108C08}.Release|x64.ActiveCfg = Release|Any CPU {C525B6DE-3003-45D5-BB83-89679B108C08}.Release|x64.Build.0 = Release|Any CPU + {6D625A4C-8618-4DFC-A6AD-AA3BE3488D70}.Debug|x64.ActiveCfg = Debug|x64 + {6D625A4C-8618-4DFC-A6AD-AA3BE3488D70}.Debug|x64.Build.0 = Debug|x64 + {6D625A4C-8618-4DFC-A6AD-AA3BE3488D70}.Release|x64.ActiveCfg = Release|Any CPU + {6D625A4C-8618-4DFC-A6AD-AA3BE3488D70}.Release|x64.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/README.md b/README.md index 42ef261..c94d015 100644 --- a/README.md +++ b/README.md @@ -72,6 +72,10 @@ Plays a sample Ogg Theora video file. Tests YUV textures and video rendering. Displays 2D slices of a 3D texture. Tests creating and drawing 3D textures. +**RenderTexture3D** + +Fades through 2D slices of a 3D render texture. Tests binding and sampling 3D render textures. + **VertexSampler** Displays a triangle whose colors are driven by sampling a texture in the vertex shader. diff --git a/RenderTexture3D/RenderTexture3D.csproj b/RenderTexture3D/RenderTexture3D.csproj new file mode 100644 index 0000000..2868e63 --- /dev/null +++ b/RenderTexture3D/RenderTexture3D.csproj @@ -0,0 +1,17 @@ + + + + + + + + + Exe + net7.0 + enable + x64 + + + + + diff --git a/RenderTexture3D/RenderTexture3DGame.cs b/RenderTexture3D/RenderTexture3DGame.cs new file mode 100644 index 0000000..238ab04 --- /dev/null +++ b/RenderTexture3D/RenderTexture3DGame.cs @@ -0,0 +1,137 @@ +using MoonWorks; +using MoonWorks.Graphics; +using MoonWorks.Math.Float; +using RefreshCS; + +namespace MoonWorks.Test +{ + class RenderTexture3DGame : Game + { + private GraphicsPipeline pipeline; + private Buffer vertexBuffer; + private Buffer indexBuffer; + private Texture rt; + private Sampler sampler; + + private float t; + private Color[] colors = new Color[] + { + Color.Red, + Color.Green, + Color.Blue, + }; + + struct FragUniform + { + public float Depth; + + public FragUniform(float depth) + { + Depth = depth; + } + } + + public RenderTexture3DGame() : base(TestUtils.GetStandardWindowCreateInfo(), TestUtils.GetStandardFrameLimiterSettings(), 60, true) + { + // Load the shaders + ShaderModule vertShaderModule = new ShaderModule(GraphicsDevice, TestUtils.GetShaderPath("TexturedQuadVert")); + ShaderModule fragShaderModule = new ShaderModule(GraphicsDevice, TestUtils.GetShaderPath("TexturedQuad3DFrag")); + + // Create the graphics pipeline + GraphicsPipelineCreateInfo pipelineCreateInfo = TestUtils.GetStandardGraphicsPipelineCreateInfo( + MainWindow.SwapchainFormat, + vertShaderModule, + fragShaderModule + ); + pipelineCreateInfo.VertexInputState = VertexInputState.CreateSingleBinding(); + pipelineCreateInfo.FragmentShaderInfo = GraphicsShaderInfo.Create(fragShaderModule, "main", 1); + pipeline = new GraphicsPipeline(GraphicsDevice, pipelineCreateInfo); + + // Create samplers + sampler = new Sampler(GraphicsDevice, SamplerCreateInfo.LinearWrap); + + // Create and populate the GPU resources + vertexBuffer = Buffer.Create(GraphicsDevice, BufferUsageFlags.Vertex, 4); + indexBuffer = Buffer.Create(GraphicsDevice, BufferUsageFlags.Index, 6); + rt = new Texture(GraphicsDevice, new TextureCreateInfo + { + Width = 16, + Height = 16, + Depth = (uint) colors.Length, + Format = TextureFormat.R8G8B8A8, + IsCube = false, + LevelCount = 1, + UsageFlags = TextureUsageFlags.ColorTarget | TextureUsageFlags.Sampler + }); + + 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, + } + ); + + // Clear each depth slice of the RT to a different color + for (uint i = 0; i < colors.Length; i += 1) + { + ColorAttachmentInfo attachmentInfo = new ColorAttachmentInfo + { + Texture = rt, + ClearColor = colors[i], + Depth = i, + Layer = 0, + Level = 0, + LoadOp = LoadOp.Clear, + StoreOp = StoreOp.Store, + SampleCount = SampleCount.One, + }; + cmdbuf.BeginRenderPass(attachmentInfo); + cmdbuf.EndRenderPass(); + } + + GraphicsDevice.Submit(cmdbuf); + } + + protected override void Update(System.TimeSpan delta) { } + + protected override void Draw(double alpha) + { + t += 0.01f; + FragUniform fragUniform = new FragUniform(t); + + 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(rt, sampler)); + uint fragParamOffset = cmdbuf.PushFragmentShaderUniforms(fragUniform); + cmdbuf.DrawIndexedPrimitives(0, 0, 2, 0, fragParamOffset); + cmdbuf.EndRenderPass(); + } + GraphicsDevice.Submit(cmdbuf); + } + + public static void Main(string[] args) + { + RenderTexture3DGame game = new RenderTexture3DGame(); + game.Run(); + } + } +}