# DirectX/10.0/Direct3D/2D Rendering

Being able to render 2D images to the screen is very useful. For example, most user interfaces, sprite systems, and text engines are made up of 2D images. DirectX 11 allows you to render 2D images by mapping them to polygons and then rendering using an orthographic projection matrix.

## 2D Screen Coordinates

To render 2D images to the screen you will need to calculate the screen X and Y coordinates. For DirectX the middle of the screen is 0,0. From there the left side of the screen and the bottom side of the screen go in the negative direction. The right side of the screen and the top of the screen go in the positive direction. As an example take a screen that is 1024x768 resolution, the coordinates for the borders of the screen would be as follows:
So keep in mind that all your 2D rendering will need to work with these screen coordinate calculations and that you will also need the size of the user's window/screen for correct placement of 2D images.

## Disabling Z buffer in DirectX 11

To draw in 2D you should be disabling the Z buffer. When the Z buffer is turned off it will write the 2D data over top of whatever is in that pixel location. Make sure to use the painter's algorithm and draw from the back to the front to ensure you get your expected rendering output.
Once you are done drawing 2D graphics re-enable the Z buffer again so you can render 3D objects properly again.
To turn the Z buffer on and off you will need to create a second depth stencil state the same as your 3D one except with DepthEnable set to false. Then just use OMSetDepthStencilState to switch between the two states to turn the Z buffer on and off.

## Dynamic Vertex Buffers

Another new concept that will be introduced is dynamic vertex buffers. So far we have used static vertex buffers in the previous tutorials. The issue with static vertex buffers is that you can't change the data inside the buffer ever. Dynamic vertex buffers on the other hand allow us to manipulate the information inside the vertex buffer each frame if we need to. These buffers are much slower than static vertex buffers but that is the trade off for the extra functionality.
The reason we use dynamic vertex buffers with 2D rendering is because we often want to move the 2D image around the screen to different locations. A good example is a mouse pointer, it gets moved often so the vertex data that represents its position on the screen needs to change often as well.
Two extra things to note. Don't use dynamic vertex buffers unless they are absolutely called for, they are quite a bit slower than static buffers. Secondly never destroy and recreate a static vertex buffer each frame, this can completely lock the video card (which I have seen on ATI but not on Nvidia) and is far worse in overall performance when compared to using dynamic vertex buffers.

## Orthographic Projection in DirectX 11

The final new concept required to render in 2D is to use an orthographic projection matrix in place of the regular 3D projection matrix. This will allow you to render to 2D screen coordinates. Remember that we already did create this matrix in the Direct3D initialization code:

## Framework

The code in this tutorial is based on the previous tutorials. The major difference in this tutorial is that ModelClass has been replaced with BitmapClass and that we are using the TextureShaderClass again instead of the LightShaderClass. The framework will look like the following:

## Bitmapclass.h

BitmapClass will be used to represent an individual 2D image that needs to be rendered to the screen. For every 2D image you have you will need a new BitmapClass for each. Note that this class is just the ModelClass re-written to handle 2D images instead of 3D objects.
Each bitmap image is still a polygon object that gets rendered similar to 3D objects. For 2D images we just need a position vector and texture coordinates.
The BitmapClass will need to maintain some extra information that a 3D model wouldn't such as the screen size, the bitmap size, and the last place it was rendered. We have added extra private variables here to track that extra information.

## Bitmapclass.cpp

