#pragma once
#define UNICODE
//Direct3D lib
#include
#include
#pragma comment(lib, "d3d9.lib")
#pragma comment(lib, "d3dx9.lib")
//Default lib
#include
#include
#include
#pragma comment(lib, "winmm.lib")
namespace Clear
{
template
void SafeRelease(T t)
{
if (t)
{
t->Release();
t = nullptr;
}
}
template
void SafeDelete(T t)
{
if (t)
{
delete t;
t = nullptr;
}
}
}
class DXApp
{
public:
DXApp(HINSTANCE hInstance = nullptr);
virtual ~DXApp();
bool InitDXApp(const WCHAR\* title, UINT width, UINT height, bool fullscreen);
bool InitWindow(const WCHAR\* title, UINT width, UINT height, bool fullscreen);
bool InitDirect3D\_9();
virtual LRESULT MsgProc(HWND hWnd, UINT Message, WPARAM wParam, LPARAM lParam);
virtual int Run();
void RenderShell();
virtual void Render() = ;
virtual void Update() = ;
virtual void OnLostDevice() = ;
virtual void OnResetDevice() = ;
protected:
HINSTANCE m\_AppInstance;
HWND m\_hWindowedHWND;
WCHAR m\_strAppTitle\[\];
UINT m\_windowWidth;
UINT m\_windowHeight;
bool m\_bFullScreen;
bool m\_bLostDevice;
//Direct3D\_9 properties
IDirect3D9\* m\_pD3D;
D3DPRESENT\_PARAMETERS m\_PresentParamenters;
IDirect3DDevice9\* m\_pD3Ddevice;
};
DXApp.cpp
#include "DXApp.h"
//Store DXApp global pointer
namespace Global
{
DXApp* g_pDxapp = nullptr;
}
LRESULT CALLBACK MainProc(HWND hWnd, UINT Message, WPARAM wParam, LPARAM lParam)
{
if (Global::g_pDxapp)
{
return Global::g_pDxapp->MsgProc(hWnd, Message, wParam, lParam);
}
else
{
return DefWindowProc(hWnd, Message, wParam, lParam);
}
}
DXApp::DXApp(HINSTANCE hInstance)
{
m_AppInstance = hInstance;
m_hWindowedHWND = nullptr;
Global::g_pDxapp = this;
}
DXApp::~DXApp()
{
Clear::SafeRelease(m_pD3D);
Clear::SafeRelease(m_pD3Ddevice);
}
bool DXApp::InitDXApp(const WCHAR* title, UINT width, UINT height, bool fullscreen)
{
if(!InitWindow(title, width, height, fullscreen))
return false;
if (!InitDirect3D_9())
return false;
return true;
}
bool DXApp::InitWindow(const WCHAR* title, UINT width, UINT height, bool fullscreen)
{
// Initialize window's properties
wsprintfW(m_strAppTitle, title);
m_windowWidth = width;
m_windowHeight = height;
m_bFullScreen = fullscreen;
m_bLostDevice = false;
const WCHAR\* CLASSNAME = L"DEMOCLASS";
WNDCLASSEX wcex;
ZeroMemory(&wcex, sizeof(wcex));
wcex.style = CS\_VREDRAW | CS\_HREDRAW;
wcex.cbClsExtra = ;
wcex.cbSize = sizeof(wcex);
wcex.cbWndExtra = ;
wcex.hbrBackground = nullptr;
wcex.hCursor = LoadCursor(m\_AppInstance, IDC\_ARROW);
wcex.hIcon = LoadIcon(m\_AppInstance, IDI\_APPLICATION);
wcex.hIconSm = LoadIcon(m\_AppInstance, IDI\_APPLICATION);
wcex.hInstance = m\_AppInstance;
wcex.lpfnWndProc = MainProc;
wcex.lpszClassName = CLASSNAME;
wcex.lpszMenuName = nullptr;
if (!RegisterClassEx(&wcex))
{
OutputDebugString(L"DXApp::InitWindow: RegisterClassEx()failed!");
return false;
}
// adjust window size
RECT adjR;
SetRect(&adjR, , , m\_windowWidth, m\_windowHeight);
AdjustWindowRect(&adjR, WS\_OVERLAPPEDWINDOW, false);
UINT w = adjR.right - adjR.left;
UINT h = adjR.bottom - adjR.top;
UINT x = GetSystemMetrics(SM\_CXSCREEN) / - w / ;
UINT y = GetSystemMetrics(SM\_CYSCREEN) / - h / ;
m\_hWindowedHWND = CreateWindow(CLASSNAME, m\_strAppTitle, WS\_OVERLAPPEDWINDOW, x, y, w, h, nullptr, nullptr, m\_AppInstance, nullptr);
if (!m\_hWindowedHWND)
{
OutputDebugString(L"DXApp::InitWindow: CreateWindow()failed!");
return false;
}
ShowWindow(m\_hWindowedHWND, SW\_SHOWDEFAULT);
return true;
}
bool DXApp::InitDirect3D_9()
{
m_pD3D = Direct3DCreate9(D3D_SDK_VERSION);
D3DCAPS9 d3dcaps;
int vertex\_proc = ;
m\_pD3D->GetDeviceCaps(D3DADAPTER\_DEFAULT, D3DDEVTYPE\_HAL, &d3dcaps);
if (d3dcaps.DevCaps & D3DDEVCAPS\_HWTRANSFORMANDLIGHT)
{
vertex\_proc = D3DCREATE\_HARDWARE\_VERTEXPROCESSING;
}
else
{
vertex\_proc = D3DCREATE\_SOFTWARE\_VERTEXPROCESSING;
}
ZeroMemory(&m\_PresentParamenters, sizeof(m\_PresentParamenters));
m\_PresentParamenters.BackBufferCount = ;
m\_PresentParamenters.BackBufferWidth = m\_windowWidth;
m\_PresentParamenters.BackBufferHeight = m\_windowHeight;
m\_PresentParamenters.BackBufferFormat = D3DFMT\_A8R8G8B8;
m\_PresentParamenters.EnableAutoDepthStencil = true;
m\_PresentParamenters.AutoDepthStencilFormat = D3DFMT\_D24S8;
m\_PresentParamenters.hDeviceWindow = m\_hWindowedHWND;
m\_PresentParamenters.Flags = ;
m\_PresentParamenters.SwapEffect = D3DSWAPEFFECT\_DISCARD;
m\_PresentParamenters.FullScreen\_RefreshRateInHz = D3DPRESENT\_RATE\_DEFAULT;
m\_PresentParamenters.MultiSampleQuality = ;
m\_PresentParamenters.MultiSampleType = D3DMULTISAMPLE\_NONE;
m\_PresentParamenters.Windowed = true;
m\_PresentParamenters.PresentationInterval = D3DPRESENT\_INTERVAL\_IMMEDIATE;
// create device
if (FAILED(m\_pD3D->CreateDevice(D3DADAPTER\_DEFAULT, D3DDEVTYPE\_HAL, m\_hWindowedHWND, vertex\_proc, &m\_PresentParamenters, &m\_pD3Ddevice)))
{
OutputDebugString(L"DXApp::InitDirect3D\_9: CreateDevice()failed!");
return false;
}
return true;
}
LRESULT DXApp::MsgProc(HWND hWnd, UINT Message, WPARAM wParam, LPARAM lParam)
{
switch (Message)
{
case WM_KEYDOWN:
if (wParam == VK_ESCAPE)
DestroyWindow(hWnd);
return ;
case WM_DESTROY:
PostQuitMessage();
return ;
}
return DefWindowProc(hWnd, Message, wParam, lParam);
}
int DXApp::Run()
{
MSG msg;
ZeroMemory(&msg, sizeof(msg));
while (msg.message != WM_QUIT)
{
if (PeekMessage(&msg, nullptr, , , PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else
{
RenderShell();
}
}
return (int)msg.wParam;
}
void DXApp::RenderShell()
{
if (m_bLostDevice)
{
HRESULT hr = m_pD3Ddevice->TestCooperativeLevel();
if (hr == D3DERR_DEVICELOST)
{
OnLostDevice();
return;
}
if (hr == D3DERR_DEVICENOTRESET)
{
m_pD3Ddevice->Reset(&m_PresentParamenters);
OnResetDevice();
return;
}
m\_bLostDevice = false;
}
m\_pD3Ddevice->Clear(, nullptr, D3DCLEAR\_TARGET | D3DCLEAR\_STENCIL | D3DCLEAR\_ZBUFFER, D3DCOLOR\_XRGB(, , ), .f, 0L);
m\_pD3Ddevice->BeginScene();
Update();
Render();
m\_pD3Ddevice->EndScene();
HRESULT hr = m\_pD3Ddevice->Present(, , , );
if (hr == D3DERR\_DEVICELOST)
m\_bLostDevice = true;
}
手机扫一扫
移动阅读更方便
你可能感兴趣的文章