diff --git a/.gitignore b/.gitignore index 5692f5b..3feb566 100644 --- a/.gitignore +++ b/.gitignore @@ -261,4 +261,4 @@ __pycache__/ *.pyc Dependencies -/CoreWindowHost/Generated Files/winrt +/**/Generated Files/* diff --git a/AngleHosting.sln b/AngleHosting.sln index ab2ac82..8445324 100644 --- a/AngleHosting.sln +++ b/AngleHosting.sln @@ -26,6 +26,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution README.md = README.md EndProjectSection EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "XamlHost", "XamlHost\XamlHost.vcxproj", "{52ADD126-DE01-4344-BD72-99914F83EFD7}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|ARM = Debug|ARM @@ -74,6 +76,24 @@ Global {5B8FEAB1-1415-446E-AFB0-95E42281D081}.Release|x86.ActiveCfg = Release|Win32 {5B8FEAB1-1415-446E-AFB0-95E42281D081}.Release|x86.Build.0 = Release|Win32 {5B8FEAB1-1415-446E-AFB0-95E42281D081}.Release|x86.Deploy.0 = Release|Win32 + {52ADD126-DE01-4344-BD72-99914F83EFD7}.Debug|ARM.ActiveCfg = Debug|ARM + {52ADD126-DE01-4344-BD72-99914F83EFD7}.Debug|ARM.Build.0 = Debug|ARM + {52ADD126-DE01-4344-BD72-99914F83EFD7}.Debug|ARM.Deploy.0 = Debug|ARM + {52ADD126-DE01-4344-BD72-99914F83EFD7}.Debug|x64.ActiveCfg = Debug|x64 + {52ADD126-DE01-4344-BD72-99914F83EFD7}.Debug|x64.Build.0 = Debug|x64 + {52ADD126-DE01-4344-BD72-99914F83EFD7}.Debug|x64.Deploy.0 = Debug|x64 + {52ADD126-DE01-4344-BD72-99914F83EFD7}.Debug|x86.ActiveCfg = Debug|Win32 + {52ADD126-DE01-4344-BD72-99914F83EFD7}.Debug|x86.Build.0 = Debug|Win32 + {52ADD126-DE01-4344-BD72-99914F83EFD7}.Debug|x86.Deploy.0 = Debug|Win32 + {52ADD126-DE01-4344-BD72-99914F83EFD7}.Release|ARM.ActiveCfg = Release|ARM + {52ADD126-DE01-4344-BD72-99914F83EFD7}.Release|ARM.Build.0 = Release|ARM + {52ADD126-DE01-4344-BD72-99914F83EFD7}.Release|ARM.Deploy.0 = Release|ARM + {52ADD126-DE01-4344-BD72-99914F83EFD7}.Release|x64.ActiveCfg = Release|x64 + {52ADD126-DE01-4344-BD72-99914F83EFD7}.Release|x64.Build.0 = Release|x64 + {52ADD126-DE01-4344-BD72-99914F83EFD7}.Release|x64.Deploy.0 = Release|x64 + {52ADD126-DE01-4344-BD72-99914F83EFD7}.Release|x86.ActiveCfg = Release|Win32 + {52ADD126-DE01-4344-BD72-99914F83EFD7}.Release|x86.Build.0 = Release|Win32 + {52ADD126-DE01-4344-BD72-99914F83EFD7}.Release|x86.Deploy.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/AngleRenderer/AngleSpriteRenderer.cpp b/AngleRenderer/AngleSpriteRenderer.cpp index 4bcf9ce..2b7d1ab 100644 --- a/AngleRenderer/AngleSpriteRenderer.cpp +++ b/AngleRenderer/AngleSpriteRenderer.cpp @@ -16,4 +16,8 @@ AngleSpriteRenderer::~AngleSpriteRenderer() { void AngleSpriteRenderer::Start(const winrt::Windows::UI::Composition::SpriteVisual & withVisual) { mRender->Start(withVisual); -} \ No newline at end of file +} + +void AngleSpriteRenderer::Start(const winrt::Windows::UI::Xaml::Controls::SwapChainPanel & panel) { + mRender->Start(panel); +} diff --git a/AngleRenderer/AngleSpriteRendererImpl.cpp b/AngleRenderer/AngleSpriteRendererImpl.cpp index 4ee998a..1bc4df3 100644 --- a/AngleRenderer/AngleSpriteRendererImpl.cpp +++ b/AngleRenderer/AngleSpriteRendererImpl.cpp @@ -22,11 +22,22 @@ void AngleSpriteRendererPrivate::Start(const SpriteVisual & withVisual) { StartRenderLoop(); } +void AngleSpriteRendererPrivate::Start(const SwapChainPanel& panel) { + mSwapChainPanel = panel; + CreateRenderSurface(); + StartRenderLoop(); +} + void AngleSpriteRendererPrivate::CreateRenderSurface() { if (mOpenGLES && mRenderSurface == EGL_NO_SURFACE) { - mRenderSurface = mOpenGLES->CreateSurface(mHostVisual); + if (mHostVisual != nullptr) { + mRenderSurface = mOpenGLES->CreateSurface(mHostVisual); + } + else { + mRenderSurface = mOpenGLES->CreateSurface(mSwapChainPanel); + } } } diff --git a/AngleRenderer/AngleSpriteRendererImpl.h b/AngleRenderer/AngleSpriteRendererImpl.h index c1345cc..b79e875 100644 --- a/AngleRenderer/AngleSpriteRendererImpl.h +++ b/AngleRenderer/AngleSpriteRendererImpl.h @@ -5,6 +5,7 @@ using namespace winrt; using namespace Concurrency; using namespace Windows::Foundation; using namespace Windows::UI::Composition; +using namespace Windows::UI::Xaml::Controls; class AngleSpriteRendererPrivate { @@ -12,6 +13,7 @@ class AngleSpriteRendererPrivate AngleSpriteRendererPrivate(); ~AngleSpriteRendererPrivate(); void Start(const SpriteVisual & withVisual); + void Start(const SwapChainPanel& panel); private: void CreateRenderSurface(); void DestroyRenderSurface(); @@ -25,5 +27,6 @@ class AngleSpriteRendererPrivate Concurrency::critical_section mRenderSurfaceCriticalSection; IAsyncAction mRenderLoopWorker; SpriteVisual mHostVisual{nullptr}; + SwapChainPanel mSwapChainPanel{nullptr}; }; diff --git a/AngleRenderer/OpenGLES.cpp b/AngleRenderer/OpenGLES.cpp index d99673d..3a8798a 100644 --- a/AngleRenderer/OpenGLES.cpp +++ b/AngleRenderer/OpenGLES.cpp @@ -197,6 +197,25 @@ EGLSurface OpenGLES::CreateSurface(winrt::Windows::UI::Composition::ISpriteVisua return surface; } +EGLSurface OpenGLES::CreateSurface(const winrt::Windows::UI::Xaml::Controls::SwapChainPanel& panel) +{ + EGLSurface surface = EGL_NO_SURFACE; + + const EGLint surfaceAttributes[] = { + // EGL_ANGLE_SURFACE_RENDER_TO_BACK_BUFFER is part of the same optimization as EGL_ANGLE_DISPLAY_ALLOW_RENDER_TO_BACK_BUFFER (see above). + // If you have compilation issues with it then please update your Visual Studio templates. + // EGL_RENDER_BUFFER, EGL_BACK_BUFFER, + EGL_NONE + }; + + surface = eglCreateWindowSurface(mEglDisplay, mEglConfig, static_cast(winrt::get_abi(panel)), nullptr); + if (surface == EGL_NO_SURFACE) { + throw hresult_error(E_FAIL, L"Failed to create EGL surface"); + } + + return surface; +} + void OpenGLES::GetSurfaceDimensions(const EGLSurface surface, EGLint* width, EGLint* height) { eglQuerySurface(mEglDisplay, surface, EGL_WIDTH, width); diff --git a/AngleRenderer/OpenGLES.h b/AngleRenderer/OpenGLES.h index 31e9ae5..085e045 100644 --- a/AngleRenderer/OpenGLES.h +++ b/AngleRenderer/OpenGLES.h @@ -9,6 +9,7 @@ class OpenGLES ~OpenGLES(); EGLSurface CreateSurface(winrt::Windows::UI::Composition::ISpriteVisual & visual); + EGLSurface CreateSurface(const winrt::Windows::UI::Xaml::Controls::SwapChainPanel & panel); void GetSurfaceDimensions(const EGLSurface surface, EGLint *width, EGLint *height); void DestroySurface(const EGLSurface surface); void MakeCurrent(const EGLSurface surface); diff --git a/AngleRenderer/inc/AngleSpriteRenderer.h b/AngleRenderer/inc/AngleSpriteRenderer.h index 36f26d1..ff6f0f8 100644 --- a/AngleRenderer/inc/AngleSpriteRenderer.h +++ b/AngleRenderer/inc/AngleSpriteRenderer.h @@ -1,6 +1,7 @@ #pragma once #include +#include class AngleSpriteRendererPrivate; class AngleSpriteRenderer { @@ -9,7 +10,8 @@ class AngleSpriteRenderer { ~AngleSpriteRenderer(); - void Start(const winrt::Windows::UI::Composition::SpriteVisual & withVisual); + void Start(const winrt::Windows::UI::Composition::SpriteVisual& withVisual); + void Start(const winrt::Windows::UI::Xaml::Controls::SwapChainPanel& panel); private: AngleSpriteRendererPrivate * mRender{ nullptr }; }; \ No newline at end of file diff --git a/AngleRenderer/pch.h b/AngleRenderer/pch.h index 4e5dec4..189869b 100644 Binary files a/AngleRenderer/pch.h and b/AngleRenderer/pch.h differ diff --git a/XamlHost/App.cpp b/XamlHost/App.cpp new file mode 100644 index 0000000..d143a5d --- /dev/null +++ b/XamlHost/App.cpp @@ -0,0 +1,119 @@ +#include "pch.h" + +#include "App.h" +#include "OpenGlPage.h" + +using namespace winrt; +using namespace Windows::ApplicationModel; +using namespace Windows::ApplicationModel::Activation; +using namespace Windows::Foundation; +using namespace Windows::UI::Xaml; +using namespace Windows::UI::Xaml::Controls; +using namespace Windows::UI::Xaml::Navigation; +using namespace XamlHost; +using namespace XamlHost::implementation; + +/// +/// Initializes the singleton application object. This is the first line of authored code +/// executed, and as such is the logical equivalent of main() or WinMain(). +/// +App::App() +{ + InitializeComponent(); + Suspending({ this, &App::OnSuspending }); + +#if defined _DEBUG && !defined DISABLE_XAML_GENERATED_BREAK_ON_UNHANDLED_EXCEPTION + UnhandledException([this](IInspectable const&, UnhandledExceptionEventArgs const& e) + { + if (IsDebuggerPresent()) + { + auto errorMessage = e.Message(); + __debugbreak(); + } + }); +#endif +} + +/// +/// Invoked when the application is launched normally by the end user. Other entry points +/// will be used such as when the application is launched to open a specific file. +/// +/// Details about the launch request and process. +void App::OnLaunched(LaunchActivatedEventArgs const& e) +{ + Frame rootFrame{ nullptr }; + auto content = Window::Current().Content(); + if (content) + { + rootFrame = content.try_as(); + } + + // Do not repeat app initialization when the Window already has content, + // just ensure that the window is active + if (rootFrame == nullptr) + { + // Create a Frame to act as the navigation context and associate it with + // a SuspensionManager key + rootFrame = Frame(); + + rootFrame.NavigationFailed({ this, &App::OnNavigationFailed }); + + if (e.PreviousExecutionState() == ApplicationExecutionState::Terminated) + { + // Restore the saved session state only when appropriate, scheduling the + // final launch steps after the restore is complete + } + + if (e.PrelaunchActivated() == false) + { + if (rootFrame.Content() == nullptr) + { + // When the navigation stack isn't restored navigate to the first page, + // configuring the new page by passing required information as a navigation + // parameter + rootFrame.Navigate(xaml_typename(), box_value(e.Arguments())); + } + // Place the frame in the current Window + Window::Current().Content(rootFrame); + // Ensure the current window is active + Window::Current().Activate(); + } + } + else + { + if (e.PrelaunchActivated() == false) + { + if (rootFrame.Content() == nullptr) + { + // When the navigation stack isn't restored navigate to the first page, + // configuring the new page by passing required information as a navigation + // parameter + rootFrame.Navigate(xaml_typename(), box_value(e.Arguments())); + } + // Ensure the current window is active + Window::Current().Activate(); + } + } +} + +/// +/// Invoked when application execution is being suspended. Application state is saved +/// without knowing whether the application will be terminated or resumed with the contents +/// of memory still intact. +/// +/// The source of the suspend request. +/// Details about the suspend request. +void App::OnSuspending([[maybe_unused]] IInspectable const& sender, [[maybe_unused]] SuspendingEventArgs const& e) +{ + // Save application state and stop any background activity +} + +/// +/// Invoked when Navigation to a certain page fails +/// +/// The Frame which failed navigation +/// Details about the navigation failure +void App::OnNavigationFailed(IInspectable const&, NavigationFailedEventArgs const& e) +{ + throw hresult_error(E_FAIL, hstring(L"Failed to load Page ") + e.SourcePageType().Name); +} \ No newline at end of file diff --git a/XamlHost/App.h b/XamlHost/App.h new file mode 100644 index 0000000..4e12f0f --- /dev/null +++ b/XamlHost/App.h @@ -0,0 +1,14 @@ +#pragma once +#include "App.xaml.g.h" + +namespace winrt::XamlHost::implementation +{ + struct App : AppT + { + App(); + + void OnLaunched(Windows::ApplicationModel::Activation::LaunchActivatedEventArgs const&); + void OnSuspending(IInspectable const&, Windows::ApplicationModel::SuspendingEventArgs const&); + void OnNavigationFailed(IInspectable const&, Windows::UI::Xaml::Navigation::NavigationFailedEventArgs const&); + }; +} diff --git a/XamlHost/App.idl b/XamlHost/App.idl new file mode 100644 index 0000000..dd1c1ca --- /dev/null +++ b/XamlHost/App.idl @@ -0,0 +1,3 @@ +namespace XamlHost +{ +} diff --git a/XamlHost/App.xaml b/XamlHost/App.xaml new file mode 100644 index 0000000..0af7d46 --- /dev/null +++ b/XamlHost/App.xaml @@ -0,0 +1,7 @@ + + + diff --git a/XamlHost/Assets/LockScreenLogo.scale-200.png b/XamlHost/Assets/LockScreenLogo.scale-200.png new file mode 100644 index 0000000..735f57a Binary files /dev/null and b/XamlHost/Assets/LockScreenLogo.scale-200.png differ diff --git a/XamlHost/Assets/SplashScreen.scale-200.png b/XamlHost/Assets/SplashScreen.scale-200.png new file mode 100644 index 0000000..023e7f1 Binary files /dev/null and b/XamlHost/Assets/SplashScreen.scale-200.png differ diff --git a/XamlHost/Assets/Square150x150Logo.scale-200.png b/XamlHost/Assets/Square150x150Logo.scale-200.png new file mode 100644 index 0000000..af49fec Binary files /dev/null and b/XamlHost/Assets/Square150x150Logo.scale-200.png differ diff --git a/XamlHost/Assets/Square44x44Logo.scale-200.png b/XamlHost/Assets/Square44x44Logo.scale-200.png new file mode 100644 index 0000000..ce342a2 Binary files /dev/null and b/XamlHost/Assets/Square44x44Logo.scale-200.png differ diff --git a/XamlHost/Assets/Square44x44Logo.targetsize-24_altform-unplated.png b/XamlHost/Assets/Square44x44Logo.targetsize-24_altform-unplated.png new file mode 100644 index 0000000..f6c02ce Binary files /dev/null and b/XamlHost/Assets/Square44x44Logo.targetsize-24_altform-unplated.png differ diff --git a/XamlHost/Assets/StoreLogo.png b/XamlHost/Assets/StoreLogo.png new file mode 100644 index 0000000..7385b56 Binary files /dev/null and b/XamlHost/Assets/StoreLogo.png differ diff --git a/XamlHost/Assets/Wide310x150Logo.scale-200.png b/XamlHost/Assets/Wide310x150Logo.scale-200.png new file mode 100644 index 0000000..288995b Binary files /dev/null and b/XamlHost/Assets/Wide310x150Logo.scale-200.png differ diff --git a/XamlHost/OpenGlPage.cpp b/XamlHost/OpenGlPage.cpp new file mode 100644 index 0000000..da7b746 --- /dev/null +++ b/XamlHost/OpenGlPage.cpp @@ -0,0 +1,29 @@ +#include "pch.h" +#include "OpenGlPage.h" +#include "OpenGlPage.g.cpp" + +using namespace winrt; + +using namespace Windows; +using namespace Windows::ApplicationModel::Core; +using namespace Windows::Foundation::Numerics; +using namespace Windows::UI; +using namespace Windows::UI::Core; +using namespace Windows::UI::Composition; +using namespace Windows::UI::Xaml::Controls; + +namespace winrt::XamlHost::implementation +{ + OpenGlPage::OpenGlPage() + { + InitializeComponent(); + AddVisual(); + } + + void OpenGlPage::AddVisual() + { + SwapChainPanel panel; + Content(panel); + m_render.Start(panel); + } +} diff --git a/XamlHost/OpenGlPage.h b/XamlHost/OpenGlPage.h new file mode 100644 index 0000000..39a51a9 --- /dev/null +++ b/XamlHost/OpenGlPage.h @@ -0,0 +1,25 @@ +#pragma once + +#include "OpenGlPage.g.h" + +namespace winrt::XamlHost::implementation +{ + struct OpenGlPage : OpenGlPageT + { + OpenGlPage(); + + private: + void AddVisual(); + + winrt::Windows::UI::Composition::CompositionTarget m_target{ nullptr }; + winrt::Windows::UI::Composition::VisualCollection m_visuals{ nullptr }; + AngleSpriteRenderer m_render; + }; +} + +namespace winrt::XamlHost::factory_implementation +{ + struct OpenGlPage : OpenGlPageT + { + }; +} diff --git a/XamlHost/OpenGlPage.idl b/XamlHost/OpenGlPage.idl new file mode 100644 index 0000000..6604de2 --- /dev/null +++ b/XamlHost/OpenGlPage.idl @@ -0,0 +1,8 @@ +namespace XamlHost +{ + [default_interface] + runtimeclass OpenGlPage : Windows.UI.Xaml.Controls.Page + { + OpenGlPage(); + } +} diff --git a/XamlHost/OpenGlPage.xaml b/XamlHost/OpenGlPage.xaml new file mode 100644 index 0000000..d0ef312 --- /dev/null +++ b/XamlHost/OpenGlPage.xaml @@ -0,0 +1,10 @@ + + + diff --git a/XamlHost/Package.appxmanifest b/XamlHost/Package.appxmanifest new file mode 100644 index 0000000..20643dc --- /dev/null +++ b/XamlHost/Package.appxmanifest @@ -0,0 +1,32 @@ + + + + + + XamlHost + johan + Assets\StoreLogo.png + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/XamlHost/PropertySheet.props b/XamlHost/PropertySheet.props new file mode 100644 index 0000000..e34141b --- /dev/null +++ b/XamlHost/PropertySheet.props @@ -0,0 +1,16 @@ + + + + + + + + \ No newline at end of file diff --git a/XamlHost/XamlHost.vcxproj b/XamlHost/XamlHost.vcxproj new file mode 100644 index 0000000..46da04c --- /dev/null +++ b/XamlHost/XamlHost.vcxproj @@ -0,0 +1,186 @@ + + + + + true + true + true + true + {52add126-de01-4344-bd72-99914f83efd7} + XamlHost + XamlHost + en-US + 15.0 + true + Windows Store + 10.0 + 10.0.18362.0 + 10.0.17134.0 + + + + + Debug + ARM + + + Debug + Win32 + + + Debug + x64 + + + Release + ARM + + + Release + Win32 + + + Release + x64 + + + + Application + v140 + v141 + v142 + Unicode + + + true + true + + + false + true + false + + + + + + + + + + + + + $(SolutionDir)Dependencies\angle\include;$(VC_IncludePath);$(WindowsSDK_IncludePath); + $(SolutionDir)x$(PlatformArchitecture)\$(Configuration)\;$(SolutionDir)Dependencies\angle\UWPLib;$(VC_LibraryPath_x64);$(WindowsSDK_LibraryPath_x64);$(NETFXKitsDir)Lib\um\x64 + + + + Use + pch.h + $(IntDir)pch.pch + Level4 + %(AdditionalOptions) /bigobj + + /DWINRT_NO_MAKE_DETECTION %(AdditionalOptions) + + + WIN32_LEAN_AND_MEAN;WINRT_LEAN_AND_MEAN;%(PreprocessorDefinitions) + + + false + + + + + _DEBUG;%(PreprocessorDefinitions) + + + WindowsApp.lib;%(AdditionalDependencies);libegl.dll.lib;AngleRenderer.lib;libglesv2.dll.lib; + + + + + NDEBUG;%(PreprocessorDefinitions) + + + true + true + + + + + + App.xaml + + + OpenGlPage.xaml + + + + + Designer + + + Designer + + + + + Designer + + + + + + + + + + + + + + Create + + + App.xaml + + + OpenGlPage.xaml + + + + + + App.xaml + + + OpenGlPage.xaml + + + + + true + + + true + + + + + false + + + + + + + + + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + + \ No newline at end of file diff --git a/XamlHost/XamlHost.vcxproj.filters b/XamlHost/XamlHost.vcxproj.filters new file mode 100644 index 0000000..7d489cf --- /dev/null +++ b/XamlHost/XamlHost.vcxproj.filters @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + Assets + + + Assets + + + Assets + + + Assets + + + Assets + + + Assets + + + Assets + + + + + + + + {e48dc53e-40b1-40cb-970a-f89935452892} + + + {43b0c0fe-87ed-4298-92a0-ea3dbe9b4bba} + + + + + + + Binaries + + + Binaries + + + + + + + + + \ No newline at end of file diff --git a/XamlHost/packages.config b/XamlHost/packages.config new file mode 100644 index 0000000..768164f --- /dev/null +++ b/XamlHost/packages.config @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/XamlHost/pch.cpp b/XamlHost/pch.cpp new file mode 100644 index 0000000..bcb5590 --- /dev/null +++ b/XamlHost/pch.cpp @@ -0,0 +1 @@ +#include "pch.h" diff --git a/XamlHost/pch.h b/XamlHost/pch.h new file mode 100644 index 0000000..62b83d7 --- /dev/null +++ b/XamlHost/pch.h @@ -0,0 +1,30 @@ +#pragma once +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// Enable function definitions in the GL headers below +#define GL_GLEXT_PROTOTYPES + +// OpenGL ES includes +#include +#include + +// EGL includes +#include +#include +#include + +#include "../AngleRenderer/inc/AngleSpriteRenderer.h" \ No newline at end of file diff --git a/XamlHost/readme.txt b/XamlHost/readme.txt new file mode 100644 index 0000000..dc7500a --- /dev/null +++ b/XamlHost/readme.txt @@ -0,0 +1,23 @@ +======================================================================== + C++/WinRT XamlHost Project Overview +======================================================================== + +This project demonstrates how to get started writing XAML apps directly +with standard C++, using the C++/WinRT SDK component and XAML compiler +support to generate implementation headers from interface (IDL) files. +These headers can then be used to implement the local Windows Runtime +classes referenced in the app's XAML pages. + +Steps: +1. Create an interface (IDL) file to define any local Windows Runtime + classes referenced in the app's XAML pages. +2. Build the project once to generate implementation templates under + the "Generated Files" folder, as well as skeleton class definitions + under "Generated Files\sources". +3. Use the skeleton class definitions for reference to implement your + Windows Runtime classes. + +======================================================================== +Learn more about C++/WinRT here: +http://aka.ms/cppwinrt/ +========================================================================