Monday, 23 July 2012

XNA Samples in C++

So I was looking at one of the 2D samples on the creators club site, namely this one, where MS show how to use XNA to create a quick 2D shooter. I thought this would be a good test to see how far I am with my library as far as my sprite batch code goes, and hoped it would show up a few issues (which thankfully it did)

Now, due to my poor C++ I still have a number of issues, so I wont be putting this library up yet, but I plan to take take the existing creators club samples and use them and their assets (hope MS don’t mind) to do samples for my library.

I am also hoping to get working samples for Windows 8 Metro applications too, time willing.

In the mean time, take a look at where I am so far with this first sample. As you can see in the clip I have animated sprites now as well, still no sound, music is played by the clip and is not in game music, but that’s just another on the TODO list :P All assets in the clip are rendered using my C++ library, but all the assets are from the XNA sample as is.

As ever your comments are more than welcome :)

Thursday, 19 July 2012

RandomchaosDX11Lib & SpriteBatch

So, since the last post, I have started to create a XNA like library for me to use while learning all this new gubbins. I know Shawn has already started a DXToolKit, and I have to say I have lifted a tone of code from it to get my library working, but to get it working in what I had already written was proving to be difficult due to my total lack of C++ knowledge, but as this is for my experiments, it won’t hurt none me writing my own and learning from Shawn along the way.

So, as it stands at the moment, I have wrapped all I have covered so far in the library and you can now create a derived instance of RCGame (similar to our Game class in XNA) and start adding stuff to the Components list and now draw 2D using the SpriteBatch.

Some of you will be happy I am looking at the 2D stuff, it’s still a long way off done, and I am sure won’t be as robust as Shawn's stuff, but I am learning from it, and hope you guys can, as ever benefit from what I am picking up (or not in some cases :P)

Tuesday, 10 July 2012

Putting it all together

So, we have a pretty simple framework now for defining objects in our game world, but we really need a class for things we want to render in the world, so we will create the RC3DBaseDrawableObject class, as before, create a class and call it RC3DBaseDrawableObject and set it’s base class as IDrawable
image
We also want this object to be updatable and have all the goodies we have in our RC3DBaseObject, so we will also derive from that class, you RC3DBaseDrawableObject.h file should look like this now
#pragma once
#include "interfaces.h"
#include "RC3DBaseObject.h"

