diff --git a/docs/1-introduction/1-1-getting-started/1-1-0-overview.md b/docs/1-introduction/1-1-getting-started/1-1-0-overview.md index 9278f55..60b66d5 100644 --- a/docs/1-introduction/1-1-getting-started/1-1-0-overview.md +++ b/docs/1-introduction/1-1-getting-started/1-1-0-overview.md @@ -1,23 +1,32 @@ # Overview -As many may know or not know, there's a few choices in terms of what to use for graphics, such as OpenGL, Vulkan, Metal and what is commonly known as "DirectX". -However in word of mouth DirectX usually refers to Direct3D, which is one of the many API's that DirectX has, as it is less known that DirectX is more than just graphics, it is: +As you may or may not know, there's a few choices in terms of what you can use for rendering, such +as OpenGL, Vulkan, Metal, and what is commonly known as "DirectX". However, in word of mouth +DirectX usually refers to Direct3D, which is one of the many API's that DirectX has. In fact +DirectX provides tooling and libraries for more aspects of game development, including: - **Audio** - - **Fonts** - - **Input** - - **Graphics** -And _other things_ more or less targeted at stuff one needs for game development. +The goal of LearnD3D11 is, as one might guess, the targeted explanation and showcase of Direct3D11 +within C++, or as one generally refers to it: "DirectX 11". This guide does _NOT_ cover DirectX 12, +the newer version of the API, as it is very low level and will usually require a good understanding +of the GPU and how it works. We will cover concepts and some techniques used in graphics programming, +and we do not expect you to have any prerequisites in this field. It is, however, not a guide +covering C++ or programming in general; we expect at least the ability and understanding to write +object-oriented programs in C++. -The goal of LearnD3D11 is as one might guess is the targeted explanation and showcase of Direct3D11 or as one generally refers to it: "DirectX 11". +During each step we'll provide a project for you to follow along as we explain everything for you +to start rendering geometry using your GPU. -During each step we'll provide a project for you to follow along as we explain each individual thing needed to get some graphics on your own screen. +Also note that DirectX is made by Microsoft and is generally only available on Windows. However, +`DXVK` was developed to run D3D9 through D3D11 on Linux or Wine on top of Vulkan and would be the +only way of developing and using D3D11 on those platforms. -This initial section will cover creating the actual window, initializing Direct3D11 and getting our very first visuals (which is commonly known as the Hello Triangle) +This initial section will cover creating the actual window, initializing Direct3D11 and getting our +very first visuals (which is commonly known as the Hello Triangle) ## Project structure @@ -45,5 +54,3 @@ x-x-x-project.vcxproj - `obj/` contains all intermediate junk the compiler produced, to keep the folder structure clean - `bin/` will contain the compiled program of the chapter along with all necessary `Assets` - `Assets/` will contain all the used assets, such as models, shaders and textures and other things. It will be empty for the first few chapters, and we will copy it and its contents to the bin/Debug or bin/Release directory, depending on which configuration you chose - -[Next chapter](../1-1-1-hello-window/) diff --git a/docs/1-introduction/1-1-getting-started/1-1-1-hello-window.md b/docs/1-introduction/1-1-getting-started/1-1-1-hello-window.md index e978f7b..9fd4418 100644 --- a/docs/1-introduction/1-1-getting-started/1-1-1-hello-window.md +++ b/docs/1-introduction/1-1-getting-started/1-1-1-hello-window.md @@ -98,9 +98,9 @@ resolution you use. Size-wise it will cover 90% of your main monitor. glfwWindowHint(GLFW_SCALE_TO_MONITOR, GLFW_FALSE); ``` -This will tell `GLFW` to not scale the window in any way, should you have setup a specific scaling -other than 100% on your desktop. That will keep the windowsize at what we set it, without thinking -about odd fractionals to manually scale the windowsize for any arbitrary scaling on your OS. +This will tell `GLFW` to not scale the window in any way, should you have set up a specific scaling +other than 100% on your desktop. That will keep the window size at what we set it, and lets us +forget about fractional window and pixel scaling. ```cpp glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API); @@ -108,8 +108,8 @@ glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API); `GLFW` was initially meant to support development of OpenGL based applications, hence the gl in its name, but over the years it also started to support other APIs and not just OpenGL. Now since `GLFW` -automatically creates a context for OpenGL and we want to use DirectX, we will have to tell it to not -to do so via [glfwWindowHint](https://www.glfw.org/docs/3.3/group__window.html#ga7d9c8c62384b1e2821c4dc48952d2033). +by default creates a context for OpenGL, and as we want to use DirectX we need to tell `GLFW` +to not do so via [glfwWindowHint](https://www.glfw.org/docs/3.3/group__window.html#ga7d9c8c62384b1e2821c4dc48952d2033). There are many other options one can define through glfwWindowHint which can be found [here](https://www.glfw.org/docs/3.3/group__window.html). Many of these options might be useful in your application, depending on what you want and how you @@ -156,7 +156,7 @@ That is more or less the heart of your application, the mainloop. You could also call it game loop, since in here everything happens. From reading keyboard and mouse input, reacting to it, to telling the graphics card to put a frog on the screen. It will keep doing it, until it gets signaled -to not to do that anymore because you closed the window for example +to not do that anymore because you closed the window for example ([glfwWindowShouldClose](https://www.glfw.org/docs/3.3/group__window.html#ga24e02fbfefbb81fc45320989f8140ab5)), or hit Escape and mapped Escape to close the window. [glfwPollEvents](https://www.glfw.org/docs/3.3/group__window.html#ga37bd57223967b4211d60ca1a0bf3c832) will make sure that `GLFW` knows about all required events coming from the operating system. @@ -200,7 +200,7 @@ The further we go into this tutorial series the more stuff we will add to the pr But we don't want to cram everything into `Main.cpp`, your main entry point of the program. A good practise is to split up things into smaller units, to not lose overview. -Right now we dont have much to show for, just a window, made by a few lines of code, +Right now we don't have much to show for, just a window, made by a few lines of code, but we are going to abstract that code into a new class called `Application` which will also be our main container so to speak, in which all the magic will happen. @@ -363,9 +363,9 @@ int main(int argc, char* argv[]) } ``` -Let's start with `Main.cpp`. That's all its doing, creating the hellowindow application and running it. +Let's start with `Main.cpp`. That's all its doing, creating the "hellowindow" application and running it. In the future this can be accompanied by loading a configuration, initializing a logger, -initiating a connection to a possible server server, or other stuff. +initiating a connection to a possible server, or other stuff. ```cpp public: @@ -377,7 +377,7 @@ public: This is a section of the `Application` class, showing only its publicly available methods. `Run` being the most important one to the outside world, like `Main`, it's the entry point into this Application. -We still dont want to cram everything into one main or one method, therefore `Run` is split up +We still don't want to cram everything into one main or one method, therefore `Run` is split up again into the following blocks. ```cpp @@ -402,22 +402,22 @@ void Application::Run() } ``` -You can clearly see what it is doing. `Initialize`, as the name suggests, will initialize everything -which is required for the app to run, which currently is the window in our case. In future chapters it -will also including initializing `D3D11` and its resources or imgui for some UI. +This function is pretty simple. `Initialize`, as the name suggests, will initialize everything +which is required for the app to run, which currently is the window in our case. In future +chapters it will also include initializing `D3D11`, its resources, and ImGUI for the UI. -`Load`s purpose is to load all the assets required to run the application, in further chapters it will +`Load`'s purpose is to load all the assets required to run the application, in further chapters it will encompass textures, shaders, models and other things. -The next block is the aforementioned mainloop or gameloop, which still does what it was doing before, -checking with the OS if events need to be processed and now we also call a `Update` and `Render` method. +The next block is the aforementioned mainloop or game loop, which still does what it was doing before, +checking with the OS if events need to be processed, and now we also call a `Update` and `Render` method. `Update` may contain queries about pressed key or mouse buttons, updating variables or other things which are - for instance - reflected on display inside the `Render` method. You probably have noticed that all the protected method in `Application` are virtual, that's because we are deriving from `Application` in form of `HelloWindowApplication` and only focus on those four -methods if required. We now dont have to deal with the mainloop anymore for the time being. +methods if required. We now don't have to deal with the mainloop anymore for the time being. ```cpp virtual void Cleanup(); @@ -438,5 +438,3 @@ and more. [Raw Winapi Hello Window Project on GitHub](https://github.com/GraphicsProgramming/learnd3d11/tree/main/src/Cpp/1-getting-started/1-1-1-HelloWin32Window) [Project on GitHub](https://github.com/GraphicsProgramming/learnd3d11/tree/main/src/Cpp/1-getting-started/1-1-1-HelloWindow) - -[Next chapter](../1-1-2-hello-d3d11/) diff --git a/docs/1-introduction/1-1-getting-started/1-1-2-hello-d3d11.md b/docs/1-introduction/1-1-getting-started/1-1-2-hello-d3d11.md index 9d60e27..6ded3b9 100644 --- a/docs/1-introduction/1-1-getting-started/1-1-2-hello-d3d11.md +++ b/docs/1-introduction/1-1-getting-started/1-1-2-hello-d3d11.md @@ -1,16 +1,16 @@ # Hello D3D11 In this chapter, we'll introduce you to the basics of using D3D11; how to create a ID3D11Device and -how to use it to show something in our window. In the last chapter we setup a basic implementation +how to use it to show something in our window. In the last chapter we set up a basic implementation for an application with a window through GLFW. The implementation for `Main.cpp` and `Application.cpp` won't be shown here anymore. -If you are looking at the source code for this chapter, you will also notice that -`Application.cpp` and `Application.hpp` do not exist anymore, as we have moved both of these -files into a separate `Framework` project to ease development between chapters. This `Framework` -project will include code that is shared between all chapters, so it might include a lot of other -files which are not used or are not relevant within some chapters. Please note that the code for -already existing files is also subject to change to accomodate newer chapters and their needs. +If you are looking at the source code for this chapter, you will also notice that `Application.cpp` +and `Application.hpp` do not exist anymore, as we have moved both of these files into a separate +`Framework` project to ease development between chapters. This `Framework` project will include +code that is shared between all chapters, so it might include a lot of other files which are not +used or are not relevant within some chapters. Please note that the code for already existing files +is also subject to change to accommodate newer chapters and their needs. However, let's start by breaking down the relevant bits and pieces by showing you how the new class, which derives from `Application` will look like. @@ -173,7 +173,7 @@ You might have noticed that we are not using raw pointers for those pieces, but `DXGI` stands for DirectX Graphics Infrastructure, in case you are wondering. -Lets go in to `Initialize` +Let's go in to `Initialize` ```cpp if (!Application::Initialize()) @@ -192,7 +192,7 @@ if (FAILED(CreateDXGIFactory2( The first part calls the parent class, where `GLFW` is initialized and setup. -`IID_PPV_ARGS(ppType)` Is a compile time macro that is defined as +`IID_PPV_ARGS(ppType)` Is a compile-time macro that is defined as ```cpp #define IID_PPV_ARGS(ppType) __uuidof(**(ppType)), IID_PPV_ARGS_Helper(ppType) ``` @@ -211,7 +211,7 @@ HRESULT CreateDXGIFactory2( What the parts of the `IID_PPV_ARGS(ppType)` macro are: [the `ppType` in `IID_PPV_ARGS(ppType)`] -- a pointer to a pointer of a object. +- a pointer to a pointer of an object. [the `__uuidof(**(ppType))` part of `IID_PPV_ARGS(ppType)`] - at compile time retrieves a `UUID` from `ppType` type which represents a `GUID`, which is returned as a `REFIID` — which means that the type returned is a reference to an identifier to a specific type of COM object. @@ -245,7 +245,7 @@ if (FAILED(D3D11CreateDevice( } ``` -This block is the the entry point into D3D11, where we ask for a device and its device context to be created. The input parameters are: +This block is the entry point into D3D11, where we ask for a device and its device context to be created. The input parameters are: We want a LEVEL_11_0, hardware accelerated device, which has support for a specific color format. Feature levels are a concept that has been introduced with D3D11, it is a way to specify which set of features we would like to use. Each GPU may support different feature levels (for example a very old GPU might only support LEVEL_9_1, while a more modern one may support every feature level up to, and including LEVEL_11_0), this is a way to avoid rewriting our application in D3D9 just because our GPU doesn't support D3D11. @@ -290,7 +290,7 @@ The majority of values should make some sense without explanation, like width an `BufferCount` is 2, because we want double buffering. Double buffering is an age-old technique to avoid presenting an image that is being used by the GPU, instead we work on the "back buffer", while the GPU is happy presenting the "front buffer", then, as soon as we are done with the back buffer, we swap front and back, and begin working on the former front buffer present that one and render to the other one again in the meantime. That process is supposed to reduce flicker or tearing. -`SwapEffect` specifies if the contents of the back buffer should be preserved or discarded after a swap, here we don't care about preserving the back buffer so we just discard everything. +`SwapEffect` specifies if the contents of the back buffer should be preserved or discarded after a swap, here we don't care about preserving the back buffer, so we just discard everything. `AlphaMode` specifies how DXGI should handle transparency, we don't care about that (yet), so we'll just say it's unspecified and rely on default behaviour @@ -332,7 +332,7 @@ bool HelloD3D11Application::CreateSwapchainResources() } ``` -When we render things, the GPU simply writes color values to a texture, which you can picture as a buffer which holds color information Swapchain is a container to manage those buffers we want to present on screen. To do that we have to create a special kind of texture called a "Render Target View" or an RTV. First off we have to grab a texture from the swapchain's main buffer (index 0), from that texture, we now have create an RTV from that, which specifies the subresource of the texture that we will be drawing to. We wont keep the actual texture around, we just need the render target view, which we will refer to as render target. +When we render things, the GPU simply writes color values to a texture, which you can picture as a buffer which holds color information Swapchain is a container to manage those buffers we want to present on screen. To do that we have to create a special kind of texture called a "Render Target View" or an RTV. First off we have to grab a texture from the swapchain's main buffer (index 0), from that texture, we now have to create an RTV from that, which specifies the subresource of the texture that we will be drawing to. We won't keep the actual texture around, we just need the render target view, which we will refer to as render target. ```cpp void HelloD3D11Application::DestroySwapchainResources() @@ -426,7 +426,7 @@ bool HelloD3D11Application::Load() } ``` -Finally we need to modify `Appplication.hpp` and `Application.cpp`. Since we want to handle resizing as well. +Finally, we need to modify `Appplication.hpp` and `Application.cpp`. Since we want to handle resizing as well. ### Application.hpp @@ -446,7 +446,7 @@ virtual void OnResize( [[nodiscard]] int32_t GetWindowHeight() const; ``` -`HandleResize` will be the callback from `GLFW` which handles resize events and `OnResize` will be execute when GLFW runs HandleResize, so that we can handle our custom things we want to execute when resizing the window, like changing the size of the swapchain in our example. +`HandleResize` will be the callback from `GLFW` which handles resize events and `OnResize` will be executed when GLFW runs HandleResize, so that we can handle our custom things we want to execute when resizing the window, like changing the size of the swapchain in our example. `GetWindow()` is used to derive the actual native window handle from, which is needed when we create the swapchain. `GetWindowWidth()` and `GetWindowHeight()` do what they say :) Also required for swapchain creation. diff --git a/docs/1-introduction/1-1-getting-started/1-1-3-hello-triangle.md b/docs/1-introduction/1-1-getting-started/1-1-3-hello-triangle.md index 72a271b..505bd7c 100644 --- a/docs/1-introduction/1-1-getting-started/1-1-3-hello-triangle.md +++ b/docs/1-introduction/1-1-getting-started/1-1-3-hello-triangle.md @@ -14,9 +14,9 @@ All the steps in the graphics pipeline go from top to bottom and are shown below As you can see, each stage in the pipeline takes in the previous stage's output as the input, the rectangle blocks are pipeline stages that are not programmable but are configurable, while the rounded rectangle blocks are stages that are fully programmable. To draw most of the things throughout this series we'll mostly need these stages: Input Assembler, Vertex Shader and the Pixel Shader, Output Merger. -The Vertex and Pixel shaders are fully programmable and we'll write a very basic program for them. +The Vertex and Pixel shaders are fully programmable, and we'll write a very basic program for them. -The other two stages are not programmable but they are fairly easy to understand and configure, the **Input Assembler** is responsible for processing the vertices in an eventual vertex buffer into the primitive of our choice, which is of course, triangles in our case, and sending this processed output to the Vertex Shader. The **Output Merger** instead is responsible for combining the values written by the pixel shader, may that be depth, color or other things, into the one or more render targets that we provide to the OM, we only have one render target for now. +The other two stages are not programmable, but they are fairly easy to understand and configure, the **Input Assembler** is responsible for processing the vertices in an eventual vertex buffer into the primitive of our choice, which is of course, triangles in our case, and sending this processed output to the Vertex Shader. The **Output Merger** instead is responsible for combining the values written by the pixel shader, may that be depth, color or other things, into the one or more render targets that we provide to the OM, we only have one render target for now. ### Vertex Shader @@ -66,7 +66,7 @@ Everything else are "user defined semantics" and their naming is up to us. These Then we have our `VSOutput`, which has our vertices in the first field `position` and our color in the second field `color`. -Finally we have our main function, which takes in a single parameter which is our input in the form of `VSInput`, and returns our output in the form of a `VSOutput`. Since we don't do any processing, we simply make a new instance of `VSOutput`, initialize it all to 0 and forward our input position and color to the output. +Finally, we have our main function, which takes in a single parameter which is our input in the form of `VSInput`, and returns our output in the form of a `VSOutput`. Since we don't do any processing, we simply make a new instance of `VSOutput`, initialize it all to 0 and forward our input position and color to the output. ### Pixel Shader @@ -106,7 +106,7 @@ Since there aren't any other shaders in between the VS and the PS, the VS's outp Next we have our output, `D3D11` gives us the possibility to write to multiple render targets, but we are not doing that, so we'll just be writing a `float4` as our output, which is an RGBA color. -Notice how we have another semantic string attached to the `color` field, this semantic string specifies which render target we want to be writing to, the `0` after `SV_Target` is the index of our render target, in our case, we have only one so we write `SV_Target0` or `SV_Target`. +Notice how we have another semantic string attached to the `color` field, this semantic string specifies which render target we want to be writing to, the `0` after `SV_Target` is the index of our render target, in our case, we have only one, so we write `SV_Target0` or `SV_Target`. `D3D11` lets us write up to 8 render targets simultaneously from the same pixel shader, those come in handy when implementing more advanced shading techniques, for example a popular technique that uses 4 or more @@ -134,7 +134,7 @@ bool CompileShader( [[nodiscard]] ComPtr CreatePixelShader(std::wstring_view fileName) const; ``` -In order we have: +In order, we have: `CompileShader`: This function is the core for compiling shaders, it requires 3 input parameters: @@ -301,7 +301,7 @@ We have successfully compiled our shaders now, we need one last thing, an **Inpu An input layout, is basically the format we want to lay our vertices in our buffers. Since all our vertices we want to give to the GPU must be tightly packed in the same buffer, the Input Assembler needs a way to make sense of our data, this is exactly what an input layout is for. -Let's see what input we expect in the vertes shader: +Let's see what input we expect in the vertex shader: ```hlsl struct VSInput @@ -313,7 +313,7 @@ struct VSInput The vertex shader expects 2 vectors of 3 components each, for each vertex. We should then create an input layout exactly with this format. -First of all, creating a `struct` in our C++ source with that maps to our `VSInput` as closely as possible will make our life easier. +First, creating a `struct` in our C++ source with that maps to our `VSInput` as closely as possible will make our life easier. To do this we'll use DirectXMath which has types that map perfectly to HLSL, both of our inputs are `float3` in HLSL, which means that this translates to `DirectX::XMFLOAT3`. @@ -358,12 +358,12 @@ constexpr D3D11_INPUT_ELEMENT_DESC vertexInputLayoutInfo[] = Now let's make sense of what each field means, let's go over one by one in order. -- `SemanticName`: let's us refer to a particular field given the string after the colon in HLSL (remember `float3 position: POSITION`) +- `SemanticName`: lets us refer to a particular field given the string after the colon in HLSL (remember `float3 position: POSITION`) - `SemanticIndex`: the index of each semantic, `POSITION` is equivalent to `POSITION0`, where the number at the end is our index, so we'll just pass in 0. - `Format`: the format of this field, basically how many components there are and what type they are, a `float3` in HLSL is a vector of 3 floats, each float is 4 bytes wide (or 32 bits), so the format here is `DXGI_FORMAT_R32G32B32_FLOAT`. - `InputSlot`: we'll see about this later. - `AlignedByteOffset`: the offset of this field, in bytes; this is our first field so there is no offset, but the `COLOR` one for example, will have an offset of 12 bytes. -- `InputSlotClass`: The rate of input either per-vertex or per-instance, we don't care about instances right now so we'll set this to PER_VERTEX. +- `InputSlotClass`: The rate of input either per-vertex or per-instance, we don't care about instances right now, so we'll set this to PER_VERTEX. - `InstanceDataStepRate`: if `InputSlotClass` was PER_INSTANCE, this would mean how many instances should be drawn with the same data; this is 0 since we don't care about this. Hopefully it makes a bit more sense now, all we have to do is create the input layout using this data: @@ -381,7 +381,7 @@ if (FAILED(_device->CreateInputLayout( } ``` -As usual we follow the same pattern, we pass in our `vertexInputLayoutInfo` that we just created and its size, we also need to pass our vertex blob pointer and size, and finally our output parameter which is our input layout. +As usual, we follow the same pattern, we pass in our `vertexInputLayoutInfo` that we just created and its size, we also need to pass our vertex blob pointer and size, and finally our output parameter which is our input layout. Now all we have to do is create a vertex buffer (don't worry it's really easy) and issue our first `Draw` command! @@ -392,7 +392,7 @@ Now all we have to do is create a vertex buffer (don't worry it's really easy) a Vertex Buffers might seem hard at first, but they're really nothing more than a buffer that resides in our device's memory, which means really fast access. This buffer will be then bound and read by the vertex shader. -Creating a vertex buffer is also really easy, first of all we have to make some data to put in our buffer, since we want to draw a triangle, we will be creating 3 vertices using our `VertexPositionColor` struct. +Creating a vertex buffer is also really easy, first we have to make some data to put in our buffer, since we want to draw a triangle, we will be creating 3 vertices using our `VertexPositionColor` struct. ```cpp constexpr VertexPositionColor vertices[] = @@ -431,11 +431,11 @@ We begin by filling a `bufferInfo` descriptor for our buffer, we specify how man And finally we create a `resourceData`, and populate the only field we care about: `pSysMem`, which is a pointer to our vertices which are currently in system RAM. -Then we issue the creation of the buffer using `CreateBuffer`, using the informations we collected until now. +Then we issue the creation of the buffer using `CreateBuffer`, using the information we collected until now. ## Drawing our triangle -Finally we have reached the moment of truth, in our `Render` function we will add a few things: +Now, we have reached the moment of truth, in our `Render` function we will add a few things: ```cpp _deviceContext->IASetInputLayout(_vertexLayout.Get()); @@ -479,7 +479,7 @@ _deviceContext->Draw(3, 0); And finally, tell the GPU to draw 3 vertices, this will invoke the vertex shader 3 times, and it will successfully process the 3 vertices we put in our vertex buffer. -Finally let's review all the commands we issue in `Render` +Finally, let's review all the commands we issue in `Render` ```cpp _deviceContext->IASetInputLayout(_vertexLayout.Get()); diff --git a/docs/1-introduction/1-1-getting-started/1-1-4-abstractions.md b/docs/1-introduction/1-1-getting-started/1-1-4-abstractions.md index 5937d63..56a5c95 100644 --- a/docs/1-introduction/1-1-getting-started/1-1-4-abstractions.md +++ b/docs/1-introduction/1-1-getting-started/1-1-4-abstractions.md @@ -1,6 +1,6 @@ # Abstractions and Quality of Life improvements -Before we move on, we are going to change a few things. When you write software you dont always want all your code +Before we move on, we are going to change a few things. When you write software you don't always want all your code in one spot, one method or one class, but split it up and separate where it makes sense to do so. This is always a good exercise in projects which are getting a bit bigger, and this project will be getting @@ -103,7 +103,7 @@ This file will contain all future vertex types as well. ### Pipeline -What is a pipeline? It's just a immutable container of various things. It describes all state for the current thing you want to render or compute. All Vertex and Pixel or Compute shaders we might require for that render task to complete, the type of primitives we want to draw and how they are setup. Since we are coming from the Hello Triangle chapter our pipeline will not contain much, but it will grow in complexity further down the chapter road. +What is a pipeline? It's just an immutable container of various things. It describes all state for the current thing you want to render or compute. All Vertex and Pixel or Compute shaders we might require for that render task to complete, the type of primitives we want to draw and how they are set up. Since we are coming from the Hello Triangle chapter our pipeline will not contain much, but it will grow in complexity further down the chapter road. ### PipelineFactory @@ -147,7 +147,7 @@ private: }; ``` -`Pipeline` is supposed to be an immutable object, there fore all relevant fields are `private`, so that you cant accidentally set them from outside. Only `PipelineFactory` will be able to access those fields, as its creating them. Also `DeviceContext` can access them too, as it needs these to set the actual state/values. +`Pipeline` is supposed to be an immutable object, therefore all relevant fields are `private`, so that you can't accidentally set them from outside. Only `PipelineFactory` will be able to access those fields, as its creating them. Also `DeviceContext` can access them too, as it needs these to set the actual state/values. We also create `Pipeline.cpp` with the following content: @@ -171,7 +171,7 @@ void Pipeline::SetViewport( Its quite empty for now. -Lets move on to `PipelineFactory`. Create a new file `PipelineFactory.hpp` and add the following content: +Let's move on to `PipelineFactory`. Create a new file `PipelineFactory.hpp` and add the following content: ```cpp #pragma once diff --git a/docs/about.md b/docs/about.md index 1399960..760a2cb 100644 --- a/docs/about.md +++ b/docs/about.md @@ -3,6 +3,7 @@ ## Disclaimer We are just a bunch of graphics programming enthusiasts doing all this on our own time. -If you find typos, bugs or have questions, dont hesitate to open an issue or even send a PR, otherwise join us on our discord server +If you find typos, bugs or have questions, don't hesitate to open an issue or even send a PR, +otherwise feel free to join us on our Discord server. -[Join Graphics Programming](https://discord.gg/6mgNGk7) \ No newline at end of file +[Join Graphics Programming](https://discord.gg/6mgNGk7) diff --git a/docs/index.md b/docs/index.md index d27d054..ef4f52b 100644 --- a/docs/index.md +++ b/docs/index.md @@ -2,4 +2,20 @@ ## Goal -Explain the goal +This is LearnD3D11, a guide aimed at anyone trying to learn Direct3D11, commonly referred to as +DirectX 11. This guide explains the basic usage of Direct3D11 and general graphics programming +topics and techniques, without requiring any previous experience within this field. The guide's +code itself is written in C++, although if one has experience with C++ and can understand how we +use it, it is probably easily transferable to any other language. + +## Disclaimer + +We are just a bunch of graphics programming enthusiasts doing all this on our own time. This +project is also still a **work in progress**; a lot of content may be missing or faulty. +If you find typos, bugs or have questions, don't hesitate to open an issue or even send a PR. +Also feel free to join us on our [Discord server](https://discord.gg/6mgNGk7). + +## Getting started + +To get started reading LearnD3D11, you can jump right into the +[first chapter](1-introduction/1-1-getting-started/1-1-0-overview/)!