Welcome!

Welcome to my blog for all things me-related! You can find out all about me on the “About” page above and you can see some of the projects I have created in the “Demo’s” drop down. Below are recent posts I have made relating to the current project I am working on! Feel free to browse and leave comments; there is a contact form on the “About” page if all you want is a chat!

categories Uncategorized | comments Comments Off

Scene Management

Just a quick update about the use of Scenes that I employed when making Tetris. A scene is a single aspect of the game that is shown to the user, so it can be the main menu, the first level, a high score screen etc. Each scene keeps a track of all the resources it requires and can be updated and rendered separate to the other scenes.

The following code shows the base class that every scene derives from:

// SceneBase Class --------------------------------
class SceneBase
{
public:		// Constructors and Destructor ------
	SceneBase();
	~SceneBase();

public:		

	// Basic versions of these methods incase the derived scene
	// doesn't require an implementation
	virtual bool Init(ID3D11Device* inDevice) { return true; }
	virtual bool IsInitialised() { return mInitialised; }
	virtual bool Update(float inDeltaTime) { return true; }
	virtual bool Draw(GameCamera& inCam, Renderer* inRenderer) { return true; }
	virtual bool Shutdown() { return true; }

	// Pure virtual methods

protected:
	// Protected Methods

	
	// Protected Data
	bool	mInitialised;

};


Using this method allows me to keep the code for different aspects of the game separate. For example, in Tetris I currently have a Main Menu scene and a Game scene. The Update function for the Tetris app now looks as follows:

if (!mPlay)
{
	// Init if required
	if (!mSceneMenu->IsInitialised())
		mSceneMenu->Init(mD3DDevice);

	// Update
	mSceneMenu->Update(inDeltaTime);
	mMenuState = reinterpret_cast<Scene_MainMenu*>(mSceneMenu)->GetMenuState();

	if (mMenuState == Scene_MainMenu_n::EMenu_ExitGame)
	{
		mSceneMenu->Shutdown();
		return false;
	}
	if (mMenuState == Scene_MainMenu_n::EMenu_NewGame)
	{
		mSceneMenu->Shutdown();
		mPlay = true;
	}
}
else
{
	// Init if required
	if (!mSceneGame->IsInitialised())
		mSceneGame->Init(mD3DDevice);

	// Returns false on game over!
	mPlay = mSceneGame->Update(inDeltaTime);

	if (!mPlay)
		mSceneGame->Shutdown();
}

return true;


A nice advantage of this technique is that it allows you to update multiple scenes while only drawing a single scene, or vice-versa. For example, if you have a Paused scene and a Game scene then when the user pauses the game the Game scene can continue to be drawn but not updated, with the Pause scene drawn over the top.

categories Uncategorized | comments Comments (0)

Tetris Video

Finally got around to making a video of my Tetris game. The UI is still pretty simplistic, using some text rendering to show the current score (I’ll be the first to admit that I’m not that good at making “art” things =P).

As usual, the latest source code is available on the right.

categories Uncategorized | comments Comments (0)

Sprite Rendering

When rendering sprites I basically followed this tutorial from Rastertek. The interesting bit is the use of a Dynamic Vertex Buffer to store the vertex data in. These are setup the same as static vertex buffers but the “usage” is changed in the vertex buffer description;

vertexBufferDesc.Usage = D3D11_USAGE_DYNAMIC;


The reason dynamic vertex buffers are used is so that we can update the vertex positions if the sprite is moving, obviously if the sprite is never going to be moving then a static buffer will work just fine. The following code is used for updating the vertex buffer after the vertices have been updated;

// Lock the vertex buffer so it can be written to
HR(inRenderer->GetDeviceContext()->Map(mVB, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource));

// Get a pointer to the data in the vertex buffer
verticesPtr = (VertexType2D*)mappedResource.pData;

// Copy the data into the vertex buffer
memcpy(verticesPtr, (void*)&vertices, (sizeof(VertexType2D) * VERTEX_COUNT));

// Unlock the vertex buffer
inRenderer->GetDeviceContext()->Unmap(mVB, 0);


The downside to using dynamic vertex buffers is that when we do update the vertices it is relatively slow so it is important to only update the vertex buffer when necessary. The easiest way to do this is to store the position of the sprite and only if the position has changed do you update the vertex buffer;

// If the sprite hasn't moved then we don't need to update the vertex buffer
if (mPrevPos.x == mPos.x &&
    mPrevPos.y == mPos.y)
        return;


The next important step when rendering sprites is to turn the depth buffer off before rendering so that 2D data will overwrite whatever is in that pixel location and appear on top;

// When rendering 2D data we need to turn the Z buffer off
mD3DImmediateContext->OMSetDepthStencilState(mDepthDisabledStencilState, 1);


Remember to turn the depth buffer back on once 2D rendering is finished so that the 3D rendering can be performed correctly;

// Now we have finished rendering 2D data turn the Z buffer back on
mD3DImmediateContext->OMSetDepthStencilState(mDepthStencilState, 1);


The depth enabled stencil state seen above is created as follows;

