Game development with SharpDX Toolkit: Creating a base project

Since the announcement that Microsoft wasn’t going to update XNA anymore, lots of frameworks have tried to fill the void it left as a friendly way of being introduced to game development. Perhaps the most well known of them is MonoGame, which started as a way to expand XNA compatibility to non-Windows platforms by using managed OpenGL and the Xamarin products. Other alternatives based on C# are Unity, OpenTK and SharpDX, but they have totally different APIs or are just graphical libraries with a more low level approach.

But time passed and the people behind SharpDX launched their own solution: SharpDX Toolkit, a higher-level library that mimicked XNA. While the namespaces are named differently, almost all classes have matching names and even their structure is identical. With this, you can bring the power of DirectX 11 to desktop, Windows Store and Windows Phone games while maintaining the philosophy that XNA introduced.

Starting with this post, there will be a (hopefully regular!) series of tutorials on how to use SharpDX Toolkit for game development. They will be intertwined with the regular, more low level Direct2D and Direct3D posts using bare SharpDX.

Creating a new Windows desktop project

This time we are going to focus on game development for the desktop platform, and in future tutorials we will be porting the existing code to Windows Store and Windows Phone Universal Apps. So, open Visual Studio and go to select the New > Project… menu option. Inside the New Project window, select the template Templates > Visual C# > Windows Desktop > Empty Project. Give it a name and a location and click OK.

Create new project window

This will give us an empty project that by default is meant for console applications; this means that a console window will pop up when our app runs! You can change this by right clicking your project file from the Solution Explorer window and selecting Properties > Application > Output Type: Windows Application. However, you can keep it this way if you want to print debug messages via Console.Write.

Now, let’s add the references to the SharpDX Toolkit assemblies that we are going to need. Instead of downloading the package and manually adding it (which you can do if you want), we are going to take advantage of NuGet to download and reference the latest version of the libraries. So right click again your project file and select Manage NuGet Packages…. In this new window search for SharpDX.Toolkit and install only the SharpDX.Toolkit.Game package; every other library (including vanilla SharpDX) will be automatically added since it’s marked as a dependency.

Installing SharpDX Toolkig packages from NuGet window

Adding the game class

Let’s get started with the Game class. Add a new source file and define a class inside it (we will call it CrazyPlanesGame) that inherits from SharpDX.Toolkit.Game. Like in XNA, this class will be used to abstract the game loop and run the update and draw logic when it is needed.

Next, we need to perform a little initialization before the game class runs properly. Add a private member field of type GraphicsDeviceManager and instantiate it inside the constructor of CrazyPlanesGame. This will take care of initializing the graphics device (Direct3D device, context and application window) and will raise the proper events during the application life cycle. For now we will only modify its PreferredBackBufferWidth and PreferredBackBufferHeight properties because we want a portrait window for our game, although you can change other properties, like running the window in full screen mode or specifying a custom colour format for the back buffer.

internal class CrazyPlanesGame : Game
{
    private GraphicsDeviceManager deviceManager;

    public CrazyPlanesGame()
    {
        deviceManager = new GraphicsDeviceManager(this);
        deviceManager.PreferredBackBufferWidth = 480;
        deviceManager.PreferredBackBufferHeight = 800;
    }
}


Creating our GraphicsDeviceManager is mandatory; not doing so will throw an InvalidOperationException with the error message No GraphicsDeviceManager found when the game starts running.

Now, and to properly run, our game needs an entry point so the operating system knows what code should be called first. In C# this is achieved by declaring a class with a static function named Main of type void. Inside it, we will need to instantiate a copy of our CrazyPlanesGame and call its Run method. In addition, the Main function must be marked with the STAThread attribute because internally SharpDX uses Windows Forms to create the game window and this is one of its requisites.

public static class Program
{
    [STAThread]
    public static void Main()
    {
        using (CrazyPlanesGame game = new CrazyPlanesGame())
        {
            game.Run();
        }
    }
}

At last, go back to the CrazyPlanesGame class and override the Draw method. This will allow us to insert our own drawing code, which for now will be just clearing the screen to a cornflower blue colour:

protected override void Draw(GameTime gameTime)
{
    GraphicsDevice.Clear(Color.CornflowerBlue);

    base.Draw(gameTime);
}


Now you can run the project and take a look at the results of our coding session.

Our first SharpDX Toolkit game window

Source code

Unlike previously, the code for this series of tutorials will be all hosted in the same repository, with each solution inside its own folder. Here it is on GitHub, and you can find the one for this article inside the folder named Chapter1.

LockScreen.SetImageUri fails sometimes on Windows Phone 8.1 devices

While working on a Silverlight for Windows Phone 8.1 app that uses the lock screen API, some beta testers reported that the app didn’t work as expected. The lock screen wasn’t being changed to the desired picture, instead using the default Windows Phone background image. Worst of all, this was happening to a very specific subset of users; even with the same phone model, in some cases it failed and in others it didn’t.

Trying to spot what failed was an easy task. Thanks to BugSense I knew that what was failing was the call to SetImageUri, with a poorly descriptive ArgumentException:

System.ArgumentException: Value does not fall within the expected range.

The problem was that I knew that setting the image was failing, but not why. I followed all the “best practices” I could find:

  • Saving the images to the Shared/ShellContent subfolder.
  • Changing the image size.
  • Changing the format from JPG to PNG.
  • Ensuring that the file was correctly being written to, and that all handles were properly closed.
  • Setting the Uri’s UriKind to UriKind.Absolute.

The problem persisted. Then, I found a common occurrence between all cases: it was only happening in low-end models. Specifically, those that had support for SD cards. So I went to the WMAppManifest.xml and checked Prevent deployment to SD cards in the Packaging tab.

The problem was gone. The LockScreen.SetImageUri function only fails if the app has been installed to an external SD card and you are trying to set an image saved to the application’s storage folder (ms-appdata:/// prefix). The ones packaged as content files (ms-appx:///) never fail!

And don’t ever bother trying to spot this bug using the emulator. While it allows you to simulate SD card support, it won’t fail there.

SharpDX.SimpleInitializer, an easy way of initializing SharpDX in your XAML projects

After working on some Windows Phone apps that required the usage of a DrawingSurface/DrawingSurfaceBackgroundGrid to perform Direct3D drawing, I have isolated some of the code in a standalone library for easily initialization of the Direct3D device, context and associated resources.

The library abstracts the initialization of Direct3D and transparently handles such cases as the control being resized (for example, a Windows Store application being snapped) and the device being lost or recreated (Windows Phone does this when sending the application to the foreground). The only dependency comes from SharpDX and it can be used in Windows Phone 8, Windows Phone 8.1 Silverlight, Windows Store 8.1 and Universal projects.

This is the workflow you should follow when using it:

  • When navigating to a page where the Direct3D drawing will be performed, instantiate a SharpDXContext object.
  • Subscribe to its DeviceReset and Render events to perform resource loading and drawing, respectively.
  • Call BindToControl passing the existing DrawingSurface, DrawingSurfaceBackgroundGrid, SwapChainPanel or SwapChainBackgroundPanel control.
  • The event Render will be raised whenever the control asks for a new frame, perform your drawing there using the D3DDevice and D3DContext properties.
  • When navigating away from the page, unsubscribe from the events and Dispose the SharpDXContext object.

You can download the library from NuGet, or take a look at the code on GitHub. Some sample projects that show how to properly manage the lifetime of the SharpDXContext object are available here.