Getting Started with Direct3D on Windows Phone 8

One of my favorite things about XNA was the ability to just start Visual Studio, create a new project, and start adding game code. My purpose in the next few blog posts will be to try and make 2D game development using Direct3D on WP8 a bit more accessible (as I would like it) using any resources I can put my hands on.

Direct3D on Windows Phone 8

We’ve known for some time that Windows Phone 8 will support native development and Direct3D, and the SDK is finally here. Nokia has a nice little summary of other WP8 features on their developer site.

Some things to note about Direct3D on Windows Phone 8:

  • It’s useable through the DirectX11.1 API
  • It only support Feature Level 9.3
  • No Direct2D, no DirectWrite
  • No WIC (Windows Imaging Component)

The prospect of going to C++ and Direct3D might seem a little daunting (and rightfully so), but with a bit of courage, help, and guidance, it’s not that bad. Of course, there are lots of other options, if you feel like it, but they are beyond the scope of this blog post; XNA 4.0 is still supported in the Windows Phone 8 SDK, and I hear some engines like Unity, Cocos2D, Ogre3D are coming this way. And you can always look at SharpDX and Monogame, once they’ll support Windows Phone 8.

But let’s get back to Direct3D.

C++ refreshment

To use Direct3D, you’ll also need to write C++ code. If you’re just starting with C++, or if you took a long break and used C# for the last few years and need a refreshment, Michael B. McLaughlin wrote a very nice guide, which is available here and here. I thoroughly recommend reading it.

DirectXTK

While drawing a simple 2D sprite on the screen is not quite that easy with native DirectX as it was with XNA, some people are making a pretty strong effort to make this easier. Shawn Hargreaves and Chuck Walbourn have created a very nice open source project called DirectXTK. It already has support for SpriteBatch, SpriteFont, built-in Effects, PrimitiveBatch, Common States, and a few other cool things.

You can (and should) download it from it’s page on Codeplex, as I’ll be using it also in today’s sample.

Getting Started

I usually like to create a new project and start analyzing it, see what the default code does and understand every little thing that happens, but I know you might be here to build a bit more confidence that native Direct3D is not as scary as it looks, so I’ll leave the detailed analysis for sometime next week (I promise), and just start with a step-by-step tutorial of getting a 2D sprite on the screen.

1.Create a new project

Open Visual Studio 2012 (the Express version comes with the WP8 SDK), and under the “Visual C++” project templates, select Windows Phone, and create a new “Windows Phone Direct3D app (Native Only)”

2. Build and run it

You should see a colorful dizzily spinning cube. Since we want to focus on drawing 2D sprites using DirectXTK, let’s go ahead and remove all 3D code from the sample. Don’t worry, once we’ve done some 2D rendering and are feeling good enough about ourselves, we’ll come back and see what all this code does and how we can write it ourselves. All the dark magic is in CubeRenderer.h and CubeRenderer.cpp. If you go and clean it up completely, you should obtain the files below. Ignore all other classes and files.

I must admit, I am going a little overboard here, but it’s all for the sake of clarity and simplicity.

CubeRenderer.h

#pragma once
#include "Direct3DBase.h"

// This class no longer renders a simple spinning cube.
ref class CubeRenderer sealed : public Direct3DBase
{
public:
    CubeRenderer();

    // Direct3DBase methods.
    virtual void CreateDeviceResources() override;
    virtual void CreateWindowSizeDependentResources() override;
    virtual void Render() override;

    // Method for updating time-dependent objects.
    void Update(float timeTotal, float timeDelta);
};

CubeRenderer.cpp

#include "pch.h"
#include "CubeRenderer.h"

using namespace DirectX;
using namespace Microsoft::WRL;
using namespace Windows::Foundation;
using namespace Windows::UI::Core;

CubeRenderer::CubeRenderer() {
}

void CubeRenderer::CreateDeviceResources() {
    Direct3DBase::CreateDeviceResources();
}

void CubeRenderer::CreateWindowSizeDependentResources() {
    Direct3DBase::CreateWindowSizeDependentResources();
}

void CubeRenderer::Update(float timeTotal, float timeDelta) {
}

void CubeRenderer::Render()
{
    const float midnightBlue[] = { 0.098f, 0.098f, 0.439f, 1.000f };
    m_d3dContext->ClearRenderTargetView(
        m_renderTargetView.Get(),
        midnightBlue
    );

    m_d3dContext->ClearDepthStencilView(
        m_depthStencilView.Get(),
        D3D11_CLEAR_DEPTH,
        1.0f,
        0
    );

    m_d3dContext->OMSetRenderTargets(
        1,
        m_renderTargetView.GetAddressOf(),
        m_depthStencilView.Get()
    );
}