The class constructor initializes all the private pointers in the class.
In the Initialize function both the screen size and image size are stored. These will be required for generating exact vertex locations during rendering. Note that the pixels of the image do not need to be exactly the same as the texture that is used, you can set this to any size and use any size texture you want also.
The previous rendering location is first initialized to negative one. This will be an important variable that will locate where it last drew this image. If the image location hasn't changed since last frame then it won't modify the dynamic vertex buffer which will save us some cycles.
The buffers are then created and the texture for this bitmap image is also loaded in.
The Shutdown function will release the vertex and index buffers as well as the texture that was used for the bitmap image.
Render puts the buffers of the 2D image on the video card. As input it takes the position of where to render the image on the screen. The UpdateBuffers function is called with the position parameters. If the position has changed since the last frame it will then update the location of the vertices in the dynamic vertex buffer to the new location. If not it will skip the UpdateBuffers function. After that the RenderBuffers function will prepare the final vertices/indices for rendering.
GetIndexCount returns the number of indexes for the 2D image. This will pretty much always be six.
The GetTexture function returns a pointer to the texture resource for this 2D image. The shader will call this function so it has access to the image when drawing the buffers.
InitializeBuffers is the function that is used to build the vertex and index buffer that will be used to draw the 2D image.
We set the vertices to six since we are making a square out of two triangles, so six points are needed. The indices will be the same.
Here is the big change in comparison to the ModelClass. We are now creating a dynamic vertex buffer so we can modify the data inside the vertex buffer each frame if we need to. To make it dynamic we set Usage to D3D11_USAGE_DYNAMIC and CPUAccessFlags to D3D11_CPU_ACCESS_WRITE in the description.
We don't need to make the index buffer dynamic since the six indices will always point to the same six vertices even though the coordinates of the vertex may change.
ShutdownBuffers releases the vertex and index buffers.
The UpdateBuffers function is called each frame to update the contents of the dynamic vertex buffer to re-position the 2D bitmap image on the screen if need be.
We check if the position to render this image has changed. If it hasn't changed then we just exit since the vertex buffer doesn't need any changes for this frame. This check can save us a lot of processing.
If the position to render this image has changed then we record the new location for the next time we come through this function.
The four sides of the image need to be calculated. See the diagram at the top of the tutorial for a complete explanation.
Now that the coordinates are calculated create a temporary vertex array and fill it with the new six vertex points.
Now copy the contents of the vertex array into the vertex buffer using the Map and memcpy functions.
The RenderBuffers function sets up the vertex and index buffers on the gpu to be drawn by the shader.
The following function loads the texture that will be used for drawing the 2D image.
This ReleaseTexture function releases the texture that was loaded.

## D3dclass.h

The D3DClass has been modified to handle enabling and disabling the Z buffer.
We now have two new function in the D3DClass for turning the Z buffer on and off when rendering 2D images.
There is also a new depth stencil state for 2D drawing.

## D3dclass.cpp

We will just cover the functions that have changed in this class since the texturing tutorial.
Initialize the new depth stencil state to null in the class constructor.
We have a new depth stencil description variable for setting up the new depth stencil.
Here we setup the description of the depth stencil. Notice the only difference between this new depth stencil and the old one is the DepthEnable is set to false here for 2D drawing.
Now create the new depth stencil.
Here we release the new depth stencil during the Shutdown function.
These are the new functions for enabling and disabling the Z buffer. To turn Z buffering on we set the original depth stencil. To turn Z buffering off we set the new depth stencil that has depthEnable set to false. Generally the best way to use these functions is first do all your 3D rendering, then turn the Z buffer off and do your 2D rendering, and then turn the Z buffer on again.

## Graphicsclass.h

Here we include the new BitmapClass header file.
We create a new private BitmapClass object here.

## Graphicsclass.cpp

We initialize the new bitmap object to null in the class constructor.
Here is where we create and initialize the new BitmapClass object. It uses the seafloor.dds as the texture and I set the size to 256x256. You can change this size to whatever you like as it does not need to reflect the exact size of the texture.
The BitmapClass object is released in the Shutdown function.
We now also get the ortho matrix from the D3DClass for 2D rendering. We will pass this in instead of the projection matrix.
The Z buffer is turned off before we do any 2D rendering.
We then render the bitmap to the 100, 100 location on the screen. You can change this to wherever you want it rendered.
Once the vertex/index buffers are prepared we draw them using the texture shader. Notice we send in the orthoMatrix instead of the projectionMatrix for rendering 2D. Due note also that if your view matrix is changing you will need to create a default one for 2D rendering and use it instead of the regular view matrix. In this tutorial using the regular view matrix is fine as the camera in this tutorial is stationary.
After all the 2D rendering is done we turn the Z buffer back on for the next round of 3D rendering.

## Summary

With these new concepts we can now render 2D images onto the screen. This opens the door for rendering user interfaces and font systems.

## To Do Exercises

1. Recompile the code and ensure you get a 2D image drawn to the 100, 100 location on your screen.
2. Change the location on the screen where the image is drawn to.
3. Change the size of the image in the m_Bitmap->Initialize function call in the GraphicsClass.
4. Change the texture that is used for the 2D image.