coderox

How to get started with game programming on Windows 8

Tags: Windows 8,DirectX,C++

I've been a passionate game developer for way too many years now and when XNA was introduced (and Managed DirectX before that) I was mighty impressed with the abstractions created and how easy it was to create both simple and advanced games with managed code for Xbox 360, Windows and later the Windows Phone platform. I was equally depressed when it was announced (or actually wasn't announced) that XNA so far hasn't been considered a solution for building games on Windows 8. But I can understand some of the reasoning behind the strategy, and I totally appreciate the efforts being made in creating the latest release of DirectX with it's support for Hull Shader, Compute Shader, Tesselation and all other goodies that we can leverage. And I've always considered game development to be the primary reason for me to keep my skills in C++ up to date so going native when building games for Windows 8 is for me an accepted challenge instead of a show stopper! But I also understand that not all have the same background in C++ and native development and hence this post on how to get started quite rapidly to build 2D games for Windows 8 with something that might look quite familiar if you have an XNA background.

But it's going to be quite a ride for one who haven't done C++ development in Visual Studio earlier, so here we go:

Before you get started this post requires you to have the following installed and running:

  • Windows 8 Consumer Preview
  • Visual Studio 2011

New ProjectFirst, we are going to use something called the DirectX Tool Kit or simply DirectXTK to mimic the behavior of the SpriteBatch. The DirectXTK includes a native implementation of the SpriteBatch created by the amazing Shawn Hargreaves who also have implemented native versions of the configurable effects as well as a SpriteFont component to render text. I hope to look into those in future posts. Download the DirectXTK and open and build the solution file "DirectXTK_11_Metro.sln" in Visual Studio 2011. Hopefully everything runs smoothly and you now have the binaries to get started.

Now create a new Direct3D Application in Visual Studio and name it appropriately. This project template is a bit too much for the purpose but still it's the easiest way to get started in my opinion without bothering with the plumbing in getting a Direct3D Metro application created. There is some documentation on the Windows Dev Center around that topic and I hope to be able to write about it to in the future. What you need to worry about is the two files CubeRenderer.h and CuberRenderer.cpp.

But first we need to make sure we can use the library we created in the previous step. Right click on the project in the solution explorer and select properties. Then find the Configuration Properties | Linker | Input section of the property pages window. In the "Additional Dependencies" you need to make sure that the DirectXTK.lib is included. Hit the combo-box down arrow and edit the configuration. On a new line in the "Additional Dependencies" dialog, insert the entire path (including the .lib-filename) to the libray. In my case this is: "c:ProjectsWindows 8DirectXDirectXTKBinMetroWin32DebugDirectXTK.lib". Hit OK to close the dialog.

Additional Include Directories Additional DependenciesNow we also must include some other files from the DirectXTK and that is also done in the Property Pages window. We highlight the Configuration Properites | C/C++ section and in a similar manner as above we make sure that the "Additional Include Directories" include the path to the Inc-folder that was included in the DirectXTK download. In my case I add the following: "c:ProjectsWindows 8DirectXDirectXTKInc", close the dialog and now it's time to delete some code!

Begin by cleaning up the CubeRenderer.h to the following:

#pragma once

#include <wrl.h>
#include <memory>

#include "Direct3DBase.h"
#include <DirectXMath.h>

ref class CubeRenderer : public Direct3DBase
{
public:
    CubeRenderer();
    ~CubeRenderer();
    virtual void CreateDeviceResources() override;
    virtual void Render() override;
    void Update(float timeTotal, float timeDelta);

private:

};

And the CubeRenderer.cpp can be cleaned as much as follows:

#include "pch.h"
#include "CubeRenderer.h"
#include <DirectXMath.h>

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

CubeRenderer::CubeRenderer() 
{
}

CubeRenderer::~CubeRenderer()
{
}

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

}

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

void CubeRenderer::Render()
{
    // clear
    m_d3dContext->OMSetRenderTargets(
        1,
        m_renderTargetView.GetAddressOf(),
        m_depthStencilView.Get()
        );

    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
        );
}

Now we need two variables in this sample, one texture to draw and one instance of the SpriteBatch. We define them as follows in CubeRenderer.h:

private:
    ID3D11ShaderResourceView* texture;
    std::unique_ptr<DirectX::SpriteBatch> spriteBatch;

Don't forget that you also need to add the following #include line above:

#include "SpriteBatch.h"

Now we create instances of these variables and then it's off to render them. We turn to the CubeRenderer.cpp and update the method CreateDeviceResources() as follows:

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

    spriteBatch = std::unique_ptr<DirectX::SpriteBatch>(new DirectX::SpriteBatch(m_d3dContext.Get()));

    DX::ThrowIfFailed(
        CreateWICTextureFromFile(m_d3dDevice.Get(),m_d3dContext.Get(),L"Assets//Logo.png",NULL,&texture,NULL)
    );      
}

It's unfortunately different syntaxes for the creation of the instances. The one line that might require the most explanation is the line that creates the texture. We're leveraging another feature from the DirectXTK library, and hence we also must add the following line of code to the file, preferably among the other #include-directives:

#include "WICTextureLoader.h"

The CreateWICTextureFromFile loads the specified file and creates the instance for us, let's just keep that in mind, because there's some advanced possibilities with the WICTextureLoader that I won't go into here.

The last piece of code we need to add will look the most familiar to us XNA-developers. Add the following three lines of code to the end of the Render() method:

spriteBatch->Begin();
spriteBatch->Draw(texture, XMFLOAT2(0,0));
spriteBatch->End();

Now you should be able to build and run this simple sample and get a very simple image rendered on screen. And most likely you also have a very tiny base for further development to get you started in porting games from XNA and C# to native DirectX and C++.

1 comment on “How to get started with game programming on Windows 8”

  1. Ronny Thörnvall said

    Great post - are there any changes one chould keep in mind when trying to do this in Visual Studio 2012? I see that the Direct3D template in C++ is still there. :-) (Also, thanks for the tips about MonoGame). :-) Maybe I should update my C++ skills (learn from scratch once again I'm afraid). :-)

Add a Comment