Happy 10th Birthday, GraphicDNA !

Last week this blog turned 10!!

Image result for 10th birthday

Can't believe how fast time goes by.

During this period, I founded my company, I had the honor to be awarded as DirectX MVP (4 years in a row), I became part of Microsoft / RARE team, and then I spent some of the best years I had in the industry, working as Associate Technical Director at Electronic Arts. It's been an amazing adventure being part of the development teams of all these games:

Credited on...

Now that I´m back to teaching, writing, developing and R&D projects, I'm certain that the best is yet to come.

It's been a wonderful time to be a developer all along, so let's see what the next 10 years bring :)

Cheers!

Custom MainLoop in C# / UWP applications with DirectX (SharpDX) with unlocked frame rates (beyond 60 Hz)

When you want to write a game or a 3D application in C# using SharpDX, and you want it to be UWP, there is little information about how to correctly handle the basics of the main loop.

All examples I found were based on the interop between XAML and DirectX, but if you go that path, you´ll need to rely on the CompositingTarget.Rendering event to handle your updates and renders, which lets all the inner processing to Windows.UI.XAML and limits the frame rate to 60 Hz.

So, how to create your own, unlocked-framerate-ready, main loop?

First things first:

Dude, where's my Main entry point?

Typically, a C# application has a Program static class where the "main" entry point is defined.

When you create a WPF, UWP or Windows Store application though, aparently that code is missing, and the application is started magically by the system.

The truth is that the main entry point is hidden in automatically-generated source code files under the obj\platform\debug folder. If you look there for a file called App.g.i.cs, you'll find something like this:


#if !DISABLE_XAML_GENERATED_MAIN
    /// <summary>
    /// Program class
    /// </summary>
    public static class Program
    {
        [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Windows.UI.Xaml.Build.Tasks"," 14.0.0.0")]
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
        static void Main(string[] args)
        {
            global::Windows.UI.Xaml.Application.Start((p) => new App());
        }
    }
#endif

Et'voila... There's your entry point.

So first thing is to define the DISABLE_XAML_GENERATED_MAIN conditional compilation symbol to prevent Visual Studio from generating the entry point for you.

Next, is to add your own Program class and main entry points, as always, so you have control on the application start procedure. You can simply copy-paste that code anywhere in your project.

The Main Loop

Please note: this implementation is inspired by the C++ equivalent described here.

Now that you have a main entry point, you can replace the invokation of Windows.UI.Xaml.Application.Start (which internally deals with its own main loop) with your own code.

What we want to use instead is: Windows.ApplicationModel.Core.CoreApplication.Run, which is not bound to XAML and allows you to define your own IFrameworkView class, with your custom Run method.

Something like:


public static class Program
{
    static void Main(string[] args)
    {
        MyApp sample = new MyApp();
        var viewProvider = new ViewProvider(sample);
        Windows.ApplicationModel.Core.CoreApplication.Run(viewProvider);            
    }
}

The ViewProvider class

The main purpose of the view provider is to create a IFrameworkView when required, so it could be something like this:


public class ViewProvider : IFrameworkViewSource
    {
        MyApp mSample;

        public ViewProvider(MyApp pSample)
        {
            mSample = pSample;
        }
        //
        // Summary:
        //     A method that returns a view provider object.
        //
        // Returns:
        //     An object that implements a view provider.
        public IFrameworkView CreateView()
        {
            return new View(mSample);
        }
    }

The View Class

The view class implements the IFrameworkView interface, which defines most of the logic we want to implement.

The framework will invoke interface's methods to perform the initialization, uninitialization, resource loading, etc, and will also report us when the application window changes through the SetWindow method.

For the purpose of this article, the most interesting part is the Run method, which we can write to include our own, shiny, new Main Loop:



public void Run()
{
    var applicationView = ApplicationView.GetForCurrentView();
    applicationView.Title = mApp.Title;

    mApp.Initialize();

    while (!mWindowClosed)
    {
        CoreWindow.GetForCurrentThread().Dispatcher.ProcessEvents(
                                   CoreProcessEventsOption.ProcessAllIfPresent);
        mApp.OnFrameMove();
        mApp.OnRender();
    }
    mApp.Dispose();
}

This removes the need to rely on XAML stuff in your game (and its overhead), gives you more control about how the mainloop behaves, and unleashes the possibility of rendering with a variable frame rate in C#.

Please refer to this page for further info about how to initialize a swap chain suitable for unlocked frame rates.

Hope it helps!

[UWP] Unable to activate Windows Store app - The app didn't start


Today, I've been struggling with a Visual Studio 2015 deploy error for a while.

When trying to debug a C# - UWP application, I kept receiving the following error upon application activation:


Places like this have information about other people finding the same error. Some of them even re-installed Windows 10 from scratch with no luck.

In my case, the cause (and solution) was much simpler than that:

I have my all my projects in an external SSD drive. Yesterday I was working in my laptop, and the last compilation I did there was in Release mode. When I brought the external disk back to my main PC today and tried to deploy directly as Debug, the activation failed for some reason.

So, going back to Release mode, rebuild, launch and let Windows activate the app did the trick. After that, I've been able to go back to Debug mode normally. 

Hope it helps.