What we’re left with is a very spartan class. The single thing it does is clear the screen to the Midnight Blue color. And that’s just fine, since we now have a clean ground to start building on.

3. Add DirectXTK to the project

Once you’ve downloaded the latest release from codeplex, unzip it, and place it in the same directory where you created the above project. Now it’s time to add it to the solution, by right clicking on the Solution then Add-> Existing Project -> Choose “DirectXTK_WindowsPhone8.vcxproj“.

To link it to your phone project, right click on the phone project, choose References…, and then click the Add New Reference… button. From the Solution/Projects tab, select DirectXTK_WindowsPhone8

There’s still a few things more to do. The steps bellow will need to be done for all build configurations you want to use: Debug, Release, Win32 and ARM. Yes, you’ll need to do it for Win32 also, because apparently when you want to deploy to an emulator, Visual Studio will switch to the Win32 build configuration.

  • Add the DirectXTK/inc directory to: Property Pages -> C/C++ ->Additional Include Directories

  • Add dxguid.lib to: Property Pages -> Linker -> Input -> Additional Dependencies

4. Add the image to your project.

One of the features of DirectXTK includes two ways to load textures in your game: the DDSTextureLoader, and the WICTextureLoader.

The WICTextureLoader allows you to load any image format, including .png, .jpg, .bmp, bu, as mentioned at the beginning of this post, the required components are not available on Windows Phone 8.

No worries, we will use DDSTextureLoader, which requires the images to be in the .dds format. In a few days, we’ll take a look at what options we have for converting our normal images to .dds manually or automatically. For now, just download CatTexture.dds, copy it to your project’s directory, and include it in the project (Add…-> Existing Item…). It contains Rhys, the famous cat of Shawn Hargreaves.

Don’t download this one, this is just a preview.

Download here: CatTexture.dds

When building, the file will be automatically copied into the .xap archive.

5. Creating the SpriteBatch and loading the texture

Go to CubeRenderer.h (or whatever else you might have renamed it to), and add two members to it, one for the SpriteBatch and one for the texture.

[...]
#include
#include

ref class CubeRenderer sealed : public Direct3DBase
{
	[...] //rest of existing stuff
	std::unique_ptr m_spriteBatch;
	ID3D11ShaderResourceView* m_catTexture;
};

Now go in CubeRenderer.cpp, and add the following code in the CreateDeviceResources method.

void CubeRenderer::CreateDeviceResources()
{
    Direct3DBase::CreateDeviceResources();
    // Create the SpriteBatch
    m_spriteBatch = std::unique_ptr(new SpriteBatch(m_d3dContext.Get()));

    // Load the CatTexture
    DX::ThrowIfFailed(
		CreateDDSTextureFromFile(m_d3dDevice.Get(),
					L"CatTexture.dds",
					NULL,
					&m_catTexture,
					NULL)
		);
}

This will load the texture from CatTexture.dds into m_catTexture, but it will do it synchronously (i.e. the game will wait for the texture to be loaded before continuing out of this method). This is not ideal when you’ll have more resources to load, but for now we’ll keep it like this for simplicity. In a later article, we will look at loading your resources asynchronously, so provide a better user experience.

6. Drawing the cat on the screen

This one will seem very familiar if you have ever used XNA before. In the Render method, add these lines at the end.

m_spriteBatch->Begin();
m_spriteBatch->Draw(m_catTexture, XMFLOAT2(50, 50));
m_spriteBatch->End();

This starts a new spritebatch, draws the cat at position (50,50) on the screen, and ends the spritebatch, causing it to draw on the screen.


The end, for now

So… drawing a sprite on the screen… It might not seem like much of an achievement, but it’s a beginning, upon which we’ll build in the next few blog posts.

You can download the full sample here: BasicDirect3DApp.zip

Throughout the article, I made several promises about the things that will be explained later on. I put them here again for accountability, and for linking to them when they come online (not necessarily in this order):

