From ee177d37df85b982d6c528a7b79e3cd9ca9749d6 Mon Sep 17 00:00:00 2001 From: Egor Yusov Date: Mon, 11 Nov 2019 07:42:14 -0800 Subject: Moved Native App from master repository --- NativeApp/src/UWP/App.cpp | 351 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 351 insertions(+) create mode 100644 NativeApp/src/UWP/App.cpp (limited to 'NativeApp/src/UWP/App.cpp') diff --git a/NativeApp/src/UWP/App.cpp b/NativeApp/src/UWP/App.cpp new file mode 100644 index 0000000..0c928eb --- /dev/null +++ b/NativeApp/src/UWP/App.cpp @@ -0,0 +1,351 @@ +/* Copyright 2015-2016 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#define NOMINIMAX +#include +#include +#include +#include + +#if defined(_DEBUG) +# include +#endif + +#include "App.h" +#include "StringTools.h" + +#include + +using namespace SampleApp; +using namespace Diligent; + +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; + + +ref class ApplicationSource sealed : IFrameworkViewSource +{ +public: + virtual IFrameworkView^ CreateView() + { + return ref new App(); + } +}; + + +// The main function is only used to initialize our IFrameworkView class. +[Platform::MTAThread] +int main(Platform::Array^) +{ + auto direct3DApplicationSource = ref new ApplicationSource(); + CoreApplication::Run(direct3DApplicationSource); + return 0; +} + +App::App() : + m_windowClosed(false), + m_windowVisible(true) +{ +} + + +// The first method called when the IFrameworkView is being created. +void App::Initialize(CoreApplicationView^ applicationView) +{ + // Register event handlers for app lifecycle. This example includes Activated, so that we + // can make the CoreWindow active and start rendering on the window. + applicationView->Activated += + ref new TypedEventHandler(this, &App::OnActivated); + + CoreApplication::Suspending += + ref new EventHandler(this, &App::OnSuspending); + + CoreApplication::Resuming += + ref new EventHandler(this, &App::OnResuming); +} + +// Called when the CoreWindow object is created (or re-created). +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); + + window->KeyDown += + ref new TypedEventHandler(this, &App::OnKeyDown); + + window->KeyUp += + ref new TypedEventHandler(this, &App::OnKeyUp); + + 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); + + if (m_Main) + { + m_Main->OnSetWindow(window); + } +} + +// Initializes scene resources, or loads a previously saved app state. +void App::Load(Platform::String^ entryPoint) +{ + if (m_Main == nullptr) + { + m_Main.reset(CreateApplication()); + m_Main->OnSetWindow(CoreWindow::GetForCurrentThread()); + } +} + +// This method is called after the window becomes active. +void App::Run() +{ + while (!m_windowClosed) + { + if (m_windowVisible) + { + CoreWindow::GetForCurrentThread()->Dispatcher->ProcessEvents(CoreProcessEventsOption::ProcessAllIfPresent); + + // Initialize device resources + GetDeviceResources(); + + //PIXBeginEvent(commandQueue, 0, L"Update"); + { + m_Main->Update(); + } + //PIXEndEvent(commandQueue); + + //PIXBeginEvent(commandQueue, 0, L"Render"); + { + m_Main->Render(); + if (m_Main->IsFrameReady()) + { + m_Main->Present(); + } + } + //PIXEndEvent(commandQueue); + } + else + { + CoreWindow::GetForCurrentThread()->Dispatcher->ProcessEvents(CoreProcessEventsOption::ProcessOneAndAllPending); + } + } +} + +// Required for IFrameworkView. +// Terminate events do not cause Uninitialize to be called. It will be called if your IFrameworkView +// class is torn down while the app is in the foreground. +void App::Uninitialize() +{ +} + +// Application lifecycle event handlers. + +void App::OnActivated(CoreApplicationView^ applicationView, IActivatedEventArgs^ args) +{ + if (args->Kind == ActivationKind::Launch) + { + LaunchActivatedEventArgs^ launchArgs = (LaunchActivatedEventArgs^)args; + auto CmdLine = Diligent::NarrowString(launchArgs->Arguments->Data()); + m_Main->ProcessCommandLine(CmdLine.c_str()); + } + + auto Title = Diligent::WidenString(m_Main->GetAppTitle()); + Windows::UI::ViewManagement::ApplicationView::GetForCurrentView()->Title = ref new Platform::String(Title.c_str()); + + // Run() won't start until the CoreWindow is activated. + CoreWindow::GetForCurrentThread()->Activate(); +} + +void App::OnSuspending(Platform::Object^ sender, SuspendingEventArgs^ args) +{ + // Save app state asynchronously after requesting a deferral. Holding a deferral + // indicates that the application is busy performing suspending operations. Be + // aware that a deferral may not be held indefinitely. After about five seconds, + // the app will be forced to exit. + SuspendingDeferral^ deferral = args->SuspendingOperation->GetDeferral(); + + create_task([this, deferral]() + { + m_Main->OnSuspending(); + deferral->Complete(); + }); +} + +void App::OnResuming(Platform::Object^ sender, Platform::Object^ args) +{ + // Restore any data or state that was unloaded on suspend. By default, data + // and state are persisted when resuming from suspend. Note that this event + // does not occur if the app was previously terminated. + + m_Main->OnResuming(); +} + +// Window event handlers. + +void App::OnWindowSizeChanged(CoreWindow^ sender, WindowSizeChangedEventArgs^ args) +{ + if (auto DeviceResources = GetDeviceResources()) + { + DeviceResources->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 event handlers. + +void App::OnDpiChanged(DisplayInformation^ sender, Object^ args) +{ + // Note: The value for LogicalDpi retrieved here may not match the effective DPI of the app + // if it is being scaled for high resolution devices. Once the DPI is set on DeviceResources, + // you should always retrieve it using the GetDpi method. + // See DeviceResources.cpp for more details. + if (auto DeviceResources = GetDeviceResources()) + { + DeviceResources->SetDpi(sender->LogicalDpi); + m_Main->OnWindowSizeChanged(); + } +} + +void App::OnOrientationChanged(DisplayInformation^ sender, Object^ args) +{ + if (auto DeviceResources = GetDeviceResources()) + { + DeviceResources->SetCurrentOrientation(sender->CurrentOrientation); + m_Main->OnWindowSizeChanged(); + } +} + +void App::OnDisplayContentsInvalidated(DisplayInformation^ sender, Object^ args) +{ + if (auto DeviceResources = GetDeviceResources()) + { + DeviceResources->ValidateDevice(); + } +} + +void App::OnKeyDown(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::KeyEventArgs^ args) +{ + auto Key = args->VirtualKey; + switch(Key) + { + case VirtualKey::Escape: + CoreApplication::Exit(); + break; + + case VirtualKey::Enter: + if(m_bShiftPressed) + { + auto applicationView = Windows::UI::ViewManagement::ApplicationView::GetForCurrentView(); + if (applicationView->IsFullScreenMode) + { + applicationView->ExitFullScreenMode(); + } + else + { + applicationView->TryEnterFullScreenMode(); + } + } + break; + + case VirtualKey::Shift: + m_bShiftPressed = true; + break; + } +} + +void App::OnKeyUp(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::KeyEventArgs^ args) +{ + auto Key = args->VirtualKey; + switch (Key) + { + case VirtualKey::Shift: + m_bShiftPressed = false; + break; + } +} + +std::shared_ptr App::GetDeviceResources() +{ + if (m_deviceResources != nullptr && m_deviceResources->IsDeviceRemoved()) + { + // All references to the existing D3D device must be released before a new device + // can be created. + + 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 = m_Main->InitDeviceResources(); + if (m_deviceResources) + { + m_deviceResources->SetWindow(CoreWindow::GetForCurrentThread()); + auto Title = Diligent::WidenString(m_Main->GetAppTitle()); + Windows::UI::ViewManagement::ApplicationView::GetForCurrentView()->Title = ref new Platform::String(Title.c_str()); + m_Main->OnWindowSizeChanged(); + m_Main->CreateRenderers(); + } + } + return m_deviceResources; +} -- cgit v1.2.3