class RC3DBaseDrawableObject : public RC3DBaseObject, public IDrawable
{
public:
    RC3DBaseDrawableObject(void);
    ~RC3DBaseDrawableObject(void);
};
Now, all we have to add is a pure virtual (in C# a virtual method) stub for the draw call to implement the IDrawable interface and, as we are deriving from RC3DBaseObject, which in turn implements the IUpdatable interface, we have to clear up any ambiguity (remember, interfaces in C++ are actually classes) between the calls and ensure the Update method of RC3DBaseObject is called, having done this your complete header file will look like this
#pragma once
#include "interfaces.h"
#include "RC3DBaseObject.h"

class RC3DBaseDrawableObject : public RC3DBaseObject, public IDrawable
{
public:
    RC3DBaseDrawableObject(void);
    ~RC3DBaseDrawableObject(void);

    virtual void Draw(float time, ID3D11DeviceContext* context, IRC3DCamera* camera) = 0;
    
    using RC3DBaseObject::Update;
};
All our basic elements are in place now, but we need a mechanism to manage this framework, so we are going to now create a basic Game class, this class wont be all singing and all dancing, like most of the objects in these initial posts, but it will get us to a position where we can render objects.
Before we create this game class, we will quickly create a keyboard manager class, this will help manage user input, it works just the same as in the earlier posts, but we can control it from within our game class.
Create a class called RCKeyboardStateManager with no base class. We will put in the header all the elements we need to manage the keyboard
#pragma once
#include <dinput.h>

class RCKeyboardStateManager
{
protected:
    LPDIRECTINPUTDEVICE8 keyboard;
    char keyboardState[256];

public:
    RCKeyboardStateManager(void);
    ~RCKeyboardStateManager(void);

    virtual LPDIRECTINPUTDEVICE8 InitializeKeyboard(HWND hwnd);

    virtual char* getKeyboardState();    
    virtual void readKeyboard();
    LPDIRECTINPUTDEVICE8 getKeyboard();
};
Then populate the cpp file with the methods we have defined
#include "RCKeyboardStateManager.h"


RCKeyboardStateManager::RCKeyboardStateManager(void){ }


RCKeyboardStateManager::~RCKeyboardStateManager(void){ }

LPDIRECTINPUTDEVICE8 RCKeyboardStateManager::InitializeKeyboard(HWND hwnd)
{
    LPDIRECTINPUT8 p_dx_KeybObject;
    
    DirectInput8Create(GetModuleHandle(NULL), DIRECTINPUT_VERSION, IID_IDirectInput8, (void**)&p_dx_KeybObject, NULL);
    p_dx_KeybObject->CreateDevice(GUID_SysKeyboard, &keyboard, NULL);

    keyboard->SetDataFormat(&c_dfDIKeyboard);
    keyboard->SetCooperativeLevel(hwnd, DISCL_BACKGROUND|DISCL_FOREGROUND|DISCL_NONEXCLUSIVE);
    keyboard->Acquire();

    return keyboard;
}

char* RCKeyboardStateManager::getKeyboardState()
{
    return keyboardState;
}

void RCKeyboardStateManager::readKeyboard()
{
    keyboardState[0] = '\0';
    HRESULT res = keyboard->GetDeviceState(sizeof(keyboardState),(LPVOID)&keyboardState);        
}

LPDIRECTINPUTDEVICE8 RCKeyboardStateManager::getKeyboard()
{
    return keyboard;
}
We will now create a class called RC3DGame, and this class will not derive or implement anything else. In our header we will have the following includes
#include <D3D11.h>
#include <D3DX11.h>
#include <d3dcompiler.h>
#include <xnamath.h>
#include <vector>

#include "interfaces.h"
#include "RC3DGraphicsDevice.h"
#include "RC3DBaseDrawableObject.h"
#include "RC3DBaseObject.h"
#include "RCKeyboardStateManager.h"
Some we have seen before, d3dcompiler.h is used to compile the shader we will use, xnamath.h (yay! XNA!) has all the vector and matrix math goodies we need, the vector header is part of the standard template library and is anice way of managing collections of objects safely, the rest are our own headers.
We are now going to define a number of methods that we will use in our game loop (this will still live out side of the Game class for this post), we also need a graphics device, and a keyboard manager. Our RCGame.h file should now look like this
#pragma once
#include <D3D11.h>
#include <D3DX11.h>
#include <d3dcompiler.h>
#include <xnamath.h>
#include <vector>

#include "interfaces.h"
#include "RC3DGraphicsDevice.h"
#include "RC3DBaseDrawableObject.h"
#include "RC3DBaseObject.h"
#include "RCKeyboardStateManager.h"


class RC3DGame
{
public:
    RC3DGame(void);
    ~RC3DGame(void);

    // GraphicsDevice
    RC3DGraphicsDevice GraphicsDevice;

    // Keyboard manager
    RCKeyboardStateManager KeyboardManager;

    // Method to initialize the window
    void Initialize(LPCTSTR str_Title,int int_XPos, int int_YPos, int int_Width, int int_Height, WNDPROC WinProc, int colorBrush = COLOR_BTNFACE);
    
    void Update(float time, std::vector<IUpdateable*>* updateambles);    

    // Draw call
    void Draw(float time, IRC3DCamera* camera, std::vector<IDrawable*>* drawables);
    
    HRESULT CompileShaderFromFile( WCHAR* szFileName, LPCSTR szEntryPoint, LPCSTR szShaderModel, ID3DBlob** ppBlobOut );
};

 

Game Initialize

And now to the function bodies, lets take a look at the Initialize method first
void RC3DGame::Initialize(LPCTSTR str_Title,int int_XPos, int int_YPos, int int_Width, int int_Height, WNDPROC WinProc, int colorBrush)
{
    GraphicsDevice.InitializeWindow(str_Title,int_XPos, int_YPos, int_Width, int_Height, WinProc, colorBrush);    
    GraphicsDevice.Initialize();

    KeyboardManager.InitializeKeyboard(GraphicsDevice.getWindowHandle());
}
Basically we are initializing the window, then the device, then the keyboard manager

Game Update

void RC3DGame::Update(float time, std::vector<IUpdateable*>* updateambles)
{
    // Componente update
    for(auto c = updateambles->begin();c != updateambles->end();c++)
    {
        (*c)->Update(time);
    }

    KeyboardManager.readKeyboard();
}
In her we use the vector to iterate through our IUpdatable objects and call there update methods, we then get the keyboard input.

Game Draw

void RC3DGame::Draw(float time,IRC3DCamera* camera, std::vector<IDrawable*>* drawables)
{
    
    GraphicsDevice.Clear(XMFLOAT4( 0.392156862745098f, 0.5843137254901961f, 0.9294117647058824f, 1.0f),D3D11_CLEAR_DEPTH,1.0f,0);
    
    for(auto c = drawables->begin();c != drawables->end();c++)
    {
        (*c)->Draw(0,GraphicsDevice.getDeviceContext(),camera);
    }
            
    
    GraphicsDevice.Present( 0, 0 );
}
First we clear the device, then we iterate through out vector of IDrawables and call there draw calls, and finally present to the device.

Game CompileShaderFromFile

HRESULT RC3DGame::CompileShaderFromFile( WCHAR* szFileName, LPCSTR szEntryPoint, LPCSTR szShaderModel, ID3DBlob** ppBlobOut )
{
    HRESULT hr = S_OK;

    DWORD dwShaderFlags = D3DCOMPILE_ENABLE_STRICTNESS;
#if defined( DEBUG ) || defined( _DEBUG )
    // Set the D3DCOMPILE_DEBUG flag to embed debug information in the shaders.
    // Setting this flag improves the shader debugging experience, but still allows
    // the shaders to be optimized and to run exactly the way they will run in
    // the release configuration of this program.
    dwShaderFlags |= D3DCOMPILE_DEBUG;
#endif

    ID3DBlob* pErrorBlob;
    hr = D3DX11CompileFromFile( szFileName, NULL, NULL, szEntryPoint, szShaderModel,
        dwShaderFlags, 0, NULL, ppBlobOut, &pErrorBlob, NULL );
    if( FAILED(hr) )
    {
        if( pErrorBlob != NULL )
            OutputDebugStringA( (char*)pErrorBlob->GetBufferPointer() );
        if( pErrorBlob ) pErrorBlob->Release();
        return hr;
    }
    if( pErrorBlob ) pErrorBlob->Release();

    return S_OK;
}
This method has been totally lifted from the SDX tutorials, but not too difficult to see what’s going on here, we will see this method in action later.
We now have a game class we can use to update and render objects in the world, so why don’t we create an object class that can then be actually rendered.
I am going to take some more from the SDK tutorial to build this class, as we have not looked at loading mesh’s in yet, we will define our own geometry and use that to render a cube, we will now create a TestCube class that will derive from RC3DBaseDrawableObject to do this.
image
We also want to include the the RCGame.h and Interfaces.h in here as we will be using them. We are also going to create a number of member variables that we can then use to set up and render our cube. We will also add an Initialize method and implement the derived Draw call. Your TestCube.h file should look something like this
#pragma once
#include <D3D11.h>
#include <D3DX11.h>
#include <xnamath.h>

#include "rc3dbasedrawableobject.h"
#include "RC3DGame.h"
#include "Interfaces.h"


class TestCube : public RC3DBaseDrawableObject
{
protected:
    ID3D11InputLayout* pVertexLayout;

    ID3D11VertexShader* pVertexShader;
    ID3D11PixelShader*  pPixelShader;

    ID3D11Buffer* pVertexBuffer;
    ID3D11Buffer* pIndexBuffer;

    ID3D11Buffer* pCBNeverChanges;
    ID3D11Buffer* pCBChangeOnResize;
    ID3D11Buffer* pCBChangesEveryFrame;

    ID3D11ShaderResourceView* pTextureRV;

    ID3D11SamplerState* pSamplerLinear;
public:
    TestCube(void);
    ~TestCube(void);

    RC3DGame* game;

    XMFLOAT4 Color;

    void Initialize(ID3D11Device* device );
    void Draw(float time, ID3D11DeviceContext* context, IRC3DCamera* camera);
};
The ID3D11InputLayout describes the vertex structure and we will define and load that up in our cpp file
We then have references to the vertex and pixel shaders we are going to use to render this object.
We then have our vertex and index buffer, again will be defined later.
We then have a number of Buffers, these are new to me as they are part of the DirectX 11 API (remember I am coming from DirectX 9c!) and I will explain my understanding of them later.
Lastly we have a texture and a sampler reference for it.
We now have a definition, as ever, onto the function bodies, but wait, we still need some data definitions, the input layout, the vertex and index buffers, all these I have put at the top of the TestCube.cpp file, this makes them global to the class and so can be accessed across methods. Really I should have not been lazy and set them up right in the class, but I am itching to get something rendered :P
So, at the top of the TestCube.cpp file we have this lump of variables
D3D11_INPUT_ELEMENT_DESC layout[] =
    {
        { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
        { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 },
    };

struct SimpleVertex
{
    XMFLOAT3 Pos;
    XMFLOAT2 Tex;
};

struct CBChangeOnResize
{
    XMMATRIX mProjection;
};

struct CBChangesEveryFrame
{
    XMMATRIX mWorld;
    XMFLOAT4 vMeshColor;
    XMMATRIX mView;
};

SimpleVertex vertices[] =
    {
        { XMFLOAT3( -0.5f, 0.5f, -0.5f ), XMFLOAT2( 0.0f, 0.0f ) },
        { XMFLOAT3( 0.5f, 0.5f, -0.5f ), XMFLOAT2( 1.0f, 0.0f ) },
        { XMFLOAT3( 0.5f, 0.5f, 0.5f ), XMFLOAT2( 1.0f, 1.0f ) },
        { XMFLOAT3( -0.5f, 0.5f, 0.5f ), XMFLOAT2( 0.0f, 1.0f ) },

        { XMFLOAT3( -0.5f, -0.5f, -0.5f ), XMFLOAT2( 0.0f, 0.0f ) },
        { XMFLOAT3( 0.5f, -0.5f, -0.5f ), XMFLOAT2( 1.0f, 0.0f ) },
        { XMFLOAT3( 0.5f, -0.5f, 0.5f ), XMFLOAT2( 1.0f, 1.0f ) },
        { XMFLOAT3( -0.5f, -0.5f, 0.5f ), XMFLOAT2( 0.0f, 1.0f ) },

        { XMFLOAT3( -0.5f, -0.5f, 0.5f ), XMFLOAT2( 0.0f, 0.0f ) },
        { XMFLOAT3( -0.5f, -0.5f, -0.5f ), XMFLOAT2( 1.0f, 0.0f ) },
        { XMFLOAT3( -0.5f, 0.5f, -0.5f ), XMFLOAT2( 1.0f, 1.0f ) },
        { XMFLOAT3( -0.5f, 0.5f, 0.5f ), XMFLOAT2( 0.0f, 1.0f ) },

        { XMFLOAT3( 0.5f, -0.5f, 0.5f ), XMFLOAT2( 0.0f, 0.0f ) },
        { XMFLOAT3( 0.5f, -0.5f, -0.5f ), XMFLOAT2( 1.0f, 0.0f ) },
        { XMFLOAT3( 0.5f, 0.5f, -0.5f ), XMFLOAT2( 1.0f, 1.0f ) },
        { XMFLOAT3( 0.5f, 0.5f, 0.5f ), XMFLOAT2( 0.0f, 1.0f ) },

        { XMFLOAT3( -0.5f, -0.5f, -0.5f ), XMFLOAT2( 0.0f, 0.0f ) },
        { XMFLOAT3( 0.5f, -0.5f, -0.5f ), XMFLOAT2( 1.0f, 0.0f ) },
        { XMFLOAT3( 0.5f, 0.5f, -0.5f ), XMFLOAT2( 1.0f, 1.0f ) },
        { XMFLOAT3( -0.5f, 0.5f, -0.5f ), XMFLOAT2( 0.0f, 1.0f ) },

        { XMFLOAT3( -0.5f, -0.5f, 0.5f ), XMFLOAT2( 0.0f, 0.0f ) },
        { XMFLOAT3( 0.5f, -0.5f, 0.5f ), XMFLOAT2( 1.0f, 0.0f ) },
        { XMFLOAT3( 0.5f, 0.5f, 0.5f ), XMFLOAT2( 1.0f, 1.0f ) },
        { XMFLOAT3( -0.5f, 0.5f, 0.5f ), XMFLOAT2( 0.0f, 1.0f ) },
    };

WORD indices[] =
    {
        3,1,0,
        2,1,3,

        6,4,5,
        7,4,6,

        11,9,8,
        10,9,11,

        14,12,13,
        15,12,14,

        19,17,16,
        18,17,19,

        22,20,21,
        23,20,22        
    };
layout describes the vertex structure to the shader pipeline and in XNA this would be the VertexDeclaration
SimpleVertex is the vertex structure we will use for the cube’s verts
CBChangeOnResize is a structure that is reloaded on screen resize
CBChangesEveryFrame describes what will be passed to the shader every frame
vertices and index are what will fill the vertex and index buffers to render the cube.
Our TestCube.cpp now looks like this after we have populated the member functions
#include "TestCube.h"


D3D11_INPUT_ELEMENT_DESC layout[] =
    {
        { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
        { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 },
    };

struct SimpleVertex
{
    XMFLOAT3 Pos;
    XMFLOAT2 Tex;
};

struct CBChangeOnResize
{
    XMMATRIX mProjection;
};

struct CBChangesEveryFrame
{
    XMMATRIX mWorld;
    XMFLOAT4 vMeshColor;
    XMMATRIX mView;
};

SimpleVertex vertices[] =
    {
        { XMFLOAT3( -0.5f, 0.5f, -0.5f ), XMFLOAT2( 0.0f, 0.0f ) },
        { XMFLOAT3( 0.5f, 0.5f, -0.5f ), XMFLOAT2( 1.0f, 0.0f ) },
        { XMFLOAT3( 0.5f, 0.5f, 0.5f ), XMFLOAT2( 1.0f, 1.0f ) },
        { XMFLOAT3( -0.5f, 0.5f, 0.5f ), XMFLOAT2( 0.0f, 1.0f ) },

        { XMFLOAT3( -0.5f, -0.5f, -0.5f ), XMFLOAT2( 0.0f, 0.0f ) },
        { XMFLOAT3( 0.5f, -0.5f, -0.5f ), XMFLOAT2( 1.0f, 0.0f ) },
        { XMFLOAT3( 0.5f, -0.5f, 0.5f ), XMFLOAT2( 1.0f, 1.0f ) },
        { XMFLOAT3( -0.5f, -0.5f, 0.5f ), XMFLOAT2( 0.0f, 1.0f ) },

        { XMFLOAT3( -0.5f, -0.5f, 0.5f ), XMFLOAT2( 0.0f, 0.0f ) },
        { XMFLOAT3( -0.5f, -0.5f, -0.5f ), XMFLOAT2( 1.0f, 0.0f ) },
        { XMFLOAT3( -0.5f, 0.5f, -0.5f ), XMFLOAT2( 1.0f, 1.0f ) },
        { XMFLOAT3( -0.5f, 0.5f, 0.5f ), XMFLOAT2( 0.0f, 1.0f ) },

        { XMFLOAT3( 0.5f, -0.5f, 0.5f ), XMFLOAT2( 0.0f, 0.0f ) },
        { XMFLOAT3( 0.5f, -0.5f, -0.5f ), XMFLOAT2( 1.0f, 0.0f ) },
        { XMFLOAT3( 0.5f, 0.5f, -0.5f ), XMFLOAT2( 1.0f, 1.0f ) },
        { XMFLOAT3( 0.5f, 0.5f, 0.5f ), XMFLOAT2( 0.0f, 1.0f ) },

        { XMFLOAT3( -0.5f, -0.5f, -0.5f ), XMFLOAT2( 0.0f, 0.0f ) },
        { XMFLOAT3( 0.5f, -0.5f, -0.5f ), XMFLOAT2( 1.0f, 0.0f ) },
        { XMFLOAT3( 0.5f, 0.5f, -0.5f ), XMFLOAT2( 1.0f, 1.0f ) },
        { XMFLOAT3( -0.5f, 0.5f, -0.5f ), XMFLOAT2( 0.0f, 1.0f ) },

        { XMFLOAT3( -0.5f, -0.5f, 0.5f ), XMFLOAT2( 0.0f, 0.0f ) },
        { XMFLOAT3( 0.5f, -0.5f, 0.5f ), XMFLOAT2( 1.0f, 0.0f ) },
        { XMFLOAT3( 0.5f, 0.5f, 0.5f ), XMFLOAT2( 1.0f, 1.0f ) },
        { XMFLOAT3( -0.5f, 0.5f, 0.5f ), XMFLOAT2( 0.0f, 1.0f ) },
    };

WORD indices[] =
    {
        3,1,0,
        2,1,3,

        6,4,5,
        7,4,6,

        11,9,8,
        10,9,11,

        14,12,13,
        15,12,14,

        19,17,16,
        18,17,19,

        22,20,21,
        23,20,22        
    };

TestCube::TestCube(void)
{
    Color = XMFLOAT4(1,1,1,1);
}

TestCube::~TestCube(void){ }

void TestCube::Initialize(ID3D11Device* device)
{
    
    // Compile the vertex shader
    ID3DBlob* pVSBlob = NULL;
    HRESULT hr = game->CompileShaderFromFile( L"Tutorial07.fx", "VS", "vs_4_0", &pVSBlob );
    if( FAILED( hr ) )
    {
        MessageBox( NULL,
                    L"The FX file cannot be compiled.  Please run this executable from the directory that contains the FX file.", L"Error", MB_OK );
        return;
    }

    // Create the vertex shader
    hr = device->CreateVertexShader( pVSBlob->GetBufferPointer(), pVSBlob->GetBufferSize(), NULL, &pVertexShader );
    if( FAILED( hr ) )
    {    
        pVSBlob->Release();
        return;
    }

    UINT numElements = ARRAYSIZE( layout );

    // Create the input layout
    hr = device->CreateInputLayout( layout, numElements, pVSBlob->GetBufferPointer(),
                                          pVSBlob->GetBufferSize(), &pVertexLayout );
    pVSBlob->Release();

    // Compile the pixel shader
    ID3DBlob* pPSBlob = NULL;
    hr = game->CompileShaderFromFile( L"Tutorial07.fx", "PS", "ps_4_0", &pPSBlob );
    if( FAILED( hr ) )
    {
        MessageBox( NULL,
                    L"The FX file cannot be compiled.  Please run this executable from the directory that contains the FX file.", L"Error", MB_OK );
        return;
    }

    // Create the pixel shader
    hr = device->CreatePixelShader( pPSBlob->GetBufferPointer(), pPSBlob->GetBufferSize(), NULL, &pPixelShader );
    pPSBlob->Release();
    if( FAILED( hr ) )
        return;

    // Create vertex buffer
    D3D11_BUFFER_DESC bd;
    ZeroMemory( &bd, sizeof(bd) );
    bd.Usage = D3D11_USAGE_DEFAULT;
    bd.ByteWidth = sizeof( SimpleVertex ) * 24;
    bd.BindFlags = D3D11_BIND_VERTEX_BUFFER;
    bd.CPUAccessFlags = 0;
    D3D11_SUBRESOURCE_DATA InitData;
    ZeroMemory( &InitData, sizeof(InitData) );
    InitData.pSysMem = vertices;
    hr = device->CreateBuffer( &bd, &InitData, &pVertexBuffer );
    if( FAILED( hr ) )
        return;
    
    // Build index
    bd.Usage = D3D11_USAGE_DEFAULT;
    bd.ByteWidth = sizeof( WORD ) * 36;
    bd.BindFlags = D3D11_BIND_INDEX_BUFFER;
    bd.CPUAccessFlags = 0;
    InitData.pSysMem = indices;
    hr = device->CreateBuffer( &bd, &InitData, &pIndexBuffer );
    if( FAILED( hr ) )
        return;

    // Create the constant buffers
    bd.Usage = D3D11_USAGE_DEFAULT;
    bd.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
    bd.ByteWidth = sizeof(CBChangeOnResize);
    hr = device->CreateBuffer( &bd, NULL, &pCBChangeOnResize );
    if( FAILED( hr ) )
        return;
    
    bd.ByteWidth = sizeof(CBChangesEveryFrame);
    hr = device->CreateBuffer( &bd, NULL, &pCBChangesEveryFrame );
    if( FAILED( hr ) )
        return;

    // Load the Texture
    hr = D3DX11CreateShaderResourceViewFromFile( device, L"seafloor.dds", NULL, NULL, &pTextureRV, NULL );
    if( FAILED( hr ) )
        return;

    // Create the sample state
    D3D11_SAMPLER_DESC sampDesc;
    ZeroMemory( &sampDesc, sizeof(sampDesc) );
    sampDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
    sampDesc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP;
    sampDesc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP;
    sampDesc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP;
    sampDesc.ComparisonFunc = D3D11_COMPARISON_NEVER;
    sampDesc.MinLOD = 0;
    sampDesc.MaxLOD = D3D11_FLOAT32_MAX;
    hr = device->CreateSamplerState( &sampDesc, &pSamplerLinear );
    if( FAILED( hr ) )
        return;
}

void TestCube::Draw(float time,ID3D11DeviceContext* context, IRC3DCamera* camera)
{
    // Set the input layout
    context->IASetInputLayout( pVertexLayout );

    // Set vertex buffer
    UINT stride = sizeof( SimpleVertex );
    UINT offset = 0;
    context->IASetVertexBuffers( 0, 1, &pVertexBuffer, &stride, &offset );

    // Set index buffer
    context->IASetIndexBuffer( pIndexBuffer, DXGI_FORMAT_R16_UINT, 0 );

    // Set primitive topology
    context->IASetPrimitiveTopology( D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST );

    // Initialize the projection matrix    
    CBChangeOnResize cbChangesOnResize;
    cbChangesOnResize.mProjection = XMMatrixTranspose( camera->getProjection() );
    context->UpdateSubresource( pCBChangeOnResize, 0, NULL, &cbChangesOnResize, 0, 0 );

    //
    // Update variables that change once per frame
    //
    CBChangesEveryFrame cb;
    cb.mWorld = XMMatrixTranspose( getWorld() );
    cb.vMeshColor = Color;
    cb.mView = XMMatrixTranspose( camera->getView()  );
    context->UpdateSubresource( pCBChangesEveryFrame, 0, NULL, &cb, 0, 0 );

    // Render the cube
    context->VSSetShader( pVertexShader, NULL, 0 );
    context->VSSetConstantBuffers( 0, 1, &pCBChangeOnResize );
    context->VSSetConstantBuffers( 1, 1, &pCBChangesEveryFrame );
    context->PSSetShader( pPixelShader, NULL, 0 );
    context->PSSetConstantBuffers( 1, 1, &pCBChangesEveryFrame );
    context->PSSetShaderResources( 0, 1, &pTextureRV );
    context->PSSetSamplers( 0, 1, &pSamplerLinear );
    context->DrawIndexed( 36, 0, 0 );    
}
As you can see we have set the ctor togive the object a default color of white. The next method we have is the HUGE Initialize, and this s the majority of the work is being done here, loading the shaders up, creating the vertex and index buffers, as well as setting the constant buffers and loading the texture and setting the sampler. Again you will see I have taken the shader and the texture from the SDK tutorials.
Our Draw call is again pretty straightforward, sets the device up with vertex and index buffers, sets the parameters in the buffers, then makes the draw call.
We now have something we can render, what we need now is a WinMain, a loop and some objects to render…
Just as before, create a main.cpp file in the solution
image
In here we will add all theeaders we need, create a WinProc call back as before and a WinMain function, we will also set up the game loop as before, but use our new game class to build the window and device.
#pragma once
#include <Windows.h>

#include "RC3DGame.h"

RC3DGame game;

int int_AppRunning = 1;

LRESULT CALLBACK winProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam )
{
    
    switch(message)
    {
        case WM_CLOSE:
        {
            int_AppRunning = 0;
            break;
        }
    }    

    return DefWindowProc(hWnd,message,wParam,lParam);
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR pScmdline, int iCmdshow)
{
    MSG msg_Message;    
    int result = 0;

    
    game.Initialize(L"RandomchaosDX11ProtoEngien",0,0,800,600,winProc);
    HWND hWnd = game.GraphicsDevice.getWindowHandle();

    
    if(hWnd != HWND(-1))
    {
        while(int_AppRunning)
        {
            if(PeekMessage(&msg_Message,hWnd,0,0,PM_REMOVE))
                DispatchMessage(&msg_Message);

            
        }
    
        DestroyWindow(hWnd);     
    }
    return result;
}
We can now compile and run our application, you wont see much, but it will run.
image
Lets add our camera, set up a list of IDrawables and I Updateables and call the game update and draw calls. Under RC3DGame game, add the following lines (don’t forget to add the header for the camera!)
RC3DCamera* camera;

std::vector<IUpdateable*> vUpdateables;
std::vector<IDrawable*> vDrawables;
We now have a camera and two lists to store references to drawable and updatable objects.
After we have initialized the graphics devic, we can initialize our camera and add it to the updateable list with in WinMain
game.Initialize(L"RandomchaosDX11ProtoEngien",0,0,800,600,winProc);
    HWND hWnd = game.GraphicsDevice.getWindowHandle();

    camera = new RC3DCamera(XMFLOAT3(0,0,0),XMFLOAT3(0,1,0),XMQuaternionIdentity(), game.GraphicsDevice.getViewPort().Width,game.GraphicsDevice.getViewPort().Height);
    
    vUpdateables.push_back(camera);
Now in our main game loop we can add the draw and update calls
        while(int_AppRunning)
        {
            if(PeekMessage(&msg_Message,hWnd,0,0,PM_REMOVE))
                DispatchMessage(&msg_Message);

            game.Update(0,&vUpdateables);

            game.Draw(0,camera,&vDrawables);
            
        }
Running this will just give us a nice cornflower blue screen, so lets put something in the scene to render, lest create a TestCube :)
Include the TestCube.h file. and add the following after the IDrawable list creation
TestCube testCube;
Then after we have added the camera to the update list, do add this
    testCube.game = &game;
    testCube.setPosition(XMFLOAT3(0,0,10));
    testCube.Initialize(game.GraphicsDevice.getDevice());

    vUpdateables.push_back(&testCube);
    vDrawables.push_back(&testCube);
We now need to add the texture and shader to the project, so right click the project, and add a new filter like this
image
and call it Shaders, then copy any dds texture you like into the project folder and call it seafloor.
In the Shaders filter/folder create anew file called Tutorial07.fx and paste the following into it
//--------------------------------------------------------------------------------------
// File: Tutorial07.fx
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//--------------------------------------------------------------------------------------

// Modified a little for the Randomchaos: Graphics Adventures in C++ with DirectX 11 blog
// http://randomchaosdx11adventures.blogspot.co.uk/

//--------------------------------------------------------------------------------------
// Constant Buffer Variables
//--------------------------------------------------------------------------------------
Texture2D txDiffuse : register( t0 );
SamplerState samLinear : register( s0 );

cbuffer cbChangeOnResize : register( b0 )
{
    matrix Projection;
};

cbuffer cbChangesEveryFrame : register( b1 )
{
    matrix World;
    float4 vMeshColor;
    matrix View;
};


//--------------------------------------------------------------------------------------
struct VS_INPUT
{
    float4 Pos : POSITION;
    float2 Tex : TEXCOORD0;
};

struct PS_INPUT
{
    float4 Pos : SV_POSITION;
    float2 Tex : TEXCOORD0;
};


//--------------------------------------------------------------------------------------
// Vertex Shader
//--------------------------------------------------------------------------------------
PS_INPUT VS( VS_INPUT input )
{
    PS_INPUT output = (PS_INPUT)0;
    output.Pos = mul( input.Pos, World );
    output.Pos = mul( output.Pos, View );
    output.Pos = mul( output.Pos, Projection );
    output.Tex = input.Tex;
    
    return output;
}


//--------------------------------------------------------------------------------------
// Pixel Shader
//--------------------------------------------------------------------------------------
float4 PS( PS_INPUT input) : SV_Target
{
    return txDiffuse.Sample( samLinear, input.Tex ) * vMeshColor;
}
The shader is a fair bit different to a XNA/DX9c shader isn’t it, variablesare now stored in cbuffer structu, and in the case of this shader there is no technique, just a vertex and a pixel shader.
So, we can run this now right? Nope, if you do you will get this error
image
We need to right click the shader file, and tell the IDE not to try and build it as we will do this at run time, change the ItemType from “HLSL Compiler” to “Does not participate in build”
If we run the project now, we will get this
image
AT LAST! We have rendered our cube in DirectX 11 using a basic C++ framework.
That’s all well and good, but that’s just a square of texture, how do I know it’s a cube? Well you will need to move around it, so lets wire up some keyboard controls like we have in previous posts, but the game class is already getting us the keyboard state, so we just need to react to what’s pressed.
After our WinProc callback method we can create a HandleKeyboardInput method like this
void HandleKeyboardInput()
{
    float spd = .0005f;
    float rotSpd = .0001f;

    if (game.KeyboardManager.getKeyboardState()[DIK_ESCAPE]/128)
        int_AppRunning = 0;

    if (game.KeyboardManager.getKeyboardState()[DIK_LEFT]/128)
        camera->Rotate(XMVectorSet(0,1,0,0),-rotSpd);

    if (game.KeyboardManager.getKeyboardState()[DIK_RIGHT]/128)
        camera->Rotate(XMVectorSet(0,1,0,0),rotSpd);

    if(game.KeyboardManager.getKeyboardState()[DIK_UP]/128)
        camera->Rotate(XMVectorSet(1,0,0,0),-rotSpd);

    if(game.KeyboardManager.getKeyboardState()[DIK_DOWN]/128)
        camera->Rotate(XMVectorSet(1,0,0,0),rotSpd);

    if(game.KeyboardManager.getKeyboardState()[DIK_SPACE]/128)
        camera->setOrientation(XMQuaternionIdentity());

    if(game.KeyboardManager.getKeyboardState()[DIK_W]/128)
        camera->Translate(XMFLOAT3(0,0,spd));

    if(game.KeyboardManager.getKeyboardState()[DIK_S]/128)
        camera->Translate(XMFLOAT3(0,0,-spd));

    if(game.KeyboardManager.getKeyboardState()[DIK_A]/128)
        camera->Translate(XMFLOAT3(-spd,0,0));

    if(game.KeyboardManager.getKeyboardState()[DIK_D]/128)
        camera->Translate(XMFLOAT3(spd,0,0));
    
}
And at the top of our game loop call it
        while(int_AppRunning)
        {
            if(PeekMessage(&msg_Message,hWnd,0,0,PM_REMOVE))
                DispatchMessage(&msg_Message);

            HandleKeyboardInput();

            game.Update(0,&vUpdateables);

            game.Draw(0,camera,&vDrawables);
            
        }
We should now be able to run the application and move around the cube to get views like this
image
Or, as shown in a clip a few posts ago, this :)
What if I want to render lots of cubes? No problem, remove the references to the instance of testCube we just rendered and do this
    int cubes = 8;
    for(int c = 0; c < cubes;c++)
    {
        TestCube* testCube = new TestCube();    

        testCube->game = &game;
        XMFLOAT3 pos;
        XMFLOAT4 col;
        switch(c)
        {
            case 0:
                pos = XMFLOAT3(-1,0,1);
                col = XMFLOAT4(1,1,1,1);
                break;
            case 1:
                pos = XMFLOAT3(1,0,1);
                col = XMFLOAT4(1,0,1,1);
                break;
            case 2:
                pos = XMFLOAT3(-1,0,3);
                col = XMFLOAT4(1,1,0,1);
                break;
            case 3:
                pos = XMFLOAT3(1,0,3);
                col = XMFLOAT4(0,1,1,1);
                break;
            case 4:
                pos = XMFLOAT3(-1,2,1);
                col = XMFLOAT4(0,0,1,1);
                break;
            case 5:
                pos = XMFLOAT3(1,2,1);
                col = XMFLOAT4(1,0,0,1);
                break;
            case 6:
                pos = XMFLOAT3(-1,2,3);
                col = XMFLOAT4(0,1,0,1);
                break;
            case 7:
                pos = XMFLOAT3(1,2,3);
                col = XMFLOAT4(.5,.5,.5,1);
                break;
        }
        testCube->setPosition(pos);
        testCube->Color = col;
        testCube->Initialize(game.GraphicsDevice.getDevice());

        vUpdateables.push_back(testCube);
        vDrawables.push_back(testCube);
    }