Have fun coding, until next time!

  • http://amapplease.blogspot.com Pete

    C++? … “Et tu, Brute?”

  • Catalin Zima

    Yes, C++. It’s not that bad actually 🙂

  • http://amapplease.blogspot.com Pete

    I still prefer C# with one of these two options you did not mention: SharpDX and Monogame.

  • Catalin Zima

    I wanted to mention Monogame, but at this moment it does not support WP8. I’m sure it will, in the future, tough. I updated to article to mention these, anyway.

  • http://amapplease.blogspot.com Pete

    :p

  • Matt

    Hey,
    I’ve been searching for a while and cannot find how to rotate the screen to a landscape orientation. Can you write a tutorial, or just the source code to do so?
    Thanks 😀

  • Catalin Zima


    Matt:

    Hey,
    I’ve been searching for a while and cannot find how to rotate the screen to a landscape orientation. Can you write a tutorial, or just the source code to do so?
    Thanks

    Hi Matt,

    With a quick search I found some pointers, but nothing clear enough, so I’ll try to do a small sample next week.

    Regards,
    Catalin

  • Matt

    Thanks! that would be awesome 🙂

  • Tom

    Thank you for the awesome tutorial 🙂 I shall look forward to any future installments.

    Would it be possible to do one with the basic geometries? (spinning teapots)

  • Dave Hunt

    SharpDX now supports WP8. They’ve also got the SharpDX.Toolkit, which is a port of DirectXTK to C#.

  • Dave Hunt

    ^^ Should have said “port of DirectXTK to .NET”.

  • Pingback: Catalin's Game Development Blog » Converting textures to .dds

  • David

    Great tutorial! Was wondering if there are plans of making more that will go into making a simple 2D game?

  • Catalin Zima

    Yes, there are plans for exactly that, but they will not be moving as fast as I would want 🙂

  • Brandon

    Landscape mode?

  • Catalin Zima

    Still working on that.

  • Pingback: Catalin's Game Development Blog » Dissecting the empty Windows Phone Direct3D App template

  • Aybe

    Thank you, exactly what I was looking for !

  • http://Www.prairiestateoutdoors.com/member/227662 Cole

    Hello, you useful to write great, but the last
    few posts are kinda boring… I miss your super writings.
    Past several posts are merely somewhat outside track! occur!

  • http://www.theverve.co.uk/index.php?/forums/member/871836/ Hildegarde

    Rattling wonderful beauty in this particular site,
    I’d rate it 10 10.

  • Milton

    Hi this is good tutorial for beginners. Few things i wanted to do with directx on wp8 are
    – i want to display fps at which frames are rendered,and want to use the app for gfx testing
    – marble maze sample has this feature, but how can i use this feature into cube render template?
    – it would be great if you can share such sample if there is any

  • Alex

    Hi, I tried your piece of code and it raises an awkward exception, like this:

    First-chance exception at 0x77D3277C in MyExample.exe: Microsoft C++ exception: Platform::COMException ^ at memory location 0x00C2E4C0. HRESULT:0x80070002

    PS: I’ve also tried the tutorial from codeplex, with DirectXTK and there seems to be a problem with the drawing, I think.

    Can you please help me? Thanks.

  • Alex

    Hi, where do I free the memory from the Renderer, because it doesn’t have a destructor, or it has a garbage collector?

  • http://www.kiwibox.com/Reastill/blog/entry/107973437/devido-as-camadas-sedimentares-sobrejacentes-a-camada-org/?pPage=0 Importação da China

    Hello! Quick question that’s totally off topic. Do you know how to make your site mobile friendly? My web site looks weird when browsing from my iphone. I’m trying to find a template or plugin
    that might be able to correct this issue. If you have
    any recommendations, please share. Appreciate it!

  • http://highcountrygardener.blogspot.com/2011/08/head-colds-and-weeds-rev.html Buy Steroid Powders

    This is very interesting, You are a very skilled blogger.
    I’ve joined your feed and look forward to seeking more of your magnificent post. Also, I have shared your website in my social networks!

  • http://sharepointedinburgh.weebly.com John

    Awesome! I am a former ruby rails and sharepoint guy so this is a exciting to learn! Thanks for all your tutorials!

    Cheers,

    John.

  • http://www.clareified.com/2013/05/28/empire-state-laid-low/ 1

    Whats up this is somewhat of off topic but I was wanting to
    know if blogs use WYSIWYG editors or if you have to manually code with HTML.
    I’m starting a blog soon but have no coding knowledge so I wanted to get advice from someone
    with experience. Any help would be enormously appreciated!

  • http://iwantmorefood.com/2010/02/05/who-takes-pictures-of-flowers-macro-button-should-be-food/ Selena

    Hello, I log on to your blogs daily. Your story-telling style is witty, keep
    it up!

  • berock212

    It would be nice if you could make a more in depth tutorial. I am having trouble with dealing with multiple sprites.

  • berock212

    Never mind that was a dumb problem, but I’m now having trouble with rendering text.

  • Vellanki Ganesh

    guys,… C++ and Directx is the best one of the best option to develop games with good latency….however learning is quite cumbersome..