Xbox-ATG-Samples/PCSamples/Raytracing/SimpleRaytracingTriangle_PC12/Main.cpp

302 строки
7.9 KiB
C++

//--------------------------------------------------------------------------------------
// Main.cpp
//
// Entry point for Windows desktop application.
//
// Advanced Technology Group (ATG)
// Copyright (C) Microsoft Corporation. All rights reserved.
//--------------------------------------------------------------------------------------
#include "pch.h"
#include "SimpleRaytracingTriangle_PC12.h"
using namespace DirectX;
namespace
{
std::unique_ptr<Sample> g_sample;
};
LPCWSTR g_szAppName = L"SimpleRaytracingTriangle_PC12";
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
// Indicates to hybrid graphics systems to prefer the discrete part by default
extern "C"
{
__declspec(dllexport) DWORD NvOptimusEnablement = 0x00000001;
__declspec(dllexport) int AmdPowerXpressRequestHighPerformance = 1;
}
// Entry point
int WINAPI wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE, _In_ LPWSTR, _In_ int nCmdShow)
{
if (!XMVerifyCPUSupport())
return 1;
Microsoft::WRL::Wrappers::RoInitializeWrapper initialize(RO_INIT_MULTITHREADED);
if (FAILED(initialize))
return 1;
g_sample = std::make_unique<Sample>();
// Register class and create window
{
// Register class
WNDCLASSEXW wcex = {};
wcex.cbSize = sizeof(WNDCLASSEXW);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = WndProc;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIconW(hInstance, L"IDI_ICON");
wcex.hCursor = LoadCursorW(nullptr, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wcex.lpszClassName = L"SimpleRaytracingTriangleWindowClass";
wcex.hIconSm = LoadIconW(wcex.hInstance, L"IDI_ICON");
if (!RegisterClassExW(&wcex))
return 1;
// Create window
int w, h;
g_sample->GetDefaultSize(w, h);
RECT rc = { 0, 0, static_cast<LONG>(w), static_cast<LONG>(h) };
AdjustWindowRect(&rc, WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU, FALSE);
HWND hwnd = CreateWindowExW(0, L"SimpleRaytracingTriangleWindowClass", g_szAppName,
WS_OVERLAPPED | WS_CAPTION | WS_CAPTION | WS_SYSMENU,
CW_USEDEFAULT, CW_USEDEFAULT, rc.right - rc.left, rc.bottom - rc.top, nullptr, nullptr, hInstance,
nullptr);
if (!hwnd)
return 1;
ShowWindow(hwnd, nCmdShow);
SetWindowLongPtr(hwnd, GWLP_USERDATA, reinterpret_cast<LONG_PTR>(g_sample.get()));
GetClientRect(hwnd, &rc);
g_sample->Initialize(hwnd, rc.right - rc.left, rc.bottom - rc.top);
}
// Main message loop
MSG msg = {};
while (WM_QUIT != msg.message)
{
if (PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else
{
g_sample->Tick();
}
}
g_sample.reset();
CoUninitialize();
return (int)msg.wParam;
}
// Windows procedure
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
PAINTSTRUCT ps;
HDC hdc;
static bool s_in_sizemove = false;
static bool s_in_suspend = false;
static bool s_minimized = false;
static bool s_fullscreen = false;
// Set s_fullscreen to true if defaulting to fullscreen.
auto sample = reinterpret_cast<Sample*>(GetWindowLongPtr(hWnd, GWLP_USERDATA));
switch (message)
{
case WM_PAINT:
if (s_in_sizemove && sample)
{
sample->Tick();
}
else
{
hdc = BeginPaint(hWnd, &ps);
EndPaint(hWnd, &ps);
}
break;
case WM_MOVE:
if (sample)
{
sample->OnWindowMoved();
}
break;
case WM_SIZE:
if (wParam == SIZE_MINIMIZED)
{
if (!s_minimized)
{
s_minimized = true;
if (!s_in_suspend && sample)
sample->OnSuspending();
s_in_suspend = true;
}
}
else if (s_minimized)
{
s_minimized = false;
if (s_in_suspend && sample)
sample->OnResuming();
s_in_suspend = false;
}
else if (!s_in_sizemove && sample)
{
sample->OnWindowSizeChanged(LOWORD(lParam), HIWORD(lParam));
}
break;
case WM_ENTERSIZEMOVE:
s_in_sizemove = true;
break;
case WM_EXITSIZEMOVE:
s_in_sizemove = false;
if (sample)
{
RECT rc;
GetClientRect(hWnd, &rc);
sample->OnWindowSizeChanged(rc.right - rc.left, rc.bottom - rc.top);
}
break;
case WM_GETMINMAXINFO:
{
auto info = reinterpret_cast<MINMAXINFO*>(lParam);
info->ptMinTrackSize.x = 320;
info->ptMinTrackSize.y = 200;
}
break;
case WM_ACTIVATEAPP:
if (sample)
{
Keyboard::ProcessMessage(message, wParam, lParam);
Mouse::ProcessMessage(message, wParam, lParam);
if (wParam)
{
sample->OnActivated();
}
else
{
sample->OnDeactivated();
}
}
break;
case WM_POWERBROADCAST:
switch (wParam)
{
case PBT_APMQUERYSUSPEND:
if (!s_in_suspend && sample)
sample->OnSuspending();
s_in_suspend = true;
return TRUE;
case PBT_APMRESUMESUSPEND:
if (!s_minimized)
{
if (s_in_suspend && sample)
sample->OnResuming();
s_in_suspend = false;
}
return TRUE;
}
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
case WM_ACTIVATE:
case WM_INPUT:
case WM_MOUSEMOVE:
case WM_LBUTTONDOWN:
case WM_LBUTTONUP:
case WM_RBUTTONDOWN:
case WM_RBUTTONUP:
case WM_MBUTTONDOWN:
case WM_MBUTTONUP:
case WM_MOUSEWHEEL:
case WM_XBUTTONDOWN:
case WM_XBUTTONUP:
case WM_MOUSEHOVER:
Mouse::ProcessMessage(message, wParam, lParam);
break;
case WM_KEYDOWN:
case WM_KEYUP:
case WM_SYSKEYUP:
Keyboard::ProcessMessage(message, wParam, lParam);
break;
case WM_SYSKEYDOWN:
if (wParam == VK_RETURN && (lParam & 0x60000000) == 0x20000000)
{
// Implements the classic ALT+ENTER fullscreen toggle
if (s_fullscreen)
{
SetWindowLongPtr(hWnd, GWL_STYLE, WS_OVERLAPPEDWINDOW);
SetWindowLongPtr(hWnd, GWL_EXSTYLE, 0);
int width = 800;
int height = 600;
if (sample)
sample->GetDefaultSize(width, height);
ShowWindow(hWnd, SW_SHOWNORMAL);
SetWindowPos(hWnd, HWND_TOP, 0, 0, width, height, SWP_NOMOVE | SWP_NOZORDER | SWP_FRAMECHANGED);
}
else
{
SetWindowLongPtr(hWnd, GWL_STYLE, 0);
SetWindowLongPtr(hWnd, GWL_EXSTYLE, WS_EX_TOPMOST);
SetWindowPos(hWnd, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED);
ShowWindow(hWnd, SW_SHOWMAXIMIZED);
}
s_fullscreen = !s_fullscreen;
}
Keyboard::ProcessMessage(message, wParam, lParam);
break;
case WM_MOUSEACTIVATE:
// When you click activate the window, we want Mouse to ignore it.
return MA_ACTIVATEANDEAT;
case WM_MENUCHAR:
// A menu is active and the user presses a key that does not correspond
// to any mnemonic or accelerator key. Ignore so we don't produce an error beep.
return MAKELRESULT(0, MNC_CLOSE);
}
return DefWindowProc(hWnd, message, wParam, lParam);
}
// Exit helper
void ExitSample() noexcept
{
PostQuitMessage(0);
}