70 lines
2.7 KiB
Markdown
70 lines
2.7 KiB
Markdown
---
|
|
title: "Graphics Device"
|
|
date: 2021-01-24T20:52:59-08:00
|
|
weight: 2
|
|
---
|
|
|
|
`GraphicsDevice` is your main entry point for graphics-related behavior. You can obtain a reference to the current `GraphicsDevice` from your `Game` class.
|
|
|
|
Rendering in MoonWorks.Graphics is mostly handled through an abstraction known as the command buffer.
|
|
You will acquire a command buffer from the `GraphicsDevice`, tell it to do things, and then submit it to the GraphicsDevice for processing.
|
|
|
|
```cs
|
|
var commandBuffer = GraphicsDevice.AcquireCommandBuffer();
|
|
|
|
// do things with command buffer
|
|
|
|
GraphicsDevice.Submit(commandBuffer);
|
|
```
|
|
|
|
The GraphicsDevice can query the swapchain format for a window.
|
|
|
|
```cs
|
|
var swapchainFormat = GraphicsDevice.GetSwapchainFormat(Window);
|
|
```
|
|
|
|
There is one last thing that the GraphicsDevice can do, and that is `Wait`. To understand waiting, you need to understand a little bit about how MoonWorks.Graphics processes rendering.
|
|
|
|
Rendering is asynchronous. This means that when you submit a command buffer, the program doesn't actually wait for the GPU to finish working on whatever commands you submitted. It just tells the GPU what to do and then keeps going with your program. This is very good for performance because it means your CPU can get started working on the next frame before the current frame is even rendered.
|
|
|
|
Sometimes you actually do want to wait for the GPU to be done with the work you asked it to do, like if you are grabbing a screenshot for example. This is where `Wait` comes in.
|
|
|
|
```cs
|
|
// in initializer
|
|
screenshotThread = new Thread(new ThreadStart(SaveScreenshot));
|
|
|
|
...
|
|
|
|
protected void Draw(double dt, double alpha)
|
|
{
|
|
// do other rendering stuff
|
|
|
|
if (screenshotActivated)
|
|
{
|
|
commandBuffer.CopyTextureToBuffer(myTextureSlice, screenshotBuffer);
|
|
}
|
|
|
|
GraphicsDevice.Submit(commandBuffer);
|
|
|
|
if (screenshotActivated)
|
|
{
|
|
screenshotThread.Start();
|
|
}
|
|
}
|
|
|
|
...
|
|
|
|
private void SaveScreenshot()
|
|
{
|
|
GraphicsDevice.Wait();
|
|
screenshotBuffer.GetData(screenshotPixels, screenShotBufferSize);
|
|
Texture.SavePNG("screenshot.png", 1280, 720, screenshotPixels);
|
|
}
|
|
```
|
|
|
|
In this example, a separate CPU thread waits for the GPU to be done working. Then it saves some pixels that the GPU moved into a buffer to the disk as a PNG. Note that this means the game doesn't stutter at all while the disk is written to, because a separate thread from the main execution thread handles saving to disk.
|
|
|
|
If you need to squeeze some performance out of your game or avoid a lengthy stutter while the disk is accessed, threading can go a long way.
|
|
|
|
Before we talk too much more about command buffers and threading, let's explain the different kinds of graphics resources that you need for rendering.
|