#include "pch.h" #include "App.h" #include using namespace $safeprojectname$; using namespace concurrency; using namespace Windows::ApplicationModel; using namespace Windows::ApplicationModel::Core; using namespace Windows::ApplicationModel::Activation; using namespace Windows::UI::Core; using namespace Windows::UI::Input; using namespace Windows::System; using namespace Windows::Foundation; using namespace Windows::Graphics::Display; using Microsoft::WRL::ComPtr; // https://go.microsoft.com/fwlink/?LinkID=613670&clcid=0x804 上介绍了“DirectX 12 应用程序”模板 // 主函数仅用于初始化我们的 IFrameworkView 类。 [Platform::MTAThread] int main(Platform::Array^) { auto direct3DApplicationSource = ref new Direct3DApplicationSource(); CoreApplication::Run(direct3DApplicationSource); return 0; } IFrameworkView^ Direct3DApplicationSource::CreateView() { return ref new App(); } App::App() : m_windowClosed(false), m_windowVisible(true) { } // 创建 IFrameworkView 时调用的第一个方法。 void App::Initialize(CoreApplicationView^ applicationView) { // 注册应用程序生命周期的事件处理程序。此示例包括 Activated,因此我们 // 可激活 CoreWindow 并开始在窗口上渲染。 applicationView->Activated += ref new TypedEventHandler(this, &App::OnActivated); CoreApplication::Suspending += ref new EventHandler(this, &App::OnSuspending); CoreApplication::Resuming += ref new EventHandler(this, &App::OnResuming); } // 创建(或重新创建) CoreWindow 对象时调用。 void App::SetWindow(CoreWindow^ window) { window->SizeChanged += ref new TypedEventHandler(this, &App::OnWindowSizeChanged); window->VisibilityChanged += ref new TypedEventHandler(this, &App::OnVisibilityChanged); window->Closed += ref new TypedEventHandler(this, &App::OnWindowClosed); DisplayInformation^ currentDisplayInformation = DisplayInformation::GetForCurrentView(); currentDisplayInformation->DpiChanged += ref new TypedEventHandler(this, &App::OnDpiChanged); currentDisplayInformation->OrientationChanged += ref new TypedEventHandler(this, &App::OnOrientationChanged); DisplayInformation::DisplayContentsInvalidated += ref new TypedEventHandler(this, &App::OnDisplayContentsInvalidated); } // 初始化场景资源或加载之前保存的应用程序状态。 void App::Load(Platform::String^ entryPoint) { if (m_main == nullptr) { m_main = std::unique_ptr<$safeprojectname$Main>(new $safeprojectname$Main()); } } // 将在窗口处于活动状态后调用此方法。 void App::Run() { while (!m_windowClosed) { if (m_windowVisible) { CoreWindow::GetForCurrentThread()->Dispatcher->ProcessEvents(CoreProcessEventsOption::ProcessAllIfPresent); auto commandQueue = GetDeviceResources()->GetCommandQueue(); PIXBeginEvent(commandQueue, 0, L"Update"); { m_main->Update(); } PIXEndEvent(commandQueue); PIXBeginEvent(commandQueue, 0, L"Render"); { if (m_main->Render()) { GetDeviceResources()->Present(); } } PIXEndEvent(commandQueue); } else { CoreWindow::GetForCurrentThread()->Dispatcher->ProcessEvents(CoreProcessEventsOption::ProcessOneAndAllPending); } } } // IFrameworkView 所必需的。 // 终止事件不会导致调用 Uninitialize。如果在应用程序在前台运行时销毁 IFrameworkView // 类,则将调用该方法。 void App::Uninitialize() { } // 应用程序生命周期事件处理程序。 void App::OnActivated(CoreApplicationView^ applicationView, IActivatedEventArgs^ args) { // Run() 在 CoreWindow 激活前将不会开始。 CoreWindow::GetForCurrentThread()->Activate(); } void App::OnSuspending(Platform::Object^ sender, SuspendingEventArgs^ args) { // 在请求延期后异步保存应用程序状态。保留延期 // 表示应用程序正忙于执行挂起操作。 // 请注意,延期不是无限期的。在大约五秒后, // 将强制应用程序退出。 SuspendingDeferral^ deferral = args->SuspendingOperation->GetDeferral(); create_task([this, deferral]() { m_main->OnSuspending(); deferral->Complete(); }); } void App::OnResuming(Platform::Object^ sender, Platform::Object^ args) { // 还原在挂起时卸载的任何数据或状态。默认情况下, // 在从挂起中恢复时,数据和状态会持续保留。请注意, // 如果之前已终止应用程序,则不会发生此事件。 m_main->OnResuming(); } // 窗口事件处理程序。 void App::OnWindowSizeChanged(CoreWindow^ sender, WindowSizeChangedEventArgs^ args) { GetDeviceResources()->SetLogicalSize(Size(sender->Bounds.Width, sender->Bounds.Height)); m_main->OnWindowSizeChanged(); } void App::OnVisibilityChanged(CoreWindow^ sender, VisibilityChangedEventArgs^ args) { m_windowVisible = args->Visible; } void App::OnWindowClosed(CoreWindow^ sender, CoreWindowEventArgs^ args) { m_windowClosed = true; } // DisplayInformation 事件处理程序。 void App::OnDpiChanged(DisplayInformation^ sender, Object^ args) { // 注意: 在此处检索到的 LogicalDpi 值可能与应用的有效 DPI 不匹配 // 如果正在针对高分辨率设备对它进行缩放。在 DeviceResources 上设置 DPI 后, // 应始终使用 GetDpi 方法进行检索。 // 有关详细信息,请参阅 DeviceResources.cpp。 GetDeviceResources()->SetDpi(sender->LogicalDpi); m_main->OnWindowSizeChanged(); } void App::OnOrientationChanged(DisplayInformation^ sender, Object^ args) { GetDeviceResources()->SetCurrentOrientation(sender->CurrentOrientation); m_main->OnWindowSizeChanged(); } void App::OnDisplayContentsInvalidated(DisplayInformation^ sender, Object^ args) { GetDeviceResources()->ValidateDevice(); } std::shared_ptr App::GetDeviceResources() { if (m_deviceResources != nullptr && m_deviceResources->IsDeviceRemoved()) { // 必须先释放对现有 D3D 设备的所有引用,然后才能 // 创建新设备。 m_deviceResources = nullptr; m_main->OnDeviceRemoved(); #if defined(_DEBUG) ComPtr dxgiDebug; if (SUCCEEDED(DXGIGetDebugInterface1(0, IID_PPV_ARGS(&dxgiDebug)))) { dxgiDebug->ReportLiveObjects(DXGI_DEBUG_ALL, DXGI_DEBUG_RLO_FLAGS(DXGI_DEBUG_RLO_SUMMARY | DXGI_DEBUG_RLO_IGNORE_INTERNAL)); } #endif } if (m_deviceResources == nullptr) { m_deviceResources = std::make_shared(); m_deviceResources->SetWindow(CoreWindow::GetForCurrentThread()); m_main->CreateRenderers(m_deviceResources); } return m_deviceResources; }