CubeExample

refresh2
cosmonaut 2024-06-06 12:06:37 -07:00
parent 8258bb07a4
commit 877b533d7b
3 changed files with 254 additions and 159 deletions

View File

@ -1,58 +1,60 @@
using MoonWorks.Graphics; using MoonWorks;
using MoonWorks.Graphics;
using MoonWorks.Input;
using MoonWorks.Math; using MoonWorks.Math;
using MoonWorks.Math.Float; using MoonWorks.Math.Float;
using System; using System;
using System.IO; using System.IO;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace MoonWorks.Test namespace MoonWorksGraphicsTests
{ {
class CubeGame : Game struct DepthUniforms
{ {
private GraphicsPipeline cubePipeline; public float ZNear;
private GraphicsPipeline cubePipelineDepthOnly; public float ZFar;
private GraphicsPipeline skyboxPipeline;
private GraphicsPipeline skyboxPipelineDepthOnly;
private GraphicsPipeline blitPipeline;
private Texture depthTexture; public DepthUniforms(float zNear, float zFar)
private Sampler depthSampler; {
private DepthUniforms depthUniforms; ZNear = zNear;
ZFar = zFar;
}
}
private GpuBuffer cubeVertexBuffer; class CubeExample : Example
{
private GraphicsPipeline CubePipeline;
private GraphicsPipeline CubePipelineDepthOnly;
private GraphicsPipeline SkyboxPipeline;
private GraphicsPipeline SkyboxPipelineDepthOnly;
private GraphicsPipeline BlitPipeline;
private Texture DepthTexture;
private Sampler DepthSampler;
private DepthUniforms DepthUniforms;
private GpuBuffer CubeVertexBuffer;
private GpuBuffer skyboxVertexBuffer; private GpuBuffer skyboxVertexBuffer;
private GpuBuffer blitVertexBuffer; private GpuBuffer BlitVertexBuffer;
private GpuBuffer indexBuffer; private GpuBuffer IndexBuffer;
private TransferBuffer screenshotTransferBuffer; private TransferBuffer ScreenshotTransferBuffer;
private Texture screenshotTexture; private Texture ScreenshotTexture;
private Fence? screenshotFence; private Fence ScreenshotFence;
private Texture skyboxTexture; private Texture SkyboxTexture;
private Sampler skyboxSampler; private Sampler SkyboxSampler;
private bool finishedLoading = false;
private float cubeTimer = 0f;
private Quaternion cubeRotation = Quaternion.Identity;
private Quaternion previousCubeRotation = Quaternion.Identity;
private bool depthOnlyEnabled = false;
private Vector3 camPos = new Vector3(0, 1.5f, 4f);
private bool takeScreenshot; private bool takeScreenshot;
private bool screenshotInProgress; private bool screenshotInProgress;
private bool swapchainCopied; // don't want to take screenshot if the swapchain was invalid private bool swapchainDownloaded; // don't want to take screenshot if the swapchain was invalid
struct DepthUniforms private bool finishedLoading;
{ private float cubeTimer;
public float ZNear; private Quaternion cubeRotation;
public float ZFar; private Quaternion previousCubeRotation;
private bool depthOnlyEnabled;
public DepthUniforms(float zNear, float zFar) private Vector3 camPos;
{
ZNear = zNear;
ZFar = zFar;
}
}
// Upload cubemap layers one at a time to minimize transfer size // Upload cubemap layers one at a time to minimize transfer size
unsafe void LoadCubemap(string[] imagePaths) unsafe void LoadCubemap(string[] imagePaths)
@ -65,15 +67,15 @@ namespace MoonWorks.Test
{ {
TextureSlice = new TextureSlice TextureSlice = new TextureSlice
{ {
Texture = skyboxTexture, Texture = SkyboxTexture,
MipLevel = 0, MipLevel = 0,
Layer = i, Layer = i,
}, },
X = 0, X = 0,
Y = 0, Y = 0,
Z = 0, Z = 0,
Width = skyboxTexture.Width, Width = SkyboxTexture.Width,
Height = skyboxTexture.Height, Height = SkyboxTexture.Height,
Depth = 1 Depth = 1
}; };
@ -88,60 +90,105 @@ namespace MoonWorks.Test
cubemapUploader.Dispose(); cubemapUploader.Dispose();
} }
public CubeGame() : base(TestUtils.GetStandardWindowCreateInfo(), TestUtils.GetStandardFrameLimiterSettings(), TestUtils.PreferredBackends, 60, true) public override void Init(Window window, GraphicsDevice graphicsDevice, Inputs inputs)
{ {
ShaderModule cubeVertShaderModule = new ShaderModule( Window = window;
GraphicsDevice = graphicsDevice;
Inputs = inputs;
Window.SetTitle("Cube");
finishedLoading = false;
cubeTimer = 0;
cubeRotation = Quaternion.Identity;
previousCubeRotation = Quaternion.Identity;
depthOnlyEnabled = false;
camPos = new Vector3(0, 1.5f, 4);
Shader cubeVertShader = new Shader(
GraphicsDevice, GraphicsDevice,
TestUtils.GetShaderPath("PositionColorWithMatrix.vert") TestUtils.GetShaderPath("PositionColorWithMatrix.vert"),
); "main",
ShaderModule cubeFragShaderModule = new ShaderModule( ShaderStage.Vertex,
GraphicsDevice, ShaderFormat.SPIRV
TestUtils.GetShaderPath("SolidColor.frag")
); );
ShaderModule skyboxVertShaderModule = new ShaderModule( Shader cubeFragShader = new Shader(
GraphicsDevice, GraphicsDevice,
TestUtils.GetShaderPath("Skybox.vert") TestUtils.GetShaderPath("SolidColor.frag"),
); "main",
ShaderModule skyboxFragShaderModule = new ShaderModule( ShaderStage.Fragment,
GraphicsDevice, ShaderFormat.SPIRV
TestUtils.GetShaderPath("Skybox.frag")
); );
ShaderModule blitVertShaderModule = new ShaderModule( Shader skyboxVertShader = new Shader(
GraphicsDevice, GraphicsDevice,
TestUtils.GetShaderPath("TexturedQuad.vert") TestUtils.GetShaderPath("Skybox.vert"),
); "main",
ShaderModule blitFragShaderModule = new ShaderModule( ShaderStage.Vertex,
GraphicsDevice, ShaderFormat.SPIRV
TestUtils.GetShaderPath("TexturedDepthQuad.frag")
); );
depthTexture = Texture.CreateTexture2D( Shader skyboxFragShader = new Shader(
GraphicsDevice, GraphicsDevice,
MainWindow.Width, TestUtils.GetShaderPath("Skybox.frag"),
MainWindow.Height, "main",
TextureFormat.D16, ShaderStage.Fragment,
TextureUsageFlags.DepthStencilTarget | TextureUsageFlags.Sampler ShaderFormat.SPIRV
); );
depthTexture.Name = "Depth Texture";
depthSampler = new Sampler(GraphicsDevice, new SamplerCreateInfo()); Shader blitVertShader = new Shader(
depthUniforms = new DepthUniforms(0.01f, 100f); GraphicsDevice,
TestUtils.GetShaderPath("TexturedQuad.vert"),
"main",
ShaderStage.Vertex,
ShaderFormat.SPIRV
);
skyboxTexture = Texture.CreateTextureCube( Shader blitFragShader = new Shader(
GraphicsDevice,
TestUtils.GetShaderPath("TexturedDepthQuad.frag"),
"main",
ShaderStage.Fragment,
ShaderFormat.SPIRV
);
DepthTexture = Texture.CreateTexture2D(
GraphicsDevice,
Window.Width,
Window.Height,
TextureFormat.D16_UNORM,
TextureUsageFlags.DepthStencil | TextureUsageFlags.Sampler
);
DepthTexture.Name = "Depth Texture";
DepthSampler = new Sampler(GraphicsDevice, new SamplerCreateInfo());
DepthUniforms = new DepthUniforms(0.01f, 100f);
SkyboxTexture = Texture.CreateTextureCube(
GraphicsDevice, GraphicsDevice,
2048, 2048,
TextureFormat.R8G8B8A8, TextureFormat.R8G8B8A8,
TextureUsageFlags.Sampler TextureUsageFlags.Sampler
); );
skyboxTexture.Name = "Skybox"; SkyboxTexture.Name = "Skybox";
skyboxSampler = new Sampler(GraphicsDevice, new SamplerCreateInfo()); SkyboxSampler = new Sampler(GraphicsDevice, new SamplerCreateInfo());
screenshotTransferBuffer = new TransferBuffer(GraphicsDevice, TransferUsage.Texture, MainWindow.Width * MainWindow.Height * 4); ScreenshotTransferBuffer = new TransferBuffer(
screenshotTexture = Texture.CreateTexture2D(GraphicsDevice, MainWindow.Width, MainWindow.Height, MainWindow.SwapchainFormat, TextureUsageFlags.Sampler); GraphicsDevice,
screenshotTexture.Name = "Screenshot"; TransferUsage.Texture,
TransferBufferMapFlags.Read,
Window.Width * Window.Height * 4
);
ScreenshotTexture = Texture.CreateTexture2D(
GraphicsDevice,
Window.Width,
Window.Height,
Window.SwapchainFormat,
TextureUsageFlags.Sampler
);
ScreenshotTexture.Name = "Screenshot";
Task loadingTask = Task.Run(() => UploadGPUAssets()); Task loadingTask = Task.Run(() => UploadGPUAssets());
@ -150,59 +197,75 @@ namespace MoonWorks.Test
GraphicsPipelineCreateInfo cubePipelineCreateInfo = new GraphicsPipelineCreateInfo GraphicsPipelineCreateInfo cubePipelineCreateInfo = new GraphicsPipelineCreateInfo
{ {
AttachmentInfo = new GraphicsPipelineAttachmentInfo( AttachmentInfo = new GraphicsPipelineAttachmentInfo(
TextureFormat.D16, TextureFormat.D16_UNORM,
new ColorAttachmentDescription( new ColorAttachmentDescription(
MainWindow.SwapchainFormat, Window.SwapchainFormat,
ColorAttachmentBlendState.Opaque ColorAttachmentBlendState.Opaque
) )
), ),
DepthStencilState = DepthStencilState.DepthReadWrite, DepthStencilState = DepthStencilState.DepthReadWrite,
VertexShaderInfo = GraphicsShaderInfo.Create<TransformVertexUniform>(cubeVertShaderModule, "main", 0),
VertexInputState = VertexInputState.CreateSingleBinding<PositionColorVertex>(), VertexInputState = VertexInputState.CreateSingleBinding<PositionColorVertex>(),
PrimitiveType = PrimitiveType.TriangleList, PrimitiveType = PrimitiveType.TriangleList,
FragmentShaderInfo = GraphicsShaderInfo.Create(cubeFragShaderModule, "main", 0),
RasterizerState = RasterizerState.CW_CullBack, RasterizerState = RasterizerState.CW_CullBack,
MultisampleState = MultisampleState.None MultisampleState = MultisampleState.None,
VertexShader = cubeVertShader,
VertexShaderResourceInfo = new GraphicsPipelineResourceInfo
{
UniformBufferCount = 1
},
FragmentShader = cubeFragShader
}; };
cubePipeline = new GraphicsPipeline(GraphicsDevice, cubePipelineCreateInfo); CubePipeline = new GraphicsPipeline(GraphicsDevice, cubePipelineCreateInfo);
cubePipelineCreateInfo.AttachmentInfo = new GraphicsPipelineAttachmentInfo(TextureFormat.D16); cubePipelineCreateInfo.AttachmentInfo = new GraphicsPipelineAttachmentInfo(TextureFormat.D16_UNORM);
cubePipelineDepthOnly = new GraphicsPipeline(GraphicsDevice, cubePipelineCreateInfo); CubePipelineDepthOnly = new GraphicsPipeline(GraphicsDevice, cubePipelineCreateInfo);
// Create the skybox pipelines // Create the skybox pipelines
GraphicsPipelineCreateInfo skyboxPipelineCreateInfo = new GraphicsPipelineCreateInfo GraphicsPipelineCreateInfo skyboxPipelineCreateInfo = new GraphicsPipelineCreateInfo
{ {
AttachmentInfo = new GraphicsPipelineAttachmentInfo( AttachmentInfo = new GraphicsPipelineAttachmentInfo(
TextureFormat.D16, TextureFormat.D16_UNORM,
new ColorAttachmentDescription( new ColorAttachmentDescription(
MainWindow.SwapchainFormat, Window.SwapchainFormat,
ColorAttachmentBlendState.Opaque ColorAttachmentBlendState.Opaque
) )
), ),
DepthStencilState = DepthStencilState.DepthReadWrite, DepthStencilState = DepthStencilState.DepthReadWrite,
VertexShaderInfo = GraphicsShaderInfo.Create<TransformVertexUniform>(skyboxVertShaderModule, "main", 0),
VertexInputState = VertexInputState.CreateSingleBinding<PositionVertex>(), VertexInputState = VertexInputState.CreateSingleBinding<PositionVertex>(),
PrimitiveType = PrimitiveType.TriangleList, PrimitiveType = PrimitiveType.TriangleList,
FragmentShaderInfo = GraphicsShaderInfo.Create(skyboxFragShaderModule, "main", 1),
RasterizerState = RasterizerState.CW_CullNone, RasterizerState = RasterizerState.CW_CullNone,
MultisampleState = MultisampleState.None, MultisampleState = MultisampleState.None,
VertexShader = skyboxVertShader,
VertexShaderResourceInfo = new GraphicsPipelineResourceInfo
{
UniformBufferCount = 1
},
FragmentShader = skyboxFragShader,
FragmentShaderResourceInfo = new GraphicsPipelineResourceInfo
{
SamplerCount = 1
}
}; };
skyboxPipeline = new GraphicsPipeline(GraphicsDevice, skyboxPipelineCreateInfo); SkyboxPipeline = new GraphicsPipeline(GraphicsDevice, skyboxPipelineCreateInfo);
skyboxPipelineCreateInfo.AttachmentInfo = new GraphicsPipelineAttachmentInfo(TextureFormat.D16); skyboxPipelineCreateInfo.AttachmentInfo = new GraphicsPipelineAttachmentInfo(TextureFormat.D16_UNORM);
skyboxPipelineDepthOnly = new GraphicsPipeline(GraphicsDevice, skyboxPipelineCreateInfo); SkyboxPipelineDepthOnly = new GraphicsPipeline(GraphicsDevice, skyboxPipelineCreateInfo);
// Create the blit pipeline // Create the blit pipeline
GraphicsPipelineCreateInfo blitPipelineCreateInfo = TestUtils.GetStandardGraphicsPipelineCreateInfo( GraphicsPipelineCreateInfo blitPipelineCreateInfo = TestUtils.GetStandardGraphicsPipelineCreateInfo(
MainWindow.SwapchainFormat, Window.SwapchainFormat,
blitVertShaderModule, blitVertShader,
blitFragShaderModule blitFragShader
); );
blitPipelineCreateInfo.VertexInputState = VertexInputState.CreateSingleBinding<PositionTextureVertex>(); blitPipelineCreateInfo.VertexInputState = VertexInputState.CreateSingleBinding<PositionTextureVertex>();
blitPipelineCreateInfo.FragmentShaderInfo = GraphicsShaderInfo.Create<DepthUniforms>(blitFragShaderModule, "main", 1); blitPipelineCreateInfo.FragmentShaderResourceInfo = new GraphicsPipelineResourceInfo
blitPipeline = new GraphicsPipeline(GraphicsDevice, blitPipelineCreateInfo); {
SamplerCount = 1,
UniformBufferCount = 1
};
BlitPipeline = new GraphicsPipeline(GraphicsDevice, blitPipelineCreateInfo);
} }
private void UploadGPUAssets() private void UploadGPUAssets()
@ -293,15 +356,15 @@ namespace MoonWorks.Test
var resourceUploader = new ResourceUploader(GraphicsDevice); var resourceUploader = new ResourceUploader(GraphicsDevice);
cubeVertexBuffer = resourceUploader.CreateBuffer(cubeVertexData, BufferUsageFlags.Vertex); CubeVertexBuffer = resourceUploader.CreateBuffer(cubeVertexData, BufferUsageFlags.Vertex);
skyboxVertexBuffer = resourceUploader.CreateBuffer(skyboxVertexData, BufferUsageFlags.Vertex); skyboxVertexBuffer = resourceUploader.CreateBuffer(skyboxVertexData, BufferUsageFlags.Vertex);
indexBuffer = resourceUploader.CreateBuffer(indexData, BufferUsageFlags.Index); IndexBuffer = resourceUploader.CreateBuffer(indexData, BufferUsageFlags.Index);
blitVertexBuffer = resourceUploader.CreateBuffer(blitVertexData, BufferUsageFlags.Vertex); BlitVertexBuffer = resourceUploader.CreateBuffer(blitVertexData, BufferUsageFlags.Vertex);
cubeVertexBuffer.Name = "Cube Vertices"; CubeVertexBuffer.Name = "Cube Vertices";
skyboxVertexBuffer.Name = "Skybox Vertices"; skyboxVertexBuffer.Name = "Skybox Vertices";
indexBuffer.Name = "Cube Indices"; IndexBuffer.Name = "Cube Indices";
blitVertexBuffer.Name = "Blit Vertices"; BlitVertexBuffer.Name = "Blit Vertices";
resourceUploader.Upload(); resourceUploader.Upload();
resourceUploader.Dispose(); resourceUploader.Dispose();
@ -323,7 +386,7 @@ namespace MoonWorks.Test
Logger.LogInfo("Press Right to save a screenshot"); Logger.LogInfo("Press Right to save a screenshot");
} }
protected override void Update(System.TimeSpan delta) public override void Update(System.TimeSpan delta)
{ {
cubeTimer += (float) delta.TotalSeconds; cubeTimer += (float) delta.TotalSeconds;
@ -356,13 +419,13 @@ namespace MoonWorks.Test
} }
} }
protected override void Draw(double alpha) public override void Draw(double alpha)
{ {
Matrix4x4 proj = Matrix4x4.CreatePerspectiveFieldOfView( Matrix4x4 proj = Matrix4x4.CreatePerspectiveFieldOfView(
MathHelper.ToRadians(75f), MathHelper.ToRadians(75f),
(float) MainWindow.Width / MainWindow.Height, (float) Window.Width / Window.Height,
depthUniforms.ZNear, DepthUniforms.ZNear,
depthUniforms.ZFar DepthUniforms.ZFar
); );
Matrix4x4 view = Matrix4x4.CreateLookAt( Matrix4x4 view = Matrix4x4.CreateLookAt(
camPos, camPos,
@ -381,7 +444,7 @@ namespace MoonWorks.Test
TransformVertexUniform cubeUniforms = new TransformVertexUniform(model * view * proj); TransformVertexUniform cubeUniforms = new TransformVertexUniform(model * view * proj);
CommandBuffer cmdbuf = GraphicsDevice.AcquireCommandBuffer(); CommandBuffer cmdbuf = GraphicsDevice.AcquireCommandBuffer();
Texture swapchainTexture = cmdbuf.AcquireSwapchainTexture(MainWindow); Texture swapchainTexture = cmdbuf.AcquireSwapchainTexture(Window);
if (swapchainTexture != null) if (swapchainTexture != null)
{ {
if (!finishedLoading) if (!finishedLoading)
@ -390,74 +453,88 @@ namespace MoonWorks.Test
Color clearColor = new Color(sine, sine, sine); Color clearColor = new Color(sine, sine, sine);
// Just show a clear screen. // Just show a clear screen.
cmdbuf.BeginRenderPass(new ColorAttachmentInfo(swapchainTexture, WriteOptions.Cycle, clearColor)); var renderPass = cmdbuf.BeginRenderPass(
cmdbuf.EndRenderPass(); new ColorAttachmentInfo(
swapchainTexture,
false,
clearColor
)
);
cmdbuf.EndRenderPass(renderPass);
} }
else else
{ {
RenderPass renderPass;
if (!depthOnlyEnabled) if (!depthOnlyEnabled)
{ {
cmdbuf.BeginRenderPass( renderPass = cmdbuf.BeginRenderPass(
new DepthStencilAttachmentInfo(depthTexture, WriteOptions.Cycle, new DepthStencilValue(1f, 0)), new DepthStencilAttachmentInfo(DepthTexture, true, new DepthStencilValue(1f, 0)),
new ColorAttachmentInfo(swapchainTexture, WriteOptions.Cycle, LoadOp.DontCare) new ColorAttachmentInfo(swapchainTexture, false, LoadOp.DontCare)
); );
} }
else else
{ {
cmdbuf.BeginRenderPass( renderPass = cmdbuf.BeginRenderPass(
new DepthStencilAttachmentInfo(depthTexture, WriteOptions.Cycle, new DepthStencilValue(1f, 0), StoreOp.Store) new DepthStencilAttachmentInfo(DepthTexture, true, new DepthStencilValue(1f, 0), StoreOp.Store)
); );
} }
// Draw cube // Draw cube
cmdbuf.BindGraphicsPipeline(depthOnlyEnabled ? cubePipelineDepthOnly : cubePipeline); renderPass.BindGraphicsPipeline(depthOnlyEnabled ? CubePipelineDepthOnly : CubePipeline);
cmdbuf.BindVertexBuffers(cubeVertexBuffer); renderPass.BindVertexBuffer(CubeVertexBuffer);
cmdbuf.BindIndexBuffer(indexBuffer, IndexElementSize.ThirtyTwo); renderPass.BindIndexBuffer(IndexBuffer, IndexElementSize.ThirtyTwo);
cmdbuf.PushVertexShaderUniforms(cubeUniforms); renderPass.PushVertexUniformData(cubeUniforms);
cmdbuf.DrawIndexedPrimitives(0, 0, 12); renderPass.DrawIndexedPrimitives(0, 0, 12);
// Draw skybox // Draw skybox
cmdbuf.BindGraphicsPipeline(depthOnlyEnabled ? skyboxPipelineDepthOnly : skyboxPipeline); renderPass.BindGraphicsPipeline(depthOnlyEnabled ? SkyboxPipelineDepthOnly : SkyboxPipeline);
cmdbuf.BindVertexBuffers(skyboxVertexBuffer); renderPass.BindVertexBuffer(skyboxVertexBuffer);
cmdbuf.BindIndexBuffer(indexBuffer, IndexElementSize.ThirtyTwo); renderPass.BindIndexBuffer(IndexBuffer, IndexElementSize.ThirtyTwo);
cmdbuf.BindFragmentSamplers(new TextureSamplerBinding(skyboxTexture, skyboxSampler)); renderPass.BindFragmentSampler(new TextureSamplerBinding(SkyboxTexture, SkyboxSampler));
cmdbuf.PushVertexShaderUniforms(skyboxUniforms); renderPass.PushVertexUniformData(skyboxUniforms);
cmdbuf.DrawIndexedPrimitives(0, 0, 12); renderPass.DrawIndexedPrimitives(0, 0, 12);
cmdbuf.EndRenderPass(); cmdbuf.EndRenderPass(renderPass);
if (depthOnlyEnabled) if (depthOnlyEnabled)
{ {
// Draw the depth buffer as a grayscale image // Draw the depth buffer as a grayscale image
cmdbuf.BeginRenderPass(new ColorAttachmentInfo(swapchainTexture, WriteOptions.Safe, LoadOp.Load)); renderPass = cmdbuf.BeginRenderPass(
new ColorAttachmentInfo(
swapchainTexture,
false,
LoadOp.Load
)
);
cmdbuf.BindGraphicsPipeline(blitPipeline); renderPass.BindGraphicsPipeline(BlitPipeline);
cmdbuf.BindFragmentSamplers(new TextureSamplerBinding(depthTexture, depthSampler)); renderPass.BindFragmentSampler(new TextureSamplerBinding(DepthTexture, DepthSampler));
cmdbuf.BindVertexBuffers(blitVertexBuffer); renderPass.BindVertexBuffer(BlitVertexBuffer);
cmdbuf.PushFragmentShaderUniforms(depthUniforms); renderPass.PushFragmentUniformData(DepthUniforms);
cmdbuf.DrawPrimitives(0, 2); renderPass.DrawPrimitives(0, 2);
cmdbuf.EndRenderPass(); cmdbuf.EndRenderPass(renderPass);
} }
if (takeScreenshot) if (takeScreenshot)
{ {
cmdbuf.BeginCopyPass(); var copyPass = cmdbuf.BeginCopyPass();
cmdbuf.CopyTextureToTexture(swapchainTexture, screenshotTexture, WriteOptions.Unsafe); copyPass.DownloadFromTexture(swapchainTexture, ScreenshotTransferBuffer, new BufferImageCopy(0, 0, 0));
cmdbuf.EndCopyPass(); cmdbuf.EndCopyPass(copyPass);
swapchainCopied = true; swapchainDownloaded = true;
} }
} }
} }
if (takeScreenshot && swapchainCopied) if (takeScreenshot && swapchainDownloaded)
{ {
screenshotFence = GraphicsDevice.SubmitAndAcquireFence(cmdbuf); ScreenshotFence = GraphicsDevice.SubmitAndAcquireFence(cmdbuf);
Task.Run(TakeScreenshot); Task.Run(TakeScreenshot);
takeScreenshot = false; takeScreenshot = false;
swapchainCopied = false; swapchainDownloaded = false;
} }
else else
{ {
@ -469,33 +546,44 @@ namespace MoonWorks.Test
{ {
screenshotInProgress = true; screenshotInProgress = true;
GraphicsDevice.WaitForFences(screenshotFence); GraphicsDevice.WaitForFence(ScreenshotFence);
GraphicsDevice.DownloadFromTexture(
screenshotTexture,
screenshotTransferBuffer,
TransferOptions.Unsafe
);
ImageUtils.SavePNG( ImageUtils.SavePNG(
Path.Combine(System.AppContext.BaseDirectory, "screenshot.png"), Path.Combine(System.AppContext.BaseDirectory, "screenshot.png"),
screenshotTransferBuffer, ScreenshotTransferBuffer,
0, 0,
(int) screenshotTexture.Width, (int) ScreenshotTexture.Width,
(int) screenshotTexture.Height, (int) ScreenshotTexture.Height,
screenshotTexture.Format == TextureFormat.B8G8R8A8 ScreenshotTexture.Format == TextureFormat.B8G8R8A8
); );
GraphicsDevice.ReleaseFence(screenshotFence); GraphicsDevice.ReleaseFence(ScreenshotFence);
screenshotFence = null; ScreenshotFence = null;
screenshotInProgress = false; screenshotInProgress = false;
} }
public static void Main(string[] args) public override void Destroy()
{ {
CubeGame game = new CubeGame(); CubePipeline.Dispose();
game.Run(); CubePipelineDepthOnly.Dispose();
} SkyboxPipeline.Dispose();
SkyboxPipelineDepthOnly.Dispose();
BlitPipeline.Dispose();
DepthTexture.Dispose();
DepthSampler.Dispose();
CubeVertexBuffer.Dispose();
skyboxVertexBuffer.Dispose();
BlitVertexBuffer.Dispose();
IndexBuffer.Dispose();
ScreenshotTransferBuffer.Dispose();
ScreenshotTexture.Dispose();
SkyboxTexture.Dispose();
SkyboxSampler.Dispose();
}
} }
} }

