From a0705c50370a6509080bec2b736fb2833dfdb0c1 Mon Sep 17 00:00:00 2001 From: cosmonaut Date: Mon, 25 Jan 2021 14:59:27 -0800 Subject: [PATCH] starting graphics resources --- content/Graphics/GraphicsDevice.md | 1 + content/Graphics/Intro.md | 1 + content/Graphics/Resources/Buffer.md | 41 ++++++++++++++++++++++++++++ content/Graphics/Resources/_index.md | 25 +++++++++++++++++ content/Window/_index.md | 2 +- 5 files changed, 69 insertions(+), 1 deletion(-) create mode 100644 content/Graphics/Resources/Buffer.md create mode 100644 content/Graphics/Resources/_index.md diff --git a/content/Graphics/GraphicsDevice.md b/content/Graphics/GraphicsDevice.md index 192e0e6..0c8bc33 100644 --- a/content/Graphics/GraphicsDevice.md +++ b/content/Graphics/GraphicsDevice.md @@ -1,6 +1,7 @@ --- 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. diff --git a/content/Graphics/Intro.md b/content/Graphics/Intro.md index 774217c..ad0b35a 100644 --- a/content/Graphics/Intro.md +++ b/content/Graphics/Intro.md @@ -1,6 +1,7 @@ --- title: "Intro" date: 2021-01-24T20:54:00-08:00 +weight: 1 --- If the other MoonWorks tools have seemed simple so far, MoonWorks.Graphics may surprise you. Graphics is implemented using the [Refresh](https://gitea.moonside.games/MoonsideGames/Refresh) library. Refresh is based on Vulkan, an industry-standard cross-platform graphics API. It provides no "standard" rendering system that you can easily hook into, unlike what you may be used to with an engine like Unity. In order to render to the screen, you will need to set up, at the minimum, a Color Target, Framebuffer, a Render Pass, some Shader Modules, a Graphics Pipeline, and provide vertex data to be rendered through the pipeline. diff --git a/content/Graphics/Resources/Buffer.md b/content/Graphics/Resources/Buffer.md new file mode 100644 index 0000000..75a408e --- /dev/null +++ b/content/Graphics/Resources/Buffer.md @@ -0,0 +1,41 @@ +--- +title: "Buffer" +date: 2021-01-25T14:41:43-08:00 +--- + +Buffers are basically containers for data. They are the bread and butter of any renderer. + +3D models are represented as a series of vertices. Vertices always have a 3D position, but they can also contain additional information, such as normal vectors or texture coordinates. Buffers are how you let the renderer use this data. + +Buffers have a pre-defined length and cannot be resized. +You also need to tell MoonWorks.Graphics how you intend to use the buffer. + +To create a buffer, you do this: + +```cs + var myIndexBuffer = new Buffer(GraphicsDevice, BufferUsageFlags.Index, 64); +``` + +This creates a 64-byte buffer intended for use as an [index buffer](https://vulkan-tutorial.com/Vertex_buffers/Index_buffer). Index buffers allow the renderer to reuse vertices when drawing in 3D so you don't need to put a bunch of redundant data in your vertex buffer. Every 3D model format and exporter will give you index data along with vertex data. + +To upload data to a buffer, you use the `SetData` method. + +```cs +var myVertices = new VertexPositionNormalTexture[128]; +var vertexSizeInBytes = Marshal.SizeOf(); + +// set vertex data here + +var myVertexBuffer = new Buffer(GraphicsDevice, BufferUsageFlags.Vertex, 128 * vertexSizeInBytes); +myVertexBuffer.SetData(myVertices); +``` + +To get data from a buffer, you use the `GetData` method. + +```cs +var pixelSizeInBytes = Marshal.SizeOf(); +var myPixelData = new Color[width * height]; +myPixelBuffer.GetData(myPixelData, width * height * pixelSizeInBytes); +``` + +There are some important things to note here. The buffer is not guaranteed to actually contain your data until `Submit` is called. Transferring memory to and from the GPU is expensive, so MoonWorks batches these operations aggressively. It *is* safe to assume that any command buffer commands you use after calling `SetData` will have access to the data, but it is *not* safe to assume that the buffer will contain the data you expect right after calling `SetData`. You need to call `GraphicsDevice.Submit` and then `GraphicsDevice.Wait` before the data is guaranteed to exist in the buffer. You should have a *very* good reason for doing this - this kind of behavior is called a "synchronization point" and it is extremely detrimental to performance. diff --git a/content/Graphics/Resources/_index.md b/content/Graphics/Resources/_index.md new file mode 100644 index 0000000..3fa579f --- /dev/null +++ b/content/Graphics/Resources/_index.md @@ -0,0 +1,25 @@ +--- +title: "Resources" +date: 2021-01-25T14:31:59-08:00 +weight: 3 +--- + +MoonWorks provides nine different kinds of graphics resources that you use to construct your renderer. + +`Buffer` holds generic data, like vertex information for example. The way this data is interpreted is determined by the pipeline. + +`Texture` holds image data in a specified format. + +`Sampler` tells a shader how it should sample texture data. + +`ComputePipeline` sets up the graphics device to do computational work using [compute shaders](https://anteru.net/blog/2018/intro-to-compute-shaders/index.html). + +`GraphicsPipeline` sets up the graphics device to do rendering work. + +`RenderTarget` is a structure that can be rendered to. + +`Framebuffer` is essentially a collection of `RenderTarget`s. + +`RenderPass` is essentially a link that tells the `GraphicsPipeline` how it should use a `Framebuffer`. + +This is all pretty abstract. Let's get into some more detail. diff --git a/content/Window/_index.md b/content/Window/_index.md index beac05d..153a7a1 100644 --- a/content/Window/_index.md +++ b/content/Window/_index.md @@ -4,7 +4,7 @@ date: 2021-01-24T20:43:17-08:00 weight: 1 --- -Window management in MoonWorks is implemented using the [SDL2](https://www.libsdl.org) library. All window management is handled through the `Window` class. A reference to this class is automatically created and can be retrieved from your `Game` subclass. +Window management in MoonWorks is implemented using the [SDL2](https://www.libsdl.org) library. All window management is handled through the `OSWindow` class. A reference to this class named `Window` is automatically created and can be retrieved from your `Game` subclass. Your game is assumed to have a window and you must pass a `WindowCreateInfo` struct when creating your `Game`.