So here's some code from one of my projects. In this example, the constructor and destructor are pretty simple. In fact, I'm not even really using the Destructor. I'm kind of bad about that. I mostly just do initialization in my constructor here. I don't use the modern convention of setting defaults for the variables in the constructor declaration. That's just old habits dying hard.
DirectXGame.h
#pragma once
#include<d3d11.h>
#include<d3dx11.h>
#include<DxErr.h>
#include "GameTimer.h"
#include "KeyboardClass.h"
#pragma comment(lib, "DxErr.lib")
#pragma comment(lib, "d3d11.lib")
#pragma comment(lib, "d3dx11.lib")
#pragma comment(lib, "d3dcompiler.lib")
//Predefined colors made to match XNA that you can use or not use.
const float RGBABlue[4] = {0.0f,0.0f,1.0f,1.0f};
const float RGBABlack[4] = {0.0f,0.0f,0.0f,1.0f};
const float RGBAWhite[4] = {1.0f,1.0f,1.0f,1.0f};
const float RGBAGreen[4] = {0.0f,0.5019607843137255f,0.0f,1.0f};
const float RGBARed[4] = {1.0f,0.0f,0.0f,1.0f};
const float RGBAYellow[4] = {1.0f,1.0f,0.0f,1.0f};
const float RGBACornFlowerBlue[4] = {0.392156862745098f,0.5843137254901961f,0.9294117647058824f,1.0f};
//=====================================================================================================================
// DirectX11Game
//
// Purpose:
// To encapsulate DirectDraw3D(DirectX) initialization/shutdown and obfuscate it so that we can forget about it.
//
// Notes:
// This class allows DirectX to mostly be obfuscated away so that the programmer doesn't have to deal with anything
// that is required to startup DX and get it properly initialized or to shut down DX when it is time to close the application.
//
// In order to write a "game" the programmer is expected to create a game object that inherits from this class which will
// hook it in to this whole system. The main code will call this object to initialize DX and this code will call the game
// object that contains all the code for the game.
//
// This is very basic bare bones code not designed to handle every feature of every graphics card. You may want to expand
// on this code a little bit to do things like checking whether the graphics card supports anti-aliasing or not before turning
// anti-aliasing on. However, by making a few minor adjustments such as matching the screen resolution to your own, this should
// give you the code needed to start every DX project you might want to do and run it on your computer. Other than anti-aliasing
// this is mostly all required code to make DX run. This is by far the longest class in this bare bones code.
//
//=====================================================================================================================
class DirectX11Game
{
public:
DirectX11Game();
virtual ~DirectX11Game();
bool InitializeDX(HINSTANCE hInstance, HWND hWnd);
void CreateViewPort(unsigned int ScreenWidth, unsigned int ScreenHeight);
D3D11_DEPTH_STENCIL_VIEW_DESC SetDepthStencilViewDesc();
bool InitializeGameClass();
void Shutdown();
bool CreateDeviceAndSwapChain(unsigned int Width, unsigned int Height);
bool DeviceContextIsDefined();
virtual bool Initialize();
virtual bool LoadContent();
virtual void UnloadContent();
virtual void Update(float dt) = 0;
virtual void Draw(float) = 0;
GameTimer Timer;
protected:
HINSTANCE WindowInstanceHandle;
HWND WindowHandle;
KeyboardClass Keyboard;
D3D_DRIVER_TYPE DriverType;
D3D_FEATURE_LEVEL GraphicsCardFeatureLevel;
ID3D11DeviceContext* GraphicsDeviceContext;
ID3D11Device* GraphicsDevice;
IDXGISwapChain* SwapChain;
ID3D11RenderTargetView* BackBuffer;
ID3D11DepthStencilView* DepthStencilView;
ID3D11Texture2D* DepthStencilTexture;
D3D11_TEXTURE2D_DESC DepthStencilTextureDescription;
bool CreateDepthStencilTexture(unsigned int ScreenWidth, unsigned int ScreenHeight);
bool SetDepthStencil(void);
};
//=====================================================================================================================
DirectX.cpp
#include"DirectX11Game.h"
#include<D3Dcompiler.h>
//=====================================================================================================================
// Constructor
//
// Purpose:
// Initialize basic values for the DXGame object.
//
// Notes:
// The feature level sets which version of DX to use. DX 11.1 seems to be the most recent here but we won't use any
// features that are not available in DX 11.0 for these tutorials.
//
// More information can be found on the DriverType at:https://msdn.microsoft.com/en-us/library/windows/desktop/ff476328(v=vs.85).aspx
//
//=====================================================================================================================
DirectX11Game::DirectX11Game()
{
DriverType = D3D_DRIVER_TYPE_HARDWARE;
GraphicsCardFeatureLevel = D3D_FEATURE_LEVEL_11_1;
GraphicsDevice = nullptr;
GraphicsDeviceContext = nullptr;
SwapChain = nullptr;
BackBuffer = nullptr;
}
//=====================================================================================================================
//=====================================================================================================================
// Destructor
//
// Purpose:
// Cleanup of any class specific code.
//
// Notes:
// Not used, but you are welcome to use it if you like.
//
//=====================================================================================================================
DirectX11Game::~DirectX11Game()
{
}
//=====================================================================================================================
//=====================================================================================================================
// DirectX11Game::InitializeDX()
//
// Purpose:
//
// Input:
// HINSTANCE hInstance - A Windows handle to our process. Mostly brought in here to allow the DXGame object to remember it if needed.
// HWND hWnd - A Windows handle to our window.
//
// Output:
// bool - Returns true if DirectX initialized properly without problems.
//
// Notes:
// Creates the Graphics Device and Device Context
// Creates the Swap Chain
// Assigns memory to the Swap Chain back buffer
// Uses the back buffer to create a render target
// Assigns memory to the Depth Stencil
// Assigns depth stencil to the Graphics Device
// Sets the view port and render target for the Graphics Device Context
// Runs Game class's startup code
//
//=====================================================================================================================
bool DirectX11Game::InitializeDX(HINSTANCE hInstance, HWND hWnd)
{
bool Initialized = false; //Return value - must be true if properly initialized.
ID3D11Texture2D* BackBufferTexture; //The back buffer.
unsigned int ScreenWidth;
unsigned int ScreenHeight;
HRESULT hr; //Used to determine if DX functions succeeded or not.
WindowHandle = hWnd; //The object will have the window's handle for latter use.
WindowInstanceHandle = hInstance; //The object will have the window's instance handle for latter use.
ScreenWidth = 1280;
ScreenHeight = 720;
if (CreateDeviceAndSwapChain(ScreenWidth, ScreenHeight))
{
if(SUCCEEDED(SwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&BackBufferTexture)))
{
if(SUCCEEDED(GraphicsDevice->CreateRenderTargetView(BackBufferTexture, 0, &BackBuffer)))
{
if(CreateDepthStencilTexture(ScreenWidth, ScreenHeight))
{
D3D11_DEPTH_STENCIL_VIEW_DESC DepthStencilViewDescription = SetDepthStencilViewDesc();
if(SUCCEEDED(hr = GraphicsDevice->CreateDepthStencilView(DepthStencilTexture, &DepthStencilViewDescription, &DepthStencilView)))
{
CreateViewPort(ScreenWidth, ScreenHeight);
if (Keyboard.Initialize(WindowInstanceHandle, WindowHandle)) //Don't bother going further if DirectInput doesn't initialize.
{
Initialized = InitializeGameClass();
}
}
else DXTRACE_ERR("Failed to create depth stencil view!", hr);
}
else DXTRACE_MSG("Failed to create the depth stencil texture!");
}
else DXTRACE_MSG("Failed to create the render target ViewMatrix!");
if(BackBufferTexture) BackBufferTexture->Release(); //BackBufferTexture pointer no longer needed.
}
else DXTRACE_MSG("Failed to get the swap chain back buffer!");
}
return Initialized;
}
//=====================================================================================================================
//=====================================================================================================================
// DirectX11Game::CreateViewPort()
//
// Purpose:
//
// Input:
// unsigned int ScreenWidth - Resolution/Width of screen display in pixels.
// unsigned int ScreenHeight - Resolution/Height of screen display in pixels.
//
// Output:
// None
//
// Notes:
// This method merely sets the render target to draw to the backbuffer(screen). And it sets the viewport. Keep in mind
// that this can be a region of the screen rather than the whole screen. So, with 4 render targets you can have 4 different
// displays on the same screen. For our example here, we're just working with 1 render target, 1 view port, and 1 computer
// monitor, but this can be expanded to do a lot more.
//
//=====================================================================================================================
void DirectX11Game::CreateViewPort(unsigned int ScreenWidth, unsigned int ScreenHeight)
{
D3D11_VIEWPORT DXViewPort; //Conceptually, a viewport is a two dimensional(2D) rectangle into which a 3D scene is projected.In Direct3D, the rectangle exists as coordinates within a Direct3D surface that the system uses as a rendering target.
GraphicsDeviceContext->OMSetRenderTargets(1, &BackBuffer, DepthStencilView); //Sets rendering(drawing) to the current back buffer maintained by this object.
DXViewPort.Width = static_cast<float>(ScreenWidth);
DXViewPort.Height = static_cast<float>(ScreenHeight);
DXViewPort.MinDepth = 0.0f;
DXViewPort.MaxDepth = 1.0f;
DXViewPort.TopLeftX = 0.0f;
DXViewPort.TopLeftY = 0.0f;
GraphicsDeviceContext->RSSetViewports(1, &DXViewPort);
}
//=====================================================================================================================
//=====================================================================================================================
// DirectX11Game::SetDepthStencilViewDesc()
//
// Purpose:
// To return a depth stencil view description data structure to describe how the depth stencil should be setup.
//
// Input:
// None.
//
// Output:
// D3D11_DEPTH_STENCIL_VIEW_DESC - Object that describes the depth stencil.
//
// Notes:
// This method is actually very straight forward. It creates a depth stencil view description object. It zeros out the
// memory being used to initialize the memory. Then it sets the parameters of this object and returns the data structure.
//
// The depth stencil is used primarily to determine an object's depth in the scene being drawn so that the objects can
// correctly be drawn in any order and yet closer objects will still be drawn on top of objects further away.
//
// I've gone ahead here and changed the code from no anti-aliasing to anti-aliasing. Turn off anti-aliasing if your
// graphics card has a problem with it. Aliasing is the "stair step" effect you see on lines and edges of objects when
// drawn. Anti-aliasing basiclly blurs these edges.
//
//=====================================================================================================================
D3D11_DEPTH_STENCIL_VIEW_DESC DirectX11Game::SetDepthStencilViewDesc()
{
D3D11_DEPTH_STENCIL_VIEW_DESC DepthStencilViewDescription;
ZeroMemory(&DepthStencilViewDescription, sizeof(DepthStencilViewDescription));
DepthStencilViewDescription.Format = DepthStencilTextureDescription.Format;
//DepthStencilViewDescription.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D; //No anti-aliasing
DepthStencilViewDescription.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DMS; //Anti-aliasing
DepthStencilViewDescription.Texture2D.MipSlice = 0;
return DepthStencilViewDescription;
}
//=====================================================================================================================
//=====================================================================================================================
// DirectX11Game::InitializeGameClass()
//
// Purpose:
// To run the programmer's custom initialization code at startup.
//
// Input:
// None.
//
// Output:
// bool - true if no errors occured.
//
// Notes:
// This method calls into the Game class that inheriets from this class which allows the programmer to include their own
// code to initialize and load art assets. The timer object is also initialized to start the clock so that we can know
// how much time has passed between each frame.
//
// All of the method that this method calls out to return false if there was a failure or error. So, if everything returns
// true, this method will return true also to indicate that everything initialized properly.
//
//=====================================================================================================================
bool DirectX11Game::InitializeGameClass()
{
bool Initialized = false; //Return value - must be true if properly initialized.
if (Initialize()) //Call Game class's Initialize method to do programmer defined initialization.
{
if (LoadContent()) //Call Game class's LoadContent method to load programmer defined game assets.
{
if (Timer.Initialize()) Initialized = true; //Initialize the Game Timer and we're good.
}
}
return Initialized;
}
//=====================================================================================================================
//=====================================================================================================================
// DirectX11Game::CreateDepthStencilTexture()
//
// Purpose:
// To create a 2D texture (memory buffer) to be ussed for the depth stencil.
//
// Input:
// unsigned int ScreenWidth - Width of the display resolution of the computer monitor.
// unsigned int ScreenHeight - Height of the display resolution of the computer monitor.
//
// Output:
// bool - true if no errors occured.
//
// Notes:
// This method creates a 2D texture that will be used as the depth stencil. This buffer of memory has to be the exact same
// size as the display screen which means it has to be the same size as the back and front buffers. Each "pixel" in this buffer
// matches up with a pixel in the back buffer. In this buffer it is not storing the color for the object on the screen but rather
// the depth in the scene away from the camera of the matching pixel in the back buffer. This allows the graphics card to know
// whether the pixel it is about to draw for a given object on the back buffer is an object in front of or in back of the color
// pixel of the object that has already been drawn.
//
// So, in other words it stores the distance of an object when it draws that object and every other object it draws after
// that gets tested in the depth stencil to determine whether it is closer or further away than the object already drawn on a
// pixel by pixel basis. So, objects that are behind an object already drawn will not get drawn and objects in front of the object
// already drawn will get drawn on top of the objects already drawn.
//
// I set this up for anti-aliasing because you will probably prefer to have anti-aliasing on. However, I left the code
// needed to turn anti-aliasing off if you would rather use that (presumably because your graphics card doesn't handle
// anti-aliasing although I can't imagine anyone has ever made a DX11 graphics card that doesn't do at least some level of
// anti-aliasing. However, I've heard there are not many examples out there showing how to do anti-aliasing, so I wanted to
// go ahead and show how that can be done here. Like a lot of things with DX programming, this is personal preference if
// your graphics card can do it.
//
//=====================================================================================================================
bool DirectX11Game::CreateDepthStencilTexture(unsigned int ScreenWidth, unsigned int ScreenHeight)
{
bool CreatedTextureForDepthStencil = false; //Fail unless we succeed.
ZeroMemory(&DepthStencilTextureDescription, sizeof(DepthStencilTextureDescription)); //Initialize memory for this object so that we don't get surprises and so we know what the initial values are when debugging.
DepthStencilTextureDescription.Width = ScreenWidth;
DepthStencilTextureDescription.Height = ScreenHeight;
DepthStencilTextureDescription.MipLevels = 1;
DepthStencilTextureDescription.ArraySize = 1;
DepthStencilTextureDescription.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
//DepthStencilTextureDescription.SampleDesc.Count = 1; //No anti-aliasing
DepthStencilTextureDescription.SampleDesc.Count = 8; //Anti-aliasing
//DepthStencilTextureDescription.SampleDesc.Quality = 0; //No anti-aliasing
DepthStencilTextureDescription.SampleDesc.Quality = 4; //Anti-aliasing
DepthStencilTextureDescription.Usage = D3D11_USAGE_DEFAULT;
DepthStencilTextureDescription.BindFlags = D3D11_BIND_DEPTH_STENCIL;
DepthStencilTextureDescription.CPUAccessFlags = 0;
DepthStencilTextureDescription.MiscFlags = 0;
if(SUCCEEDED(GraphicsDevice->CreateTexture2D(&DepthStencilTextureDescription, NULL, &DepthStencilTexture)))
{
CreatedTextureForDepthStencil = true;
}
return CreatedTextureForDepthStencil;
}
//=====================================================================================================================
//=====================================================================================================================
// DirectX11Game::CreateDeviceAndSwapChain()
//
// Purpose:
// To create the Device, Device Context, and Swap Chain. Basically, initializes DX.
//
// Input:
// unsigned int Width - Width of the display resolution of the computer monitor.
// unsigned int Height - Height of the display resolution of the computer monitor.
//
// Output:
// bool - true if no errors occured.
//
// Notes:
// This method is the core of starting up DX. This one method, by calling D3D11CreateDeviceAndSwapChain, almost single handedly
// initializes DX. Three of the most important parts of DX are setup here in this one call: the Device, the Device Context, and the
// swap chain.
//
// I have to admit that I'm still basically trying to understand exactly what a device and a device context are. Here is MS's
// documentation on the matter:
// https://msdn.microsoft.com/en-us/library/windows/desktop/ff476880(v=vs.85).aspx
//
// Basicaly, the best explanation I've heard comes from MS and is that a device is basically used to put together the resources
// that the graphics card uses such as textures and vertex buffers. And a device context is what actually does the work. At least,
// that's my current understanding of the matter.
//
// Regardless, the combination of the device and device context ARE DirectDraw3D/DirectX. This is the COM object that is
// DirectX and that does all the drawing.
//
// The swapchain consists of the front buffer and one or more back buffers. The front buffer is the area of memory where
// the graphics card looks to determine what color every pixel on your computer screen will be drawn with. By drawing all the
// pixels on the computer screen in the correct color, you get the image on your computer screen. All the front buffer contains
// is a color for every pixel to be drawn on the screen (I say screen but you could be drawing picture in picture or multiple
// cameras which would each need their own swap chain.) But it is 1 to 1 with each value in the front buffer representing nothing
// but a color for a pixel on the screen. Whatever is in the front buffer IS what's on your computer screen.
//
// You could theoretically draw to the front buffer, but we don't. The primary reason is that if you do, you get what is called
// screen tearing. You can google that to get some great example images of what that is. But basically it means that when something
// changes between frames part of the screen still has the image for the previous frame and part of the screen has the image for the
// new frame and you can see the line where they don't agree with one another.
//
// So, instead we create an identical buffer called the back buffer which we draw to instead. Then we do a SUPER fast change between
// frames all at once to flip the buffers. Actually, the difference between the front buffer and the back buffer is just which one the
// pointer points to. Flipping the back buffer and front buffer is called "presenting" and all that happens is that between frames the
// back buffer pointer is changed to point to the front buffer memory and the front buffer pointer is changed to point to the back buffer
// memory. Then the new frame is presented to the video display all at once without any tearing. And changing two memory pointers is super
// fast not to mention that this can be coordinated with the drawing so that it occurs between screen refreshes. The screen refresh rate
// is also set here if you like. 1/60th of a second is pretty standard.
//
// Two buffers is called double buffering. But you can have even more back buffers if needed for some reason. The front buffer
// and all the back buffers is what is known as the "swap chain".
//
// If D3D11CreateDeviceAndSwapChain succeeds then it returns a pointer to the Device, Device Context, and swap chain. If it fails
// then DirectX is not going to be able to draw anything to the screen and we probably might as well close the application and call it
// quits. This method returns false if such a catostrophic failure occurs.
//
// This isn't really designed to work with multiple graphics cards or even multiple monitors. So, you're pretty much on your own
// modding this code to make it handle that. It pretty much goes with the first graphics port it finds.
//
//=====================================================================================================================
bool DirectX11Game::CreateDeviceAndSwapChain(unsigned int Width, unsigned int Height)
{
bool DriverFound = false; //Assume we fail unless everything goes right.
unsigned int Driver = 0;
unsigned int NumberOfDriverTypes;
unsigned int NumberOfFeatureLevels;
unsigned int DeviceCreationFlags = NULL;
D3D_DRIVER_TYPE DriverTypes[] =
{
D3D_DRIVER_TYPE_HARDWARE, D3D_DRIVER_TYPE_WARP,
D3D_DRIVER_TYPE_REFERENCE, D3D_DRIVER_TYPE_SOFTWARE //The driver types we want to support. Usually only the hardware driver.
};
D3D_FEATURE_LEVEL FeatureLevels[] =
{
D3D_FEATURE_LEVEL_11_1,
D3D_FEATURE_LEVEL_11_0 //,
//D3D_FEATURE_LEVEL_10_1,
//D3D_FEATURE_LEVEL_10_0 //The different versions of DX hardware we want to support.
};
NumberOfDriverTypes = ARRAYSIZE(DriverTypes);
NumberOfFeatureLevels = ARRAYSIZE(FeatureLevels);
DXGI_SWAP_CHAIN_DESC swapChainDesc;
ZeroMemory(&swapChainDesc, sizeof(swapChainDesc)); //Initialize the memory by zero'ing it all out.
swapChainDesc.BufferCount = 1;
swapChainDesc.BufferDesc.Width = Width;
swapChainDesc.BufferDesc.Height = Height;
swapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
swapChainDesc.BufferDesc.RefreshRate.Numerator = 60;
swapChainDesc.BufferDesc.RefreshRate.Denominator = 1;
swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
swapChainDesc.OutputWindow = WindowHandle; //Connect DirectX to the window so that DX can draw in the application's window.
swapChainDesc.Windowed = true; //Create windowed or full screen.
//swapChainDesc.SampleDesc.Count = 1; //No anti-aliasing
swapChainDesc.SampleDesc.Count = 8; //Anti-aliasing
//swapChainDesc.SampleDesc.Quality = 0; //No anti-aliasing
swapChainDesc.SampleDesc.Quality = 4; //Anti-aliasing
swapChainDesc.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH; //Allow full screen switching;
#ifdef _DEBUG
DeviceCreationFlags |= D3D11_CREATE_DEVICE_DEBUG; //If you're debugging, you might want a little extra info as to what went wrong.
#endif
do
{
if(SUCCEEDED(D3D11CreateDeviceAndSwapChain(0, DriverTypes[Driver], 0, DeviceCreationFlags, FeatureLevels, NumberOfFeatureLevels,
D3D11_SDK_VERSION, &swapChainDesc, &SwapChain, &GraphicsDevice, &GraphicsCardFeatureLevel, &GraphicsDeviceContext)))
{
DriverType = DriverTypes[Driver];
DriverFound = true; //We can now draw to the screen. Exit after finding the first working graphics driver type.
}
++Driver;
}
while (Driver < NumberOfDriverTypes && !DriverFound);
if(!DriverFound) DXTRACE_MSG("Failed to create the Direct3D device!");
return DriverFound;
}
//=====================================================================================================================
//=====================================================================================================================
// DirectX11Game::DeviceContextIsDefined()
//
// Purpose:
// Allows the programmer to ask this object whether there is currently a valid Device Context created.
//
// Input:
//
// Output:
// bool - true there is a GraphicsDeviceContext defined.
//
// Notes:
// GraphicsDeviceContext is an interface to the DX COM object that allows us to manipulate the graphics card. If DX is not
// properly initialized we will not have a pointer to this interface. We don't want to make calls to DX if it is not properly
// initialized.
//
//=====================================================================================================================
bool DirectX11Game::DeviceContextIsDefined(void)
{
return GraphicsDeviceContext != NULL;
}
//=====================================================================================================================
//=====================================================================================================================
// DirectX11Game::Initialize()
//
// Purpose:
// Mostly just a place holder to make the Game object that inherits from this class have an Initialize() method of its own.
//
// Input:
// None.
//
// Output:
// bool - never fail.
//
// Notes:
// This is a virtual method to make the child object that inherits from this object implement an initialization method.
//
//=====================================================================================================================
bool DirectX11Game::Initialize()
{
return true;
}
//=====================================================================================================================
//=====================================================================================================================
// DirectX11Game::LoadContent()
//
// Purpose:
// Mostly just a place holder to make the Game object that inherits from this class have a LoadContent() method of its own.
//
// Input:
// None.
//
// Output:
// bool - never fail.
//
// Notes:
// This is a virtual method to make the child object that inherits from this object implement a load content method.
//
//=====================================================================================================================
bool DirectX11Game::LoadContent()
{
return true;
}
//=====================================================================================================================
//=====================================================================================================================
// DirectX11Game::UnloadContent()
//
// Purpose:
// Mostly just a place holder to make the Game object that inherits from this class have an UnloadContent() method of its own.
//
// Input:
// None.
//
// Output:
// None.
//
// Notes:
// This is a virtual method to make the child object that inherits from this object implement an UnloadContent method.
//
//=====================================================================================================================
void DirectX11Game::UnloadContent()
{
}
//=====================================================================================================================
//=====================================================================================================================
// DirectX11Game::Shutdown()
//
// Purpose:
// To cleanly shut down DirectX and our application.
//
// Input:
// None.
//
// Output:
// None.
//
// Notes:
// The first thing this method does is call the Game object that inherits from this class's UnloadContent() method to
// free up any memory used for art assets by that object. Then it basically just shuts down DX and releases any memory
// associated with DX.
//
//=====================================================================================================================
void DirectX11Game::Shutdown()
{
UnloadContent();
Keyboard.Shutdown(); //Release DirectInput and the keyboard device.
GraphicsDeviceContext->ClearState();
if(DepthStencilTexture) DepthStencilTexture->Release();
if(DepthStencilView) DepthStencilView->Release();
if(BackBuffer) BackBuffer->Release();
if(SwapChain)
{
SwapChain->SetFullscreenState(FALSE, NULL);
SwapChain->Release();
}
if(GraphicsDeviceContext) GraphicsDeviceContext->Release();
if(GraphicsDevice) GraphicsDevice->Release();
BackBuffer = NULL;
SwapChain = NULL;
GraphicsDeviceContext = NULL;
GraphicsDevice = NULL;
}
//=====================================================================================================================