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.
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):
- Analysis of the code created for us by the Windows Phone Direct3D App template
- Converting images to the .dds file format
- Loading resources asynchronously
Have fun coding, until next time!





C++? ... "Et tu, Brute?"
Yes, C++. It's not that bad actually :)
I still prefer C# with one of these two options you did not mention: SharpDX and Monogame.
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.
:p
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 :D
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
Thanks! that would be awesome :)
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)
SharpDX now supports WP8. They've also got the SharpDX.Toolkit, which is a port of DirectXTK to C#.
^^ Should have said "port of DirectXTK to .NET".
Great tutorial! Was wondering if there are plans of making more that will go into making a simple 2D game?
Yes, there are plans for exactly that, but they will not be moving as fast as I would want :)
Landscape mode?
Still working on that.
Thank you, exactly what I was looking for !
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!
Rattling wonderful beauty in this particular site,
I'd rate it 10 10.
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
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.
Hi, where do I free the memory from the Renderer, because it doesn't have a destructor, or it has a garbage collector?
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!
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!
Awesome! I am a former ruby rails and sharepoint guy so this is a exciting to learn! Thanks for all your tutorials!
Cheers,
John.
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!
Hello, I log on to your blogs daily. Your story-telling style is witty, keep
it up!
It would be nice if you could make a more in depth tutorial. I am having trouble with dealing with multiple sprites.
Never mind that was a dumb problem, but I'm now having trouble with rendering text.
guys,... C++ and Directx is the best one of the best option to develop games with good latency....however learning is quite cumbersome..