1 #pragma once 2 #define UNICODE 3 //Direct3D lib 4 #include<d3d9.h> 5 #include<d3dx9.h> 6 #pragma comment(lib, "d3d9.lib") 7 #pragma comment(lib, "d3dx9.lib") 8 9 //Default lib 10 #include<wchar.h> 11 #include<tchar.h> 12 #include<assert.h> 13 #pragma comment(lib, "winmm.lib") 14 15 namespace Clear 16 { 17 template<typename T> 18 void SafeRelease(T t) 19 { 20 if (t) 21 { 22 t->Release(); 23 t = nullptr; 24 } 25 } 26 template<typename T> 27 void SafeDelete(T t) 28 { 29 if (t) 30 { 31 delete t; 32 t = nullptr; 33 } 34 } 35 } 36 class DXApp 37 { 38 public: 39 40 DXApp(HINSTANCE hInstance = nullptr); 41 virtual ~DXApp(); 42 43 bool InitDXApp(const WCHAR* title, UINT width, UINT height, bool fullscreen); 44 45 bool InitWindow(const WCHAR* title, UINT width, UINT height, bool fullscreen); 46 bool InitDirect3D_9(); 47 48 virtual LRESULT MsgProc(HWND hWnd, UINT Message, WPARAM wParam, LPARAM lParam); 49 virtual int Run(); 50 void RenderShell(); 51 virtual void Render() = 0; 52 virtual void Update() = 0; 53 virtual void OnLostDevice() = 0; 54 virtual void OnResetDevice() = 0; 55 56 protected: 57 58 HINSTANCE m_AppInstance; 59 HWND m_hWindowedHWND; 60 WCHAR m_strAppTitle[128]; 61 UINT m_windowWidth; 62 UINT m_windowHeight; 63 64 bool m_bFullScreen; 65 bool m_bLostDevice; 66 67 //Direct3D_9 properties 68 IDirect3D9* m_pD3D; 69 D3DPRESENT_PARAMETERS m_PresentParamenters; 70 IDirect3DDevice9* m_pD3Ddevice; 71 72 };
DXApp.cpp
1 #include "DXApp.h" 2 3 4 //Store DXApp global pointer 5 namespace Global 6 { 7 DXApp* g_pDxapp = nullptr; 8 } 9 LRESULT CALLBACK MainProc(HWND hWnd, UINT Message, WPARAM wParam, LPARAM lParam) 10 { 11 if (Global::g_pDxapp) 12 { 13 return Global::g_pDxapp->MsgProc(hWnd, Message, wParam, lParam); 14 } 15 else 16 { 17 return DefWindowProc(hWnd, Message, wParam, lParam); 18 } 19 } 20 21 DXApp::DXApp(HINSTANCE hInstance) 22 { 23 m_AppInstance = hInstance; 24 m_hWindowedHWND = nullptr; 25 Global::g_pDxapp = this; 26 27 } 28 29 DXApp::~DXApp() 30 { 31 Clear::SafeRelease(m_pD3D); 32 Clear::SafeRelease(m_pD3Ddevice); 33 } 34 35 bool DXApp::InitDXApp(const WCHAR* title, UINT width, UINT height, bool fullscreen) 36 { 37 if(!InitWindow(title, width, height, fullscreen)) 38 return false; 39 if (!InitDirect3D_9()) 40 return false; 41 42 return true; 43 } 44 45 bool DXApp::InitWindow(const WCHAR* title, UINT width, UINT height, bool fullscreen) 46 { 47 // Initialize window's properties 48 wsprintfW(m_strAppTitle, title); 49 m_windowWidth = width; 50 m_windowHeight = height; 51 m_bFullScreen = fullscreen; 52 m_bLostDevice = false; 53 54 const WCHAR* CLASSNAME = L"DEMOCLASS"; 55 WNDCLASSEX wcex; 56 ZeroMemory(&wcex, sizeof(wcex)); 57 wcex.style = CS_VREDRAW | CS_HREDRAW; 58 wcex.cbClsExtra = 0; 59 wcex.cbSize = sizeof(wcex); 60 wcex.cbWndExtra = 0; 61 wcex.hbrBackground = nullptr; 62 wcex.hCursor = LoadCursor(m_AppInstance, IDC_ARROW); 63 wcex.hIcon = LoadIcon(m_AppInstance, IDI_APPLICATION); 64 wcex.hIconSm = LoadIcon(m_AppInstance, IDI_APPLICATION); 65 wcex.hInstance = m_AppInstance; 66 wcex.lpfnWndProc = MainProc; 67 wcex.lpszClassName = CLASSNAME; 68 wcex.lpszMenuName = nullptr; 69 if (!RegisterClassEx(&wcex)) 70 { 71 OutputDebugString(L"DXApp::InitWindow: RegisterClassEx()failed!"); 72 return false; 73 } 74 75 // adjust window size 76 RECT adjR; 77 SetRect(&adjR, 0, 0, m_windowWidth, m_windowHeight); 78 AdjustWindowRect(&adjR, WS_OVERLAPPEDWINDOW, false); 79 UINT w = adjR.right - adjR.left; 80 UINT h = adjR.bottom - adjR.top; 81 UINT x = GetSystemMetrics(SM_CXSCREEN) / 2 - w / 2; 82 UINT y = GetSystemMetrics(SM_CYSCREEN) / 2 - h / 2; 83 m_hWindowedHWND = CreateWindow(CLASSNAME, m_strAppTitle, WS_OVERLAPPEDWINDOW, x, y, w, h, nullptr, nullptr, m_AppInstance, nullptr); 84 if (!m_hWindowedHWND) 85 { 86 OutputDebugString(L"DXApp::InitWindow: CreateWindow()failed!"); 87 return false; 88 } 89 90 ShowWindow(m_hWindowedHWND, SW_SHOWDEFAULT); 91 92 return true; 93 } 94 95 bool DXApp::InitDirect3D_9() 96 { 97 m_pD3D = Direct3DCreate9(D3D_SDK_VERSION); 98 99 D3DCAPS9 d3dcaps; 100 int vertex_proc = 0; 101 m_pD3D->GetDeviceCaps(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, &d3dcaps); 102 if (d3dcaps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT) 103 { 104 vertex_proc = D3DCREATE_HARDWARE_VERTEXPROCESSING; 105 } 106 else 107 { 108 vertex_proc = D3DCREATE_SOFTWARE_VERTEXPROCESSING; 109 } 110 111 ZeroMemory(&m_PresentParamenters, sizeof(m_PresentParamenters)); 112 m_PresentParamenters.BackBufferCount = 0; 113 m_PresentParamenters.BackBufferWidth = m_windowWidth; 114 m_PresentParamenters.BackBufferHeight = m_windowHeight; 115 m_PresentParamenters.BackBufferFormat = D3DFMT_A8R8G8B8; 116 m_PresentParamenters.EnableAutoDepthStencil = true; 117 m_PresentParamenters.AutoDepthStencilFormat = D3DFMT_D24S8; 118 m_PresentParamenters.hDeviceWindow = m_hWindowedHWND; 119 m_PresentParamenters.Flags = 0; 120 m_PresentParamenters.SwapEffect = D3DSWAPEFFECT_DISCARD; 121 m_PresentParamenters.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT; 122 m_PresentParamenters.MultiSampleQuality = 0; 123 m_PresentParamenters.MultiSampleType = D3DMULTISAMPLE_NONE; 124 m_PresentParamenters.Windowed = true; 125 m_PresentParamenters.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; 126 127 // create device 128 if (FAILED(m_pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, m_hWindowedHWND, vertex_proc, &m_PresentParamenters, &m_pD3Ddevice))) 129 { 130 OutputDebugString(L"DXApp::InitDirect3D_9: CreateDevice()failed!"); 131 return false; 132 } 133 134 135 return true; 136 } 137 138 LRESULT DXApp::MsgProc(HWND hWnd, UINT Message, WPARAM wParam, LPARAM lParam) 139 { 140 switch (Message) 141 { 142 case WM_KEYDOWN: 143 if (wParam == VK_ESCAPE) 144 DestroyWindow(hWnd); 145 return 0; 146 case WM_DESTROY: 147 PostQuitMessage(0); 148 return 0; 149 } 150 151 return DefWindowProc(hWnd, Message, wParam, lParam); 152 } 153 154 int DXApp::Run() 155 { 156 MSG msg; 157 ZeroMemory(&msg, sizeof(msg)); 158 while (msg.message != WM_QUIT) 159 { 160 if (PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE)) 161 { 162 TranslateMessage(&msg); 163 DispatchMessage(&msg); 164 } 165 else 166 { 167 RenderShell(); 168 } 169 } 170 171 return (int)msg.wParam; 172 } 173 174 void DXApp::RenderShell() 175 { 176 if (m_bLostDevice) 177 { 178 HRESULT hr = m_pD3Ddevice->TestCooperativeLevel(); 179 if (hr == D3DERR_DEVICELOST) 180 { 181 OnLostDevice(); 182 return; 183 } 184 if (hr == D3DERR_DEVICENOTRESET) 185 { 186 m_pD3Ddevice->Reset(&m_PresentParamenters); 187 OnResetDevice(); 188 return; 189 } 190 191 m_bLostDevice = false; 192 } 193 m_pD3Ddevice->Clear(0, nullptr, D3DCLEAR_TARGET | D3DCLEAR_STENCIL | D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0, 40, 100), 1.f, 0L); 194 m_pD3Ddevice->BeginScene(); 195 Update(); 196 Render(); 197 m_pD3Ddevice->EndScene(); 198 HRESULT hr = m_pD3Ddevice->Present(0, 0, 0, 0); 199 if (hr == D3DERR_DEVICELOST) 200 m_bLostDevice = true; 201 }