UWP C++ applications based on “DirectX 11 and XAML App” or “XAML App for OpenGL ES“ project templates have some partial App class defined in user code and in generated file App.g.h:
partial ref class App : public ::Windows::UI::Xaml::Application,
virtual ::Windows::UI::Xaml::Markup::IXamlType^ GetXamlType(::Windows::UI::Xaml::Interop::TypeName type);
virtual ::Windows::UI::Xaml::Markup::IXamlType^ GetXamlType(::Platform::String^ fullName);
virtual ::Platform::Array<::Windows::UI::Xaml::Markup::XmlnsDefinition>^ GetXmlnsDefinitions();
the user code:
ref class App sealed
virtual void OnLaunched(Windows::ApplicationModel::Activation::LaunchActivatedEventArgs^ e) override;
Cross platform (Android, iOS, UWP) OpenGLES 2 application can be easily created in VS2015 using “OpenGLES 2 Application (Android, iOS, Windows Universal)” project template:
Visual Studio 2015 allows easily combine OpenGL graphics with XAML controls in a single window. To accomplish this task we can create a new project based on “XAML App for OpenGL ES (Universal Windows)” template:
ANGLE is a wrapper library that implements OpenGL ES API (version 2.0 and parts of 3.0) and translates OpenGL ES calls to their DirectX equivalents. See https://github.com/MSOpenTech/angle for more information.
There are two options how to use ANGLE: install its binaries as a NuGet package or compile it from the source code. I believe that cool software developers, like real heroes, never search easy ways, so I decided to compile ANGLE from the source code with VS2015 Community.
First I cloned the repository and ensured that my branch is ms-master:
Probably it would be better if I learned Java 15 years ago because Java technologies do not change so rapidly, but I love C++ very much and I spent some time investigating how the application based on DirectX 11 and XAML Visual Studio 2015 template works on relatively new UWP platform.
In opposite to Win32, there are no main thread in UWP applications, because in UWP application each top-level window runs on its own thread. Our application has only one top-level window so it has one UI thread and also it has event handling thread and renderer thread (creating new top-level window will require some adaptive changes in our application).
WinRT has a huge amount of new functionality that makes it an exciting development platform and from GUI developer perspective it has a lot of significant benefits over WPF such as the ability to combine XAML and DirectX together and better managed and unmanaged code integration with new C++/CX compiler and COM based WinRT components. But from other side, WinRT has a number of limitations that developers who migrate their code from WPF to WinRT should be aware of. Below I briefly described those limitations.
COM based components limitations
WinRT components actually are not classes they are COM objects, so they can not be inherited and can only be used as a set of interfaces, that is why we use sealed keyword with the component class declaration in C# and C++. In my opinion this is significant disadvantage that breaks the object oriented paradigm.
The lack of synchronous methods in API
WinRT asynchronous API is useful when I have an button click handler that opens a file, for example. In this case async/await keywords help me to write a code that does not block UI thread. But what if I already have a separate non-UI thread that opens a file? Why should I use asynchronous API if my separate thread does not block anything?
The possible solution in this case is to use old C-style API like ::CreateFile2, for example.
The easiest way to accomplish this task is to use converter provided below. It is written in C++ but this convertor can be easily converted to C#:
public ref class MultiplicationConverter sealed : Windows::UI::Xaml::Data::IValueConverter
virtual Platform::Object^ Convert(Platform::Object^ value, Windows::UI::Xaml::Interop::TypeName targetType, Platform::Object^ parameter, Platform::String^ language);
virtual Platform::Object^ ConvertBack(Platform::Object^ value, Windows::UI::Xaml::Interop::TypeName targetType, Platform::Object^ parameter, Platform::String^ language);
Platform::Object^ InternalConvert(Platform::Object^ value, Platform::Object^ parameter, bool forward);
I developed some prototype of a custom layout panel on Universal Windows Platform called DynamicSplitter that contains multiple child panes and arranges them horizontally or vertically depending on its IsHorizontal property of type bool. To support heterogeneous layout of panes, DynamicSplitter itself is used as the child pane of another DynamicSplitter with different IsHorizontal property. So, for example, the parent splitter can have two panes split horizontally one of which is a user control and other is the child splitter, and the child splitter can have three panes split vertically and so on.
Regardless of DynamicSplitter has a lot in common with Grid or StackPanel it is inherited directly from Panel and lays out its child panes by overriding MeasureOverride(…) and ArrangeOverride(…) functions:
With the release of Windows 8, Microsoft introduced a grate technology for combining XAML and DirectX together, letting us to place XAML controls over intensive real-time graphics, see DirectX and XAML interop (Windows Runtime apps using DirectX with C++) for more details.
You can easily download and build sample XAML SwapChainPanel DirectX interop sample demonstrating how it works. All that you need is Visual Studio 2013 with installed license. After the license is installed Visual Studio 2013 shows the following dialog: