Computer Graphics Programming

Made with C++ and DirectX11

Video

Narrated by Chaye Foster

What we had to do

We were required to make a game using DirectX11 and C++ from the ground up in our group. This required us to learn the rendering pipeline and helping our further understanding of Object Oriented Programming and an Agile workflow as we work in our groups making each iteration.

My contributionns

I contributed as the scene manager of the project. We all had to set up the project and create a basic plane with a directional light and movable character. Then once the coursework had reached a certain point each group added their individuality with the project. We decided to go for a museum to showcase dinosaurs. I had worked on importing assets from various file formats to show the support for them and align them in our scene with the inclusion of collision boxes.

Code

Here are a few snippets of code from the project.

Pickup able Object

#include "CLitPickupableModel.h"

#include "CBlinnPhongMaterial.h"
#include "Game.h" // Add to the score
#include <sstream> // Display the score

namespace Rendering
{
	RTTI_DEFINITIONS(CLitPickupableModel);

	CLitPickupableModel::CLitPickupableModel(Game& aGame, Camera& aCamera, const std::string aModelFileName,
		const std::wstring aTextureFileName, std::wstring aPickUpDescription, int aPickupValue, bool aFlipUVs) :
		CLitModel(aGame, aCamera, aModelFileName, aTextureFileName, L"", aFlipUVs),
		mPickupDescription(aPickUpDescription), mPickupValue(aPickupValue)
	{
	}

	DirectX::BoundingBox CLitPickupableModel::GetBoundingBox() const
	{
		if (mMaterial != nullptr)
		{
			return mMaterial->GetBoundingBox();
		}
		else
		{
			return DirectX::BoundingBox();
		}
	}

	XMFLOAT4X4* CLitPickupableModel::GetPickupWorldMatrix()
	{
		return &mWorldMatrix;
	}

	bool CLitPickupableModel::CanBePicked() const
	{
		return Visible();
	}

	/// <summary>
	/// Display a message box to the user asking if they want to pick up the object
	/// If they do, hide the object and update the score
	/// </summary>
	/// <returns>If the object was picked as confirmed in the message box</returns>
	bool CLitPickupableModel::PickObject()
	{         
		std::wostringstream pickupString;
		pickupString << L"Do you want to pick up: " << (mPickupDescription).c_str() << '\n' << '\t' << '+' << mPickupValue << L" points";

		// If the object is picked
		int result = MessageBox(0, pickupString.str().c_str(), L"Object Found", MB_ICONASTERISK | MB_YESNO);
		if (result == IDYES)
		{
			// Hide the object
			SetVisible(false);

			// Update the score
			mGame->AddToGameScore(mPickupValue);

			return true;
		}
		else
		{
			return false;
		}
	}
}

Rotating Animated Model

#include "AnimatedModel.h"

namespace Rendering {
    RTTI_DEFINITIONS(AnimatedModel)

    AnimatedModel::AnimatedModel(Game& game, Camera& camera, const std::string& modelFilename, const std::wstring& textureFilename, bool flipUVs)
        : CLitModel(game, camera, modelFilename, textureFilename, L"", flipUVs) // Added L"" for the normal map parameter
    {
        // Initialize members
        mRotationSpeed = 0.0f;
        mRotationAxis = XMFLOAT3(1.0f, 0.0f, 0.0f); // Default rotation
    }

    AnimatedModel::~AnimatedModel() {
    }

    void AnimatedModel::Update(const GameTime& gameTime) {
        float deltaTime = static_cast<float>(gameTime.ElapsedGameTime());
        float angle = mRotationSpeed * deltaTime;

        XMMATRIX rotationMatrix = XMMatrixRotationAxis(XMLoadFloat3(&mRotationAxis), angle);
        XMMATRIX currentTransform = XMLoadFloat4x4(&mWorldMatrix);
        currentTransform = currentTransform * rotationMatrix;
        XMStoreFloat4x4(&mWorldMatrix, currentTransform);

        CLitModel::Update(gameTime);
    }

    void AnimatedModel::SetRotationSpeed(float speed) {
        mRotationSpeed = speed;
    }

    void AnimatedModel::SetRotationAxis(const XMFLOAT3& axis) {
        mRotationAxis = axis;
    }
}

Object Defuse Light

#include "ObjectDiffuseLight.h"