// Create Depth enabled stencil state
D3D11_DEPTH_STENCIL_DESC depthStencilDesc;
ZeroMemory(&depthStencilDesc, sizeof(depthStencilDesc));

depthStencilDesc.DepthEnable = true;
depthStencilDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL;
depthStencilDesc.DepthFunc = D3D11_COMPARISON_LESS;
depthStencilDesc.StencilEnable = true;
depthStencilDesc.StencilReadMask = 0xFF;
depthStencilDesc.StencilWriteMask = 0xFF;

// Stencil operations if pixel is front-facing
depthStencilDesc.FrontFace.StencilFailOp = D3D11_STENCIL_OP_KEEP;
depthStencilDesc.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_INCR;
depthStencilDesc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP;
depthStencilDesc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS;

// Stencil operations if pixel is back-facing
depthStencilDesc.BackFace.StencilFailOp = D3D11_STENCIL_OP_KEEP;
depthStencilDesc.BackFace.StencilDepthFailOp = D3D11_STENCIL_OP_DECR;
depthStencilDesc.BackFace.StencilPassOp = D3D11_STENCIL_OP_KEEP;
depthStencilDesc.BackFace.StencilFunc = D3D11_COMPARISON_ALWAYS;


The depth disabled stencil state is created in exactly the same way apart from the “DepthEnable” state;

depthDisabledStencilDesc.DepthEnable = false;


The rest of the rendering is pretty standard so I won’t discuss it here, but my source code can be downloaded from the right-hand sidebar on the front page if needed.

I do plan on updating my sprite rendering so that its more efficient as currently each sprite has its own dynamic vertex buffer and locks/unlocks when it moves. My aim is to have a single dynamic vertex buffer for all sprite data so that I will only ever be lock/unlocking a vertex buffer once per frame, no matter how many sprites are being rendered. I then want to add to batching & instancing to further improve the rendering efficiency overall.

categories DX11 Framework | comments Comments (0)

Long Overdue Update!

So it’s been a while since I posted here…..christmas, job, life, things just kept getting in the way!

But, I now have a working version of Tetris! Since the last post I have also created a sprite class and edited my renderer slightly to allow for rendering 2D sprites (I’ll go into the detail of how I render sprites in a later post).

All shapes-normal game

I plan on making a series of posts over the coming days explaining how I created Tetris and the different problems I encountered along the way.

The next step is to add text rendering so that I can output the current score, have a menu etc and then after that I plan to optimise my use of sprites as the current rendering is not very efficient (every sprite has its own dynamic vertex buffer and the render states are set each time for every sprite =O!).

categories Tetris | comments Comments (0)

Matrix Interface

Just finished the majority of the Matrix4x4 class (still need to add scaling but that isn’t a priority right now), so it now has the following public interface:

Now that I have the basic movement/rotation functions available I can start Tetris with earnest!

categories Uncategorized | comments Comments (0)

Love Quick Fixes!

Turns out it was such a simple mistake that was causing my odd texturing problem! I have a “texTransform” variable in my shader that is used to alter the texture if I wish. For some reason when I first wrote the rendering code I sent the world matrix of the current model into that variable….not sure why! Altered the code to just send an identity matrix through unless a transform is required and the textures stay where they are supposed to now!

categories Uncategorized | comments Comments (0)

Games!

Not posted much this last week because Dishonored and XCOM: Enemy Unknown were both released last weekend and have been taking up more of my time than I care to admit! On other news, I have small bug I’m in the process of fixing; when rotating a model the textures aren’t rotating with it…..time to put on my solving cap!

categories Uncategorized | comments Comments (0)

Source Code Download

Quick update.

Just added the source code for my current project to the side bar on the right on this front page. It is a work-in-progress and with each post I intend to update the source code to reflect the changes I have made!

categories DX11 Framework | comments Comments (0)

Woops!

Realised this evening that when loading a mesh I was still only using the first mesh that a child node has:

aiMesh* childMesh = inScene->mMeshes[childNode->mMeshes[0]];

That code was placeholder when I first started writing the loading code based on aiNode’s and I forgot to go back and change it! Found this out the hard way when trying to help a fellow coder on GameDev.net and I tried to load a model that had a child with 6 meshes!

The new version of this code now looks like this:

aiNode* childNode = rootNode->mChildren[child];