to get something like this
image
So, your main.cpp would look something like this
#pragma once
#include <Windows.h>

#include "RC3DGame.h"
#include "RC3DCamera.h"
#include "TestCube.h"

RC3DGame game;
RC3DCamera* camera;

std::vector<IUpdateable*> vUpdateables;
std::vector<IDrawable*> vDrawables;

int int_AppRunning = 1;

LRESULT CALLBACK winProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam )
{
    
    switch(message)
    {
        case WM_CLOSE:
        {
            int_AppRunning = 0;
            break;
        }
    }    

    return DefWindowProc(hWnd,message,wParam,lParam);
}

void HandleKeyboardInput()
{
    float spd = .0005f;
    float rotSpd = .0001f;

    if (game.KeyboardManager.getKeyboardState()[DIK_ESCAPE]/128)
        int_AppRunning = 0;

    if (game.KeyboardManager.getKeyboardState()[DIK_LEFT]/128)
        camera->Rotate(XMVectorSet(0,1,0,0),-rotSpd);

    if (game.KeyboardManager.getKeyboardState()[DIK_RIGHT]/128)
        camera->Rotate(XMVectorSet(0,1,0,0),rotSpd);

    if(game.KeyboardManager.getKeyboardState()[DIK_UP]/128)
        camera->Rotate(XMVectorSet(1,0,0,0),-rotSpd);

    if(game.KeyboardManager.getKeyboardState()[DIK_DOWN]/128)
        camera->Rotate(XMVectorSet(1,0,0,0),rotSpd);

    if(game.KeyboardManager.getKeyboardState()[DIK_SPACE]/128)
        camera->setOrientation(XMQuaternionIdentity());

    if(game.KeyboardManager.getKeyboardState()[DIK_W]/128)
        camera->Translate(XMFLOAT3(0,0,spd));

    if(game.KeyboardManager.getKeyboardState()[DIK_S]/128)
        camera->Translate(XMFLOAT3(0,0,-spd));

    if(game.KeyboardManager.getKeyboardState()[DIK_A]/128)
        camera->Translate(XMFLOAT3(-spd,0,0));

    if(game.KeyboardManager.getKeyboardState()[DIK_D]/128)
        camera->Translate(XMFLOAT3(spd,0,0));
    
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR pScmdline, int iCmdshow)
{
    MSG msg_Message;    
    int result = 0;

    
    game.Initialize(L"RandomchaosDX11ProtoEngien",0,0,800,600,winProc);
    HWND hWnd = game.GraphicsDevice.getWindowHandle();

    camera = new RC3DCamera(XMFLOAT3(0,0,0),XMFLOAT3(0,1,0),XMQuaternionIdentity(), game.GraphicsDevice.getViewPort().Width,game.GraphicsDevice.getViewPort().Height);
    
    vUpdateables.push_back(camera);

    int cubes = 8;
    for(int c = 0; c < cubes;c++)
    {
        TestCube* testCube = new TestCube();
        

        testCube->game = &game;
        XMFLOAT3 pos;
        XMFLOAT4 col;
        switch(c)
        {
            case 0:
                pos = XMFLOAT3(-1,0,1);
                col = XMFLOAT4(1,1,1,1);
                break;
            case 1:
                pos = XMFLOAT3(1,0,1);
                col = XMFLOAT4(1,0,1,1);
                break;
            case 2:
                pos = XMFLOAT3(-1,0,3);
                col = XMFLOAT4(1,1,0,1);
                break;
            case 3:
                pos = XMFLOAT3(1,0,3);
                col = XMFLOAT4(0,1,1,1);
                break;
            case 4:
                pos = XMFLOAT3(-1,2,1);
                col = XMFLOAT4(0,0,1,1);
                break;
            case 5:
                pos = XMFLOAT3(1,2,1);
                col = XMFLOAT4(1,0,0,1);
                break;
            case 6:
                pos = XMFLOAT3(-1,2,3);
                col = XMFLOAT4(0,1,0,1);
                break;
            case 7:
                pos = XMFLOAT3(1,2,3);
                col = XMFLOAT4(.5,.5,.5,1);
                break;
        }
        testCube->setPosition(pos);
        testCube->Color = col;
        testCube->Initialize(game.GraphicsDevice.getDevice());

        vUpdateables.push_back(testCube);
        vDrawables.push_back(testCube);
    }

    if(hWnd != HWND(-1))
    {
        while(int_AppRunning)
        {
            if(PeekMessage(&msg_Message,hWnd,0,0,PM_REMOVE))
                DispatchMessage(&msg_Message);

            HandleKeyboardInput();

            game.Update(0,&vUpdateables);

            game.Draw(0,camera,&vDrawables);
            
        }
    
        DestroyWindow(hWnd);     
    }
    return result;
}
Now, I guess all we have done here is create similar objects to the XNA Game, GameComponent and DrawableGameComponent. We have not even scratched the surface of a way to import assets. What I would like to do now is create a framework that would be truly useful to us XNA folk moving to C++/DirectX11, something that would give us familiar objects to work with. Not sure how far I will get, but what ever I do, ill be posting it here.
I hope you have found this of some use, please let me know what you think in the comments.
Source code is available here.