View File

@ -32,6 +32,7 @@
<Compile Include="Examples\CompressedTexturesExample.cs" /> <Compile Include="Examples\CompressedTexturesExample.cs" />
<Compile Include="Examples\ComputeUniformsExample.cs" /> <Compile Include="Examples\ComputeUniformsExample.cs" />
<Compile Include="Examples\CopyTextureExample.cs" /> <Compile Include="Examples\CopyTextureExample.cs" />
<Compile Include="Examples\CubeExample.cs" />
</ItemGroup> </ItemGroup>
<Import Project=".\CopyMoonlibs.targets" /> <Import Project=".\CopyMoonlibs.targets" />

View File

@ -15,7 +15,8 @@ class Program : Game
new CompressedTexturesExample(), new CompressedTexturesExample(),
new BasicComputeExample(), new BasicComputeExample(),
new ComputeUniformsExample(), new ComputeUniformsExample(),
new CopyTextureExample() new CopyTextureExample(),
new CubeExample()
]; ];
int ExampleIndex = 0; int ExampleIndex = 0;
@ -64,6 +65,11 @@ class Program : Game
Examples[ExampleIndex].Draw(alpha); Examples[ExampleIndex].Draw(alpha);
} }
protected override void Destroy()
{
Examples[ExampleIndex].Destroy();
}
static void Main(string[] args) static void Main(string[] args)
{ {
var debugMode = false; var debugMode = false;