├── DirectXUtilities └── DirectXUtilities.h ├── DirectXWindow ├── DirectXWindow.cpp └── DirectXWindow.h ├── README.md ├── StringCoverter └── StringConverter.h ├── Window ├── Window.cpp └── Window.h └── winmain.cpp /DirectXUtilities/DirectXUtilities.h: -------------------------------------------------------------------------------- 1 | /** 2 | * DirectXUtilities.h 3 | * Purpose: Provide memory management tools for the main DirectX window. 4 | * 5 | * @author Raul Butuc 6 | * @version 1.0.0 07/03/2015 7 | */ 8 | 9 | #pragma once 10 | 11 | #include 12 | #include 13 | 14 | #pragma comment(lib, "d3d11.lib") 15 | 16 | namespace MemoryManagement { 17 | 18 | /** 19 | * Safely deallocate a pointer from memory after being used. 20 | * 21 | * @param _ptr The pointer of generic type _PtrT that is to be deallocated. 22 | */ 23 | template 24 | void SafeDelete(_PtrT& _ptr) { 25 | if (_ptr) { 26 | delete _ptr; 27 | _ptr = nullptr; 28 | } 29 | } 30 | 31 | /** 32 | * Safely deallocate an array from memory after being used. 33 | * 34 | * @param _ptr The pointer of generic type _PtrT that is to be deallocated. 35 | */ 36 | template 37 | void SafeDeleteArr(_PtrT& _ptr) { 38 | if (_ptr) { 39 | delete[] _ptr; 40 | _ptr = nullptr; 41 | } 42 | } 43 | 44 | /** 45 | * Safely release a pointer from memory after being used. 46 | * 47 | * @param _ptr The pointer of generic type _PtrT that is to be released. 48 | */ 49 | template 50 | void SafeRelease(_PtrT& _ptr) { 51 | if (_ptr) { 52 | _ptr->Release(); 53 | _ptr = nullptr; 54 | } 55 | } 56 | } -------------------------------------------------------------------------------- /DirectXWindow/DirectXWindow.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * DirectXWindow.cpp 3 | * Purpose: Build a DirectX managed window. 4 | * 5 | * @author Raul Butuc 6 | * @version 1.0.1 07/03/2015 7 | */ 8 | 9 | #include "DirectXWindow.h" 10 | 11 | namespace DirectXApplication { 12 | 13 | /** 14 | * Call the base class constructor with the same parameters. 15 | * 16 | * @param hInstance The current instance handler. 17 | * @param ClientWidth The width of the client. 18 | * @param ClientHeight The height of the client. 19 | * @param AppTitle The title for the window. 20 | */ 21 | DirectXWindow::DirectXWindow(HINSTANCE hInstance, UINT ClientWidth, UINT ClientHeight, string AppTitle) : 22 | Window(hInstance, ClientWidth, ClientHeight, AppTitle) {} 23 | 24 | /** 25 | * Initialise the DirectX window. 26 | * 27 | * @return The state after trying to initialise the window. 28 | */ 29 | bool DirectXWindow::Init() { 30 | return Window::Init(); 31 | } 32 | 33 | /** 34 | * Update the DirectX window. 35 | * 36 | * @param dt The period of time after which the window should update. 37 | */ 38 | void DirectXWindow::Update(float dt) { 39 | // @TODO: Write the Update function, given delta t. 40 | } 41 | 42 | /** 43 | * Render the DirectX window. 44 | * 45 | * @param dt The period of time after which the window should render. 46 | */ 47 | void DirectXWindow::Render(float dt) { 48 | m_pImmediateContext->ClearRenderTargetView(m_pRenderTargetView, DirectX::Colors::CornflowerBlue); 49 | m_pSwapChain->Present(0, 0); 50 | } 51 | 52 | /** 53 | * Default destructor. 54 | */ 55 | DirectXWindow::~DirectXWindow() {} 56 | 57 | } -------------------------------------------------------------------------------- /DirectXWindow/DirectXWindow.h: -------------------------------------------------------------------------------- 1 | /** 2 | * DirectXWindow.h 3 | * Purpose: Build a DirectX managed window. 4 | * 5 | * @author Raul Butuc 6 | * @version 1.0.1 07/03/2015 7 | */ 8 | 9 | #pragma once 10 | 11 | #include "Window.h" 12 | 13 | namespace DirectXApplication { 14 | 15 | class DirectXWindow : public Window { 16 | 17 | public: 18 | DirectXWindow(HINSTANCE, UINT, UINT, string); 19 | bool Init() override; 20 | void Update(float) override; 21 | void Render(float) override; 22 | ~DirectXWindow(); 23 | 24 | }; 25 | 26 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # DirectX-Application 2 | Building a basic DirectX11 application 3 | -------------------------------------------------------------------------------- /StringCoverter/StringConverter.h: -------------------------------------------------------------------------------- 1 | /** 2 | * StringConverter.h 3 | * Purpose: Enable easy conversion from string to lpConstWideStr and other string types. 4 | * 5 | * @author Raul Butuc 6 | * @version 1.0.1 07/03/2015 7 | */ 8 | 9 | #pragma once 10 | 11 | #define WIN32_LEAN_AND_MEAN 12 | #include 13 | #include 14 | 15 | using std::string; 16 | 17 | namespace StringHelper { 18 | 19 | template 20 | class StringConverter { 21 | 22 | public: 23 | static StrT convert(StrS); 24 | 25 | }; 26 | 27 | /** 28 | * Convert a string of type StrS to a string of type StrT. 29 | * 30 | * @param str The string of type StrS that is to be converted. 31 | * @return The converted string into the desired format (long pointer constant type assumed). 32 | * 33 | */ 34 | template 35 | StrT StringConverter::convert(StrS str) { 36 | wchar_t* wString = new wchar_t[2 * strlen(str.c_str())]; 37 | MultiByteToWideChar(CP_ACP, 0, str.c_str(), -1, wString, 2 * strlen(str.c_str())); 38 | 39 | return wString; 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /Window/Window.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Window.cpp 3 | * Purpose: Build a DirectX supported WIN32 window. 4 | * 5 | * @author Raul Butuc 6 | * @version 1.0.2 07/03/2015 7 | */ 8 | 9 | #include "Window.h" 10 | 11 | namespace DirectXApplication { 12 | 13 | // Used to forward messages to user defined procedure fuction. 14 | Window* g_pApp = nullptr; 15 | 16 | /** 17 | * Constructor for a window. 18 | * 19 | * @param hInstance The current instance handler. 20 | * @param ClientWidth The width of the client. 21 | * @param ClientHeight The height of the client. 22 | * @param AppTitle The title for the window. 23 | */ 24 | Window::Window(HINSTANCE hInstance, UINT ClientWidth, UINT ClientHeight, string AppTitle) { 25 | m_hAppInstance = hInstance; 26 | m_hAppWnd = NULL; 27 | m_ClientWidth = ClientWidth; 28 | m_ClientHeight = ClientHeight; 29 | m_AppTitle = AppTitle; 30 | m_WndStyle = WS_OVERLAPPEDWINDOW; 31 | g_pApp = this; 32 | 33 | m_pDevice = nullptr; 34 | m_pImmediateContext = nullptr; 35 | m_pRenderTargetView = nullptr; 36 | m_pSwapChain = nullptr; 37 | } 38 | 39 | /** 40 | * Run the window and fetch the window message as long as not being told otherwise. 41 | * Main application loop. 42 | * 43 | * @return An integer representing the state message. 44 | */ 45 | int Window::Run() { 46 | MSG msg = { 0 }; 47 | 48 | while (WM_QUIT != msg.message) { 49 | if (PeekMessage(&msg, NULL, NULL, NULL, PM_REMOVE)) { 50 | TranslateMessage(&msg); 51 | DispatchMessage(&msg); 52 | } 53 | else { 54 | Update(0.0f); 55 | Render(0.0f); 56 | } 57 | } 58 | 59 | return static_cast(msg.wParam); 60 | } 61 | 62 | /** 63 | * Framework method that initialises the window. 64 | * 65 | * @return A boolean representing the success/failure state received after executing the init methods. 66 | */ 67 | bool Window::Init() { 68 | // Initialise window. 69 | if (!InitWindow()) { 70 | return false; 71 | } 72 | 73 | // Initialise DirectX window. 74 | if (!InitDirect3D()) { 75 | return false; 76 | } 77 | 78 | return true; 79 | } 80 | 81 | /** 82 | * Windows message procedure method. 83 | * 84 | * @param hwnd Current window handler. 85 | * @param msg The windows message. 86 | * @param wParam A message parameter. 87 | * @param lParam A message parameter. 88 | * @return A long pointer, either nullptr or the result obtained from the default window procedure. 89 | */ 90 | LRESULT Window::MsgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { 91 | switch (msg) { 92 | case WM_DESTROY: 93 | PostQuitMessage(0); 94 | return 0; 95 | 96 | default: 97 | return DefWindowProc(hwnd, msg, wParam, lParam); 98 | } 99 | } 100 | 101 | /** 102 | * Windows callback message procedure method. 103 | * 104 | * @param hwnd Current window handler. 105 | * @param msg The windows message. 106 | * @param wParam A message parameter. 107 | * @param lParam A message parameter. 108 | * @return A long pointer, either nullptr or the result obtained from the default window procedure. 109 | */ 110 | LRESULT CALLBACK MainWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { 111 | if (g_pApp) { 112 | return g_pApp->MsgProc(hwnd, msg, wParam, lParam); 113 | } 114 | 115 | return DefWindowProc(hwnd, msg, wParam, lParam); 116 | } 117 | 118 | /** 119 | * Destructor. Deallocate all the memory used. 120 | */ 121 | Window::~Window() { 122 | if (m_pImmediateContext) { 123 | m_pImmediateContext->ClearState(); 124 | } 125 | 126 | MemoryManagement::SafeRelease(m_pRenderTargetView); 127 | MemoryManagement::SafeRelease(m_pSwapChain); 128 | MemoryManagement::SafeRelease(m_pImmediateContext); 129 | MemoryManagement::SafeRelease(m_pDevice); 130 | } 131 | 132 | /** 133 | * First part of the main framework method that initialises the application window. 134 | * Deals with the main window display part. 135 | * 136 | * @return A boolean representing the success/failure state received after attempting to initialise the window. 137 | */ 138 | bool Window::InitWindow() { 139 | WNDCLASSEX wcex; 140 | ZeroMemory(&wcex, sizeof(WNDCLASSEX)); 141 | 142 | wcex.cbClsExtra = 0; 143 | wcex.cbWndExtra = 0; 144 | wcex.cbSize = sizeof(WNDCLASSEX); 145 | wcex.style = CS_HREDRAW | CS_VREDRAW; 146 | wcex.hInstance = m_hAppInstance; 147 | wcex.lpfnWndProc = MainWndProc; 148 | wcex.hIcon = LoadIcon(NULL, IDI_APPLICATION); 149 | wcex.hIconSm = LoadIcon(NULL, IDI_APPLICATION); 150 | wcex.hCursor = LoadCursor(NULL, IDC_ARROW); 151 | wcex.hbrBackground = (HBRUSH)GetStockObject(NULL_BRUSH); 152 | wcex.lpszMenuName = NULL; 153 | wcex.lpszClassName = StringConverter::convert("DXAPPWNDCLASS");; 154 | 155 | if (!RegisterClassEx(&wcex)) { 156 | OutputDebugString(StringConverter::convert("Failed to create window class\n")); 157 | 158 | return false; 159 | } 160 | 161 | RECT rectangle = { 0, 0, m_ClientWidth, m_ClientHeight }; 162 | AdjustWindowRect(&rectangle, m_WndStyle, FALSE); 163 | UINT width = rectangle.right - rectangle.left; 164 | UINT height = rectangle.bottom - rectangle.top; 165 | 166 | UINT xCoord = GetSystemMetrics(SM_CXSCREEN) / 2 - width / 2; 167 | UINT yCoord = GetSystemMetrics(SM_CYSCREEN) / 2 - height / 2; 168 | 169 | LPCWSTR lpClassName = StringConverter::convert("DXAPPWNDCLASS"); 170 | LPCWSTR lpWindowName = StringConverter::convert(m_AppTitle); 171 | 172 | m_hAppWnd = CreateWindow(lpClassName, lpWindowName, m_WndStyle, 173 | xCoord, yCoord, width, height, NULL, NULL, m_hAppInstance, NULL); 174 | 175 | if (!m_hAppWnd) { 176 | OutputDebugString(StringConverter::convert("Failed to create window\n")); 177 | 178 | return false; 179 | } 180 | 181 | ShowWindow(m_hAppWnd, SW_SHOW); 182 | 183 | return true; 184 | } 185 | 186 | /** 187 | * Second part of the main framework method that initialises the application window. 188 | * Deals with the DirectX display part. 189 | * 190 | * @return A boolean representing the success/failure state received after attempting to initialise the window. 191 | */ 192 | bool Window::InitDirect3D() { 193 | UINT createDeviceFlags = 0; 194 | 195 | #ifdef _DEBUG 196 | createDeviceFlags |= D3D11_CREATE_DEVICE_DEBUG; 197 | #endif 198 | 199 | D3D_DRIVER_TYPE driverTypes[] = { 200 | D3D_DRIVER_TYPE_HARDWARE, 201 | D3D_DRIVER_TYPE_WARP, 202 | D3D_DRIVER_TYPE_REFERENCE 203 | }; 204 | UINT numDriverTypes = ARRAYSIZE(driverTypes); 205 | 206 | D3D_FEATURE_LEVEL featureLevels[] = { 207 | D3D_FEATURE_LEVEL_11_0, 208 | D3D_FEATURE_LEVEL_10_1, 209 | D3D_FEATURE_LEVEL_10_0, 210 | D3D_FEATURE_LEVEL_9_3 211 | }; 212 | UINT numFeatureLevels = ARRAYSIZE(featureLevels); 213 | 214 | DXGI_SWAP_CHAIN_DESC swapDesc; 215 | ZeroMemory(&swapDesc, sizeof(DXGI_SWAP_CHAIN_DESC)); 216 | swapDesc.BufferCount = 1; 217 | swapDesc.BufferDesc.Width = m_ClientWidth; 218 | swapDesc.BufferDesc.Height = m_ClientHeight; 219 | swapDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; 220 | swapDesc.BufferDesc.RefreshRate.Numerator = 60; 221 | swapDesc.BufferDesc.RefreshRate.Denominator = 1; 222 | swapDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; 223 | swapDesc.OutputWindow = m_hAppWnd; 224 | swapDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; 225 | swapDesc.Windowed = true; 226 | swapDesc.SampleDesc.Count = 1; 227 | swapDesc.SampleDesc.Quality = 0; 228 | swapDesc.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH; 229 | 230 | HRESULT result; 231 | for (int id = 0; id < numDriverTypes; ++id) { 232 | result = D3D11CreateDeviceAndSwapChain(NULL, driverTypes[id], NULL, createDeviceFlags, 233 | featureLevels, numFeatureLevels, D3D11_SDK_VERSION, &swapDesc, &m_pSwapChain, &m_pDevice, 234 | &m_FeatureLevel, &m_pImmediateContext); 235 | 236 | if (SUCCEEDED(result)) { 237 | m_DriverType = driverTypes[id]; 238 | break; 239 | } 240 | } 241 | 242 | if (FAILED(result)) { 243 | OutputDebugString(StringConverter::convert("Failed to create device and swap chain.")); 244 | 245 | return false; 246 | } 247 | 248 | ID3D11Texture2D* m_pBackBufferTex = 0; 249 | m_pSwapChain->GetBuffer(NULL, __uuidof(ID3D11Texture2D), reinterpret_cast(&m_pBackBufferTex)); 250 | m_pDevice->CreateRenderTargetView(m_pBackBufferTex, nullptr, &m_pRenderTargetView); 251 | 252 | m_pImmediateContext->OMSetRenderTargets(1, &m_pRenderTargetView, nullptr); 253 | 254 | m_Viewport.Width = static_cast(m_ClientWidth); 255 | m_Viewport.Height = static_cast(m_ClientHeight); 256 | m_Viewport.TopLeftX = 0; 257 | m_Viewport.TopLeftY = 0; 258 | m_Viewport.MinDepth = 0.0f; 259 | m_Viewport.MaxDepth = 1.0f; 260 | 261 | m_pImmediateContext->RSSetViewports(1, &m_Viewport); 262 | 263 | return true; 264 | } 265 | 266 | } -------------------------------------------------------------------------------- /Window/Window.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Window.h 3 | * Purpose: Build a DirectX supported WIN32 window. 4 | * 5 | * @author Raul Butuc 6 | * @version 1.0.2 07/03/2015 7 | */ 8 | 9 | #pragma once 10 | 11 | #define WIN32_LEAN_AND_MEAN 12 | #include 13 | #include 14 | #include "StringConverter.h" 15 | #include "DirectXUtilities.h" 16 | 17 | using StringHelper::StringConverter; 18 | 19 | namespace DirectXApplication { 20 | 21 | class Window { 22 | 23 | public: 24 | Window(HINSTANCE, UINT, UINT, string); 25 | int Run(); 26 | virtual bool Init(); 27 | virtual void Update(float) = 0; 28 | virtual void Render(float) = 0; 29 | virtual LRESULT MsgProc(HWND, UINT, WPARAM, LPARAM); 30 | virtual ~Window(); 31 | 32 | protected: 33 | // Win32 attributes declaration. 34 | HWND m_hAppWnd; 35 | HINSTANCE m_hAppInstance; 36 | UINT m_ClientWidth; 37 | UINT m_ClientHeight; 38 | string m_AppTitle; 39 | DWORD m_WndStyle; 40 | 41 | // DirectX11 attributes declaration. 42 | ID3D11Device* m_pDevice; 43 | ID3D11DeviceContext* m_pImmediateContext; 44 | IDXGISwapChain* m_pSwapChain; 45 | ID3D11RenderTargetView* m_pRenderTargetView; 46 | D3D_DRIVER_TYPE m_DriverType; 47 | D3D_FEATURE_LEVEL m_FeatureLevel; 48 | D3D11_VIEWPORT m_Viewport; 49 | 50 | // Win32 init fuction. 51 | bool InitWindow(); 52 | 53 | // DirectX11 init function. 54 | bool InitDirect3D(); 55 | }; 56 | 57 | } -------------------------------------------------------------------------------- /winmain.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * winmain.cpp 3 | * Purpose: Run the application and test its functionality. 4 | * 5 | * @author Raul Butuc 6 | * @version 1.0.1 07/03/2015 7 | */ 8 | 9 | #include "DirectXWindow.h" 10 | 11 | int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd) { 12 | DirectXApplication::DirectXWindow DXApp(hInstance, 1280, 720, "DirectX11 Application"); 13 | 14 | if (!DXApp.Init()) { 15 | return 1; 16 | } 17 | 18 | return DXApp.Run(); 19 | } --------------------------------------------------------------------------------