for (int mesh=0; mesh < childNode->mNumMeshes; mesh++)
{
	aiMesh* childMesh = inScene->mMeshes[childNode->mMeshes[mesh]];
	aiMatrix4x4 childTrans = childNode->mTransformation;
....
categories DX11 Framework | comments Comments (0)

More Absolute/Relative Matrices

Now I’ve cleaned up the code regarding getting the relative matrices from Assimp that I mentioned in my last post I thought I’d share it here!

There is still plenty of room for improvement and my next step is to write a matrix class so I don’t have to use XMMATRIX/XMFLOAT4X4 anymore!

So this is code for when the mesh is loaded. For meshes with multiple children a dummy root matrix is created that defines the mesh as a whole (i.e. where it is located and how it is rotated/scaled).

// For now initialise the root matrix to an Identity Matrix
// In the future the root will be initialise to a position,
// rotation and scale that is sent in.
XMMATRIX I = XMMATRIX(XMMatrixIdentity() );
XMFLOAT4X4 temp;
XMStoreFloat4x4(&temp, I);
mRelMatrices.push_back( temp );

aiNode* rootNode = inScene->mRootNode;
if (rootNode->mNumChildren == 0)
{
	// If there are no children then assimp doesn't use a dummy node as
	// the root

	// Create a sub-mesh
	SubMesh* subMesh = new SubMesh();
	// The last two parameters are:
	//			The index of this sub-meshes relative matrix	
	//			The index of this sub-meshes parent matrix
	subMesh->Init(inDevice, inScene->mMeshes[0], inScene->mMaterials[0], 0, 0);

	mSubMeshes.push_back(subMesh);
}
else
{
	// For each child of rootNode
	for (int i=0; i < rootNode->mNumChildren; i++)
	{
		// Child node information
		aiNode* childNode = rootNode->mChildren[i];
		aiMesh* childMesh = inScene->mMeshes[childNode->mMeshes[0]];
		aiMatrix4x4 childTrans = childNode->mTransformation;

		// The matrix we will store the transformation in
		XMFLOAT4X4 relMatrix;
		relMatrix._11 = childTrans.a1;
		relMatrix._12 = childTrans.b1;
		relMatrix._13 = childTrans.c1;
		relMatrix._14 = childTrans.d1;
					 
		relMatrix._21 = childTrans.a2;
		relMatrix._22 = childTrans.b2;
		relMatrix._23 = childTrans.c2;
		relMatrix._24 = childTrans.d2;
					 
		relMatrix._31 = childTrans.a3;
		relMatrix._32 = childTrans.b3;
		relMatrix._33 = childTrans.c3;
		relMatrix._34 = childTrans.d3;
					 
		relMatrix._41 = childTrans.a4;
		relMatrix._42 = childTrans.b4;
		relMatrix._43 = childTrans.c4;
		relMatrix._44 = childTrans.d4;
			
		mRelMatrices.push_back(relMatrix);

		SubMesh* subMesh = new SubMesh();
		// The last two parameters are:
		//			The index of this sub-meshes relative matrix,
		//			(i+1) because the root is the overall matrix for this mesh.
		//			The index of this sub-meshes parent matrix
		subMesh->Init(inDevice, childMesh, inScene->mMaterials[childMesh->mMaterialIndex], i+1, 0);

		mSubMeshes.push_back(subMesh);
	}
}

mAbsMatrices.resize(mRelMatrices.size());



And this is the code used in the Mesh::Draw method.

// Set the root absolute
mAbsMatrices[0] = mRelMatrices[0];

// For meshes that have children we update the absolute
// matrices
for (int i=1; i < mRelMatrices.size(); i++)
{
	// Get the matrices we need for the calculation
	XMFLOAT4X4 relMatrix = mRelMatrices[i];
	unsigned int parIdx = mSubMeshes[i-1]->GetParentIdx();
	XMFLOAT4X4 parMatrix = mAbsMatrices[parIdx];

	// Convert to XMMATRIX so we can use the * operator
	XMMATRIX rel = XMLoadFloat4x4(&relMatrix);
	XMMATRIX par = XMLoadFloat4x4(&parMatrix);

	// Calculate new absolute
	XMMATRIX newMatrix = rel * par;

	// Convert back to Float4x4
	XMFLOAT4X4 res;
	XMStoreFloat4x4(&res, newMatrix);

	// Store
	mAbsMatrices[i] = res;
}

// Draw each submesh in turn using the new absolute matrices
for (int subMesh=0; subMesh < mSubMeshes.size(); subMesh++)
{
	// Access the matrix for the current sub-mesh
	XMFLOAT4X4 subAbsMatrix = mAbsMatrices[ mSubMeshes[subMesh]->GetMatrixIdx() ];

	mSubMeshes[subMesh]->Draw(inCam, inRenderer, subAbsMatrix);
}



As the absolute matrices are worked out during the Draw call the SetPosition function is relatively simple because we just need to translate the relative matrix of the node we want to move. This is where the dummy root node comes in handy because if we want to move the whole mesh we just translate the root matrix and the sub-meshes matrices new locations will be calculated in the Draw function.

// Converting to XMVECTOR so we can use the Translation function
// to get an XMMATRIX that defines the translation we want to make
XMVECTOR pos = XMLoadFloat3(&inPos);
XMMATRIX transMat = XMMatrixTranslationFromVector(pos);
// Convert the matrix that we want to set the position of
// to an XMMATRIX so we use the * operator
XMMATRIX rootMat = XMLoadFloat4x4(&mRelMatrices[inNode]);

// Calculate the new matrix after translation
XMMATRIX newMat = rootMat * transMat;

// Store the matrix back in the matrices array.
XMStoreFloat4x4(&mRelMatrices[inNode], newMat);



Now I can go back to allowing full translation/rotation/scaling of meshes! That will go nicely alongside creating a new matrix class so I can get rid of all those pesky ‘XMdothis‘ and ‘XMdothat‘ functions!

categories DX11 Framework | comments Comments (0)
go to ajlee