#include "DiffuseLightingMaterial.h"
#include "Game.h"
#include "GameException.h"
#include "Camera.h"
#include "CModel.h"
#include "Mesh.h"
#include "Utility.h"
#include "DirectionalLight.h"
#include <WICTextureLoader.h>

namespace Rendering
{
	RTTI_DEFINITIONS(ObjectDiffuseLight)

	ObjectDiffuseLight::ObjectDiffuseLight(Game& game, Camera& camera)
		: CDirectionalLightSetter(game, camera), mEffect(nullptr), mMaterial(nullptr), mTextureShaderResourceView(nullptr),
		  mVertexBuffer(nullptr), mIndexBuffer(nullptr), mIndexCount(0)
	{
	}

	ObjectDiffuseLight::~ObjectDiffuseLight()
	{
		ReleaseObject(mTextureShaderResourceView);
		DeleteObject(mMaterial);
		DeleteObject(mEffect);	
		ReleaseObject(mVertexBuffer);
		ReleaseObject(mIndexBuffer);
	}

	void ObjectDiffuseLight::Initialize()
	{
		SetCurrentDirectory(Utility::ExecutableDirectory().c_str());

		std::unique_ptr<CModel> model(new CModel(*mGame, "Content\\Models\\house.3ds", true));

		// Initialize the material
		mEffect = new Effect(*mGame);
		mEffect->LoadCompiledEffect(L"Content\\Effects\\DiffuseLighting.cso");
		


		mMaterial = new DiffuseLightingMaterial();
		mMaterial->Initialize(*mEffect);

		Mesh* mesh = model->Meshes().at(0);
		mMaterial->CreateVertexBuffer(mGame->Direct3DDevice(), *mesh, &mVertexBuffer);
		mesh->CreateIndexBuffer(&mIndexBuffer);
		mIndexCount = mesh->Indices().size();

		std::wstring textureName = L"Content\\Textures\\house.bmp";
		HRESULT hr = DirectX::CreateWICTextureFromFile(mGame->Direct3DDevice(), mGame->Direct3DDeviceContext(), textureName.c_str(), nullptr, &mTextureShaderResourceView);
		if (FAILED(hr))
		{
			throw GameException("CreateWICTextureFromFile() failed.", hr);
		}

		// Initialize light setter
		CDirectionalLightSetter::Initialize();
	}

	void ObjectDiffuseLight::Update(const GameTime& gameTime)
	{
		// Update light setter
		CDirectionalLightSetter::Update(gameTime);
	}

	void ObjectDiffuseLight::Draw(const GameTime& gameTime)
	{
		ID3D11DeviceContext* direct3DDeviceContext = mGame->Direct3DDeviceContext();
		direct3DDeviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);

		Pass* pass = mMaterial->CurrentTechnique()->Passes().at(0);
		ID3D11InputLayout* inputLayout = mMaterial->InputLayouts().at(pass);
		direct3DDeviceContext->IASetInputLayout(inputLayout);		

		UINT stride = mMaterial->VertexSize();
		UINT offset = 0;
		direct3DDeviceContext->IASetVertexBuffers(0, 1, &mVertexBuffer, &stride, &offset);
		direct3DDeviceContext->IASetIndexBuffer(mIndexBuffer, DXGI_FORMAT_R32_UINT, 0);

		XMMATRIX worldMatrix = XMLoadFloat4x4(&mWorldMatrix);
		XMMATRIX wvp = worldMatrix * mCamera->ViewMatrix() * mCamera->ProjectionMatrix();
		XMVECTOR ambientColor = XMLoadColor(&mAmbientColor);			

		mMaterial->WorldViewProjection() << wvp;
		mMaterial->World () << worldMatrix;
		mMaterial->AmbientColor() << ambientColor;
		mMaterial->LightColor() << mDirectionalLight->ColorVector();
		mMaterial->LightDirection() << mDirectionalLight->DirectionVector();
		mMaterial->ColorTexture() << mTextureShaderResourceView;
		
		pass->Apply(0, direct3DDeviceContext);
		
		direct3DDeviceContext->DrawIndexed(mIndexCount, 0, 0);

		// Draw light setter
		CDirectionalLightSetter::Draw(gameTime);
	}
}
Next
Next

Game Engine Architechture