using MoonWorks; using MoonWorks.Audio; using MoonWorks.Graphics; using MoonWorks.Input; using System.IO; using System.Threading.Tasks; namespace MoonWorksTest { public class TestGame : Game { ShaderModule passthroughVertexShaderModule; ShaderModule raymarchFragmentShaderModule; RaymarchUniforms raymarchUniforms; Texture woodTexture; Texture noiseTexture; Sampler sampler; Buffer vertexBuffer; Color clearColor; GraphicsPipeline mainGraphicsPipeline; byte[] screenshotPixels; Buffer screenshotBuffer; uint screenshotBufferSize; StaticSound music; StaticSoundInstance musicInstance; StreamingSoundOgg musicStream; bool screenshotInProgress = false; public TestGame(WindowCreateInfo windowCreateInfo, PresentMode presentMode, int targetTimestep = 60, bool debugMode = false) : base(windowCreateInfo, presentMode, targetTimestep, debugMode) { var windowWidth = windowCreateInfo.WindowWidth; var windowHeight = windowCreateInfo.WindowHeight; passthroughVertexShaderModule = new ShaderModule(GraphicsDevice, Path.Combine("Content", "passthrough_vert.spv")); raymarchFragmentShaderModule = new ShaderModule(GraphicsDevice, Path.Combine("Content", "hexagon_grid.spv")); raymarchUniforms.time = 0; raymarchUniforms.padding = 0; raymarchUniforms.resolutionX = windowWidth; raymarchUniforms.resolutionY = windowHeight; var uploadCommandBuffer = GraphicsDevice.AcquireCommandBuffer(); woodTexture = Texture.LoadPNG(GraphicsDevice, uploadCommandBuffer, "Content/woodgrain.png"); noiseTexture = Texture.LoadPNG(GraphicsDevice, uploadCommandBuffer, "Content/noise.png"); sampler = new Sampler(GraphicsDevice, SamplerCreateInfo.LinearWrap); /* Load Vertex Data */ var vertices = new PositionTexture[3]; vertices[0].Position.X = -1; vertices[0].Position.Y = -1; vertices[0].Position.Z = 0; vertices[0].Texture.X = 0; vertices[0].Texture.Y = 1; vertices[1].Position.X = 3; vertices[1].Position.Y = -1; vertices[1].Position.Z = 0; vertices[1].Texture.X = 1; vertices[1].Texture.Y = 1; vertices[2].Position.X = -1; vertices[2].Position.Y = 3; vertices[2].Position.Z = 0; vertices[2].Texture.X = 0; vertices[2].Texture.Y = 0; vertexBuffer = Buffer.Create(GraphicsDevice, BufferUsageFlags.Vertex, 3); uploadCommandBuffer.SetBufferData(vertexBuffer, vertices); GraphicsDevice.Submit(uploadCommandBuffer); /* Pipeline */ mainGraphicsPipeline = new GraphicsPipeline( GraphicsDevice, new GraphicsPipelineCreateInfo { AttachmentInfo = new GraphicsPipelineAttachmentInfo( new ColorAttachmentDescription( GraphicsDevice.GetSwapchainFormat(Window), ColorAttachmentBlendState.None ) ), DepthStencilState = DepthStencilState.Disable, VertexShaderInfo = GraphicsShaderInfo.Create(passthroughVertexShaderModule, "main", 0), VertexInputState = new VertexInputState( VertexBinding.Create(), VertexAttribute.Create("Position", 0), VertexAttribute.Create("Texture", 1) ), PrimitiveType = PrimitiveType.TriangleList, FragmentShaderInfo = GraphicsShaderInfo.Create(raymarchFragmentShaderModule, "main", 2), RasterizerState = RasterizerState.CW_CullBack, ViewportState = new ViewportState((int)Window.Width, (int)Window.Height), MultisampleState = MultisampleState.None } ); screenshotBufferSize = windowWidth * windowHeight * 4; screenshotPixels = new byte[screenshotBufferSize]; screenshotBuffer = new Buffer(GraphicsDevice, 0, screenshotBufferSize); music = StaticSound.LoadOgg(AudioDevice, Path.Combine("Content", "title_screen.ogg")); musicInstance = music.CreateInstance(); // musicInstance.Play(); musicStream = StreamingSoundOgg.Load(AudioDevice, Path.Combine("Content", "title_screen.ogg"), false, true); musicStream.Play(); } protected override void Update(System.TimeSpan dt) { raymarchUniforms.time += (float)dt.TotalSeconds; } protected override void Draw(System.TimeSpan dt, double alpha) { var commandBuffer = GraphicsDevice.AcquireCommandBuffer(); var swapchainTexture = commandBuffer.AcquireSwapchainTexture(Window); var takeScreenshot = Inputs.Keyboard.IsPressed(Keycode.S) && !screenshotInProgress && (swapchainTexture != null); if (swapchainTexture != null) { commandBuffer.BeginRenderPass( new ColorAttachmentInfo(swapchainTexture, clearColor) ); commandBuffer.BindGraphicsPipeline(mainGraphicsPipeline); commandBuffer.BindVertexBuffers(vertexBuffer); commandBuffer.BindFragmentSamplers( new TextureSamplerBinding(woodTexture, sampler), new TextureSamplerBinding(noiseTexture, sampler) ); var fragmentParamOffset = commandBuffer.PushFragmentShaderUniforms(raymarchUniforms); commandBuffer.DrawPrimitives(0, 1, 0, fragmentParamOffset); commandBuffer.EndRenderPass(); if (takeScreenshot) { commandBuffer.CopyTextureToBuffer(new TextureSlice(swapchainTexture), screenshotBuffer); } } GraphicsDevice.Submit(commandBuffer); if (takeScreenshot) { Task.Run(() => SaveScreenshot()); } } private void SaveScreenshot() { screenshotInProgress = true; var name = "MoonWorksTest-" + System.DateTime.Now.ToString("MM-dd-yyyy-hh-mm-ss") + ".png"; System.Console.WriteLine("Saving screenshot " + name + " ..."); GraphicsDevice.Wait(); screenshotBuffer.GetData(screenshotPixels, screenshotBufferSize); Texture.SavePNG( name, 1280, 720, GraphicsDevice.GetSwapchainFormat(Window), screenshotPixels ); System.Console.WriteLine("Screenshot saved!"); screenshotInProgress = false; } protected override void OnDestroy() { } } }