DX11 Anwendung - Quellcode (C++)
<!-- #include <windows.h> -->
<!-- #include <string> -->
<!-- #include <memory> -->
<!-- #include <chrono> -->
<!-- --- DX11 Eintritt --- -->
class DX11App {
public:
DX11App(HWND hwnd) : m_hwnd(hwnd) {}
bool Initialize() {
<!-- TODO: Device, DeviceContext, SwapChain, RenderTargetView anlegen. -->
return true;
}
void Update(float deltaTime) {
<!-- TODO: Update -->
}
void Render() {
<!-- TODO: Render -->
}
void OnResize(int width, int height) {
<!-- TODO: Resize -->
}
private:
HWND m_hwnd;
};
<!-- --- Window Class --- -->
class Window {
public:
Window(int width, int height, const std::wstring& title) {
<!-- Prüfen auf DPI, hochauflösende Monitore -->
SetProcessDPIAware();
WNDCLASS wc = {};
wc.lpfnWndProc = WndProc;
wc.hInstance = GetModuleHandle(nullptr);
wc.lpszClassName = L"WindowClass";
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
if (!RegisterClass(&wc)) {
MessageBox(nullptr, L"Fehler: RegisterClass!", L"Fehler", MB_OK);
exit(-1);
}
m_hwnd = CreateWindow(wc.lpszClassName, title.c_str(),
WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, width, height,
nullptr, nullptr, wc.hInstance, nullptr);
if (m_hwnd == nullptr) {
MessageBox(nullptr, L"Fehler: Anlage , CreateWindow!", L"Fehler", MB_OK);
exit(-1);
}
ShowWindow(m_hwnd, SW_SHOW);
}
~Window() {
<!-- angelegte Resourcen bereinigen, -->
}
void Run() {
<!-- RAII: unique_ptr , damit wir m_app auch Fehlerabruch ordentlich gelöscht -->
m_app = std::make_unique<DX11App>(m_hwnd);
if (m_app->Initialize()) {
MSG msg = {};
auto lastTime = std::chrono::high_resolution_clock::now();
float deltaTime = 0.0f;
while (msg.message != WM_QUIT) {
if (PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else {
auto currentTime = std::chrono::high_resolution_clock::now();
std::chrono::duration<float> elapsed = currentTime - lastTime;
lastTime = currentTime;
deltaTime = elapsed.count();
if (deltaTime < (1.0f / 60.0f)) {
Sleep(1);
}
m_app->Update(deltaTime);
m_app->Render();
}
}
}
else {
MessageBox(nullptr, L"Fehler Initialisierung DX11", L"Fehler", MB_ICONSTOP | MB_OK);
}
}
HWND GetHWND() const { return m_hwnd; }
private:
HWND m_hwnd;
std::unique_ptr<DX11App> m_app;
// Static WndProc
static LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
Window* pWindow = (Window*)GetWindowLongPtr(hwnd, GWLP_USERDATA); <!-- jetzt die Daten die in window.GetHWND gespeichert wurden, auslesen -->
switch (msg) {
case WM_DESTROY :
if (msg == WM_DESTROY) {
PostQuitMessage(0);
return 0;
}
break;
case WM_SIZE:
if (pWindow && pWindow->m_app) {
pWindow->m_app->OnResize((int)LOWORD(lParam), (int)HIWORD(lParam));
}
return 0;
case WM_KEYDOWN:
<!-- für Tastatureingaben -->
return 0;
}
return DefWindowProc(hwnd, msg, wParam, lParam);
}
};
int WINAPI WinMain( _In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrev, _In_ LPSTR lpCmd, _In_ int nCmdShow) {
<!-- Setzt den Window-UserData-Pointer, damit WndProc auf die Window-Instanz zugreifen kann. -->
<!-- Dies ist der korrekte Weg, um statische WndProc-Callbacks zu handhaben. -->
UNREFERENCED_PARAMETER(hInstance);
UNREFERENCED_PARAMETER(hPrev);
UNREFERENCED_PARAMETER(lpCmd);
UNREFERENCED_PARAMETER(nCmdShow);
Window window(800, 600, L"Windows Class Template");
SetWindowLongPtr(window.GetHWND(), GWLP_USERDATA, (LONG_PTR)&window);
window.Run();
return 0;
}