Quantcast
Channel: catalinzima.com
Viewing all articles
Browse latest Browse all 31

Getting Started with Direct3D on Windows Phone 8

$
0
0

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!


Viewing all articles
Browse latest Browse all 31

Latest Images

Trending Articles





Latest Images