view LightClone/Source/Environment.cpp @ 10:292e534f00c2

Moved rendering into Bot/Environment; Started work on Gui system
author koryspansel <koryspansel@bendbroadband.com>
date Sat, 10 Sep 2011 23:52:12 -0700
parents 7e3a0ae9c016
children 5656c8e382fc
line wrap: on
line source

/*
 * Environment
 */

#include "Environment.h"
#include "VertexTypes.h"
#include "Util.h"

/*
 * Environment
 */
Environment::Environment() : pGrid(0)
{
	pBlockEffect		= NULL;
	pBlockVertexBuffer	= NULL;
	pBlockTexture		= NULL;
	nWidth				= 0;
	nHeight				= 0;
	kScale.x			= 1.0f;
	kScale.y			= 0.4f;
	kScale.z			= 1.0f;
}

/*
 * ~Environment
 */
Environment::~Environment()
{
	delete[] pGrid;
}

/*
 * Initialize
 */
ErrorCode Environment::Initialize(ResourceManager* pResourceManager)
{
	ErrorCode eCode = pResourceManager->CreateEffectFromFile("Data\\Shaders\\Environment.fx", &pBlockEffect);
	if(eCode == Error_Success)
	{
		eCode = pResourceManager->CreateTextureFromFile("Data\\Textures\\Block02.tga", &pBlockTexture);
		if(eCode == Error_Success)
		{
			eCode = pResourceManager->CreateVertexBuffer(VerticesPerBlock * sizeof(Vertex::Block), D3DUSAGE_WRITEONLY, D3DPOOL_MANAGED, &pBlockVertexBuffer);
			if(eCode == Error_Success)
			{
				eCode = SetupVertexBuffer();
			}
		}
	}

	return eCode;
}

/*
 * Terminate
 */
void Environment::Terminate()
{
	if(pBlockVertexBuffer)
	{
		pBlockVertexBuffer->Release();
		pBlockVertexBuffer = NULL;
	}

	if(pBlockTexture)
	{
		pBlockTexture->Release();
		pBlockTexture = NULL;
	}

	if(pBlockEffect)
	{
		pBlockEffect->Release();
		pBlockEffect = 0;
	}
}

/*
 * Setup
 */
ErrorCode Environment::Setup(uint32 nGridWidth, uint32 nGridHeight)
{
	if(pGrid)
	{
		delete[] pGrid;
		pGrid = 0;
	}

	nWidth	= nGridWidth;
	nHeight	= nGridHeight;
	pGrid	= new Tower[nGridWidth * nGridHeight];

	return Error_Success;
}

/*
 * Reset
 */
void Environment::Reset()
{
	for(uint32 i = 0; i < nWidth * nHeight; ++i)
	{
		pGrid[i].State = 0;
	}
}

/*
 * Render
 */
void Environment::Render(RenderContext& kContext, Camera& kCamera)
{
	uint32 nPasses = 0;

	kContext.ApplyCameraToEffect(kCamera, pBlockEffect);

	pBlockEffect->SetTechnique(pBlockEffect->GetTechnique(0));
	pBlockEffect->Begin(&nPasses, 0);
	pBlockEffect->BeginPass(0);

	D3DXMATRIX kScaleMatrix;
	D3DXMatrixScaling(&kScaleMatrix, kScale.x, kScale.y, kScale.z);

	//const D3DXMATRIX& kProjection	= kContext.GetProjection();
	//const D3DXMATRIX& kView			= kContext.GetView();

	D3DVIEWPORT9 kViewport;
	kContext.GetViewport(&kViewport);

	D3DXVECTOR3 kCenterWorld(0.0f, 0.0f, 0.0f);
	const float fMagicOffset = 400.0f;
	//const D3DXVECTOR3& kCenterWorld = ComputeOrigin(0.5f * (ScreenSizeX - (304.0f + fMagicOffset)), 0.5f * ScreenSizeY, kViewport, kProjection, kView);

	const float fOffsetX	= -0.5f * (nWidth * kScale.x);
	const float fOffsetZ	= -0.5f * (nHeight * kScale.z);

	for(uint32 nZ = 0; nZ < nHeight; ++nZ)
	{
		for(uint32 nX = 0; nX < nWidth; ++nX)
		{
			uint32 nType	= GetType(nX, nZ);
			uint32 nHeight	= GetAltitude(nX, nZ);
			uint32 nState	= GetState(nX, nZ);
			uint32 nColor	= D3DCOLOR_XRGB(0x80, 0x80, 0x80);

			if(nType == 1)
			{
				nColor = nState ? D3DCOLOR_XRGB(0, 0, 255) : D3DCOLOR_XRGB(255, 0, 0);
			}

			for(uint32 i = 0; i < GetAltitude(nX, nZ); ++i)
			{
				D3DXMATRIX kTranslateMatrix;
				D3DXMatrixTranslation(&kTranslateMatrix, fOffsetX + (kCenterWorld.x + nX) * kScale.x, i * kScale.y, fOffsetZ + (kCenterWorld.z + nZ) * kScale.z);

				D3DXMATRIX kWorldMatrix;
				D3DXMatrixMultiply(&kWorldMatrix, &kScaleMatrix, &kTranslateMatrix);

				const float fAlpha	= ((nColor >> 24) & 0xFF) / 255.0f;
				const float fRed	= ((nColor >> 16) & 0xFF) / 255.0f;
				const float fGreen	= ((nColor >> 8 ) & 0xFF) / 255.0f;
				const float fBlue	= ((nColor >> 0 ) & 0xFF) / 255.0f;

				const D3DXVECTOR4 kColorVector(fRed, fGreen, fBlue, fAlpha);

				pBlockEffect->SetMatrix(pBlockEffect->GetParameterByName(NULL, "kWorld"), &kWorldMatrix);
				pBlockEffect->SetVector(pBlockEffect->GetParameterByName(NULL, "kColor"), &kColorVector);
				pBlockEffect->SetTexture(pBlockEffect->GetParameterByName(NULL, "kTexture"), pBlockTexture);
				pBlockEffect->CommitChanges();

				kContext.DrawTriangles(Vertex::Block::Declaration, pBlockVertexBuffer, sizeof(Vertex::Block), FacesPerCube * TrianglesPerFace);
			}
		}
	}

	pBlockEffect->EndPass();
	pBlockEffect->End();

	if(false) // wireframe
	{
		pBlockEffect->SetTechnique(pBlockEffect->GetTechniqueByName("Wire"));
		pBlockEffect->Begin(&nPasses, 0);
		pBlockEffect->BeginPass(0);

		for(uint32 nZ = 0; nZ < nHeight; ++nZ)
		{
			for(uint32 nX = 0; nX < nWidth; ++nX)
			{
				for(uint32 i = 0; i < GetAltitude(nX, nZ); ++i)
				{
					D3DXMATRIX kTranslateMatrix;
					D3DXMatrixTranslation(&kTranslateMatrix, nX * kScale.x, i * kScale.y, nZ * kScale.z);

					D3DXMATRIX kWorldMatrix;
					D3DXMatrixMultiply(&kWorldMatrix, &kScaleMatrix, &kTranslateMatrix);

					const D3DXVECTOR4 kColorVector(0.0f, 0.0f, 0.0f, 1.0f);

					pBlockEffect->SetMatrix(pBlockEffect->GetParameterByName(NULL, "kWorld"), &kWorldMatrix);
					pBlockEffect->SetVector(pBlockEffect->GetParameterByName(NULL, "kColor"), &kColorVector);
					pBlockEffect->SetTexture(pBlockEffect->GetParameterByName(NULL, "kTexture"), pBlockTexture);
					pBlockEffect->CommitChanges();

					kContext.DrawTriangles(Vertex::Block::Declaration, pBlockVertexBuffer, sizeof(Vertex::Block), FacesPerCube * TrianglesPerFace);
				}
			}
		}

		pBlockEffect->EndPass();
		pBlockEffect->End();
	}
}

/*
 * GetWidth
 */
uint32 Environment::GetWidth() const
{
	return nWidth;
}

/*
 * GetHeight
 */
uint32 Environment::GetHeight() const
{
	return nHeight;
}

/*
 * GetScale
 */
const D3DXVECTOR3& Environment::GetScale() const
{
	return kScale;
}

/*
 * SetType
 */
void Environment::SetType(uint32 nX, uint32 nY, uint32 nType)
{
	pGrid[nY * nWidth + nX].Type = nType;
}

/*
 * GetType
 */
uint32 Environment::GetType(uint32 nX, uint32 nY) const
{
	return pGrid[nY * nWidth + nX].Type;
}

/*
 * SetAltitude
 */
void Environment::SetAltitude(uint32 nX, uint32 nY, uint32 nHeight)
{
	pGrid[nY * nWidth + nX].Height = nHeight;
}

/*
 * GetAltitude
 */
uint32 Environment::GetAltitude(uint32 nX, uint32 nY) const
{
	return pGrid[nY * nWidth + nX].Height;
}

/*
 * GetState
 */
uint32 Environment::GetState(uint32 nX, uint32 nY) const
{
	return pGrid[nY * nWidth + nX].State;
}

/*
 * IsMovementValid
 */
bool Environment::IsMovementValid(uint32 nAction, uint32 nX, uint32 nY, uint32 nDirection)
{
	if(nAction == Action_Forward)
	{
		const uint32 nGridHeight = pGrid[nY * nWidth + nX].Height;

		if(nDirection == Direction_North)
		{
			if(nY + 1 < nHeight)
			{
				return nGridHeight == pGrid[(nY + 1) * nWidth + nX].Height;
			}
		}
		else

		if(nDirection == Direction_East)
		{
			if(nX + 1 < nWidth)
			{
				return nGridHeight == pGrid[nY * nWidth + nX + 1].Height;
			}
		}
		else

		if(nDirection == Direction_South)
		{
			if(nY - 1 >= 0)
			{
				return nGridHeight == pGrid[(nY - 1) * nWidth + nX].Height;
			}
		}
		else

		if(nDirection == Direction_West)
		{
			if(nX - 1 >= 0)
			{
				return nGridHeight == pGrid[nY * nWidth + nX - 1].Height;
			}
		}
	}
	else

	if(nAction == Action_Jump)
	{
		const int32 nGridHeight = (int32)pGrid[nY * nWidth + nX].Height;

		if(nDirection == Direction_North)
		{
			if(nY + 1 < nHeight)
			{
				const int32 nDelta = nGridHeight - (int32)pGrid[(nY + 1) * nWidth + nX].Height;
				return nDelta == 1 || nDelta < 0;
			}
		}
		else

		if(nDirection == Direction_East)
		{
			if(nX + 1 < nWidth)
			{
				const int32 nDelta = nGridHeight - (int32)pGrid[nY * nWidth + nX + 1].Height;
				return nDelta == 1 || nDelta < 0;
			}
		}
		else

		if(nDirection == Direction_South)
		{
			if(nY - 1 >= 0)
			{
				const int32 nDelta = nGridHeight - (int32)pGrid[(nY - 1) * nWidth + nX].Height;
				return nDelta == 1 || nDelta < 0;
			}
		}
		else

		if(nDirection == Direction_West)
		{
			if(nX - 1 >= 0)
			{
				const int32 nDelta = nGridHeight - (int32)pGrid[nY * nWidth + nX - 1].Height;
				return nDelta == 1 || nDelta < 0;
			}
		}
	}

	return false;
}

/*
 * NotifyAction
 */
void Environment::NotifyAction(uint32 nX, uint32 nY)
{
	if(pGrid[nY * nWidth + nX].Type == Tower_Light)
	{
		pGrid[nY * nWidth + nX].State ^= 1;
	}
}

/*
 * RequirementsMet
 */
bool Environment::RequirementsMet() const
{
	for(uint32 i = 0; i < nWidth * nHeight; ++i)
	{
		if(pGrid[i].Type == Tower_Light)
		{
			if(!pGrid[i].State)
			{
				return false;
			}
		}
	}

	return true;
}

/*
 * SetupVertexBuffer
 */
ErrorCode Environment::SetupVertexBuffer()
{
	Vertex::Block* pVertices = NULL;
	
	HRESULT hResult = pBlockVertexBuffer->Lock(0, 0, (void**)&pVertices, D3DLOCK_DISCARD);
	if(FAILED(hResult))
	{
		return Error_Fail;
	}

	const float fU1	= 0.66f;
	const float fV1 = 0.66f;

	// front
	pVertices[0]	= Vertex::Block(-0.5f, 0.0f, -0.5f, 0.0f, 0.0f, -1.0f, 0.00f, 1.00f);
	pVertices[1]	= Vertex::Block(-0.5f, 1.0f, -0.5f, 0.0f, 0.0f, -1.0f, 0.00f, 0.66f);
	pVertices[2]	= Vertex::Block(+0.5f, 1.0f, -0.5f, 0.0f, 0.0f, -1.0f, 1.00f, 0.66f);
	pVertices[3]	= Vertex::Block(-0.5f, 0.0f, -0.5f, 0.0f, 0.0f, -1.0f, 0.00f, 1.00f);
	pVertices[4]	= Vertex::Block(+0.5f, 1.0f, -0.5f, 0.0f, 0.0f, -1.0f, 1.00f, 0.66f);
	pVertices[5]	= Vertex::Block(+0.5f, 0.0f, -0.5f, 0.0f, 0.0f, -1.0f, 1.00f, 1.00f);
	// back
	pVertices[6]	= Vertex::Block(+0.5f, 0.0f, +0.5f, 0.0f, 0.0f, +1.0f, 0.00f, 1.00f);
	pVertices[7]	= Vertex::Block(+0.5f, 1.0f, +0.5f, 0.0f, 0.0f, +1.0f, 0.00f, 0.66f);
	pVertices[8]	= Vertex::Block(-0.5f, 1.0f, +0.5f, 0.0f, 0.0f, +1.0f, 1.00f, 0.66f);
	pVertices[9]	= Vertex::Block(+0.5f, 0.0f, +0.5f, 0.0f, 0.0f, +1.0f, 0.00f, 1.00f);
	pVertices[10]	= Vertex::Block(-0.5f, 1.0f, +0.5f, 0.0f, 0.0f, +1.0f, 1.00f, 0.66f);
	pVertices[11]	= Vertex::Block(-0.5f, 0.0f, +0.5f, 0.0f, 0.0f, +1.0f, 1.00f, 1.00f);
	// left
	pVertices[12]	= Vertex::Block(-0.5f, 0.0f, +0.5f, -1.0f, 0.0f, 0.0f, 0.00f, 1.00f);
	pVertices[13]	= Vertex::Block(-0.5f, 1.0f, +0.5f, -1.0f, 0.0f, 0.0f, 0.00f, 0.66f);
	pVertices[14]	= Vertex::Block(-0.5f, 1.0f, -0.5f, -1.0f, 0.0f, 0.0f, 1.00f, 0.66f);
	pVertices[15]	= Vertex::Block(-0.5f, 0.0f, +0.5f, -1.0f, 0.0f, 0.0f, 0.00f, 1.00f);
	pVertices[16]	= Vertex::Block(-0.5f, 1.0f, -0.5f, -1.0f, 0.0f, 0.0f, 1.00f, 0.66f);
	pVertices[17]	= Vertex::Block(-0.5f, 0.0f, -0.5f, -1.0f, 0.0f, 0.0f, 1.00f, 1.00f);
	// right
	pVertices[18]	= Vertex::Block(+0.5f, 0.0f, -0.5f, +1.0f, 0.0f, 0.0f, 0.00f, 1.00f);
	pVertices[19]	= Vertex::Block(+0.5f, 1.0f, -0.5f, +1.0f, 0.0f, 0.0f, 0.00f, 0.66f);
	pVertices[20]	= Vertex::Block(+0.5f, 1.0f, +0.5f, +1.0f, 0.0f, 0.0f, 1.00f, 0.66f);
	pVertices[21]	= Vertex::Block(+0.5f, 0.0f, -0.5f, +1.0f, 0.0f, 0.0f, 0.00f, 1.00f);
	pVertices[22]	= Vertex::Block(+0.5f, 1.0f, +0.5f, +1.0f, 0.0f, 0.0f, 1.00f, 0.66f);
	pVertices[23]	= Vertex::Block(+0.5f, 0.0f, +0.5f, +1.0f, 0.0f, 0.0f, 1.00f, 1.00f);
	// top
	pVertices[24]	= Vertex::Block(-0.5f, 1.0f, -0.5f, 0.0f, +1.0f, 0.0f, 0.00f, 0.66f);
	pVertices[25]	= Vertex::Block(-0.5f, 1.0f, +0.5f, 0.0f, +1.0f, 0.0f, 0.00f, 0.00f);
	pVertices[26]	= Vertex::Block(+0.5f, 1.0f, +0.5f, 0.0f, +1.0f, 0.0f, 1.00f, 0.00f);
	pVertices[27]	= Vertex::Block(-0.5f, 1.0f, -0.5f, 0.0f, +1.0f, 0.0f, 0.00f, 0.66f);
	pVertices[28]	= Vertex::Block(+0.5f, 1.0f, +0.5f, 0.0f, +1.0f, 0.0f, 1.00f, 0.00f);
	pVertices[29]	= Vertex::Block(+0.5f, 1.0f, -0.5f, 0.0f, +1.0f, 0.0f, 1.00f, 0.66f);
	// bottom
	pVertices[30]	= Vertex::Block(-0.5f, 0.0f, +0.5f, 0.0f, -1.0f, 0.0f, 0.00f, 0.66f);
	pVertices[31]	= Vertex::Block(-0.5f, 0.0f, -0.5f, 0.0f, -1.0f, 0.0f, 0.00f, 0.00f);
	pVertices[32]	= Vertex::Block(+0.5f, 0.0f, -0.5f, 0.0f, -1.0f, 0.0f, 1.00f, 0.00f);
	pVertices[33]	= Vertex::Block(-0.5f, 0.0f, +0.5f, 0.0f, -1.0f, 0.0f, 0.00f, 0.66f);
	pVertices[34]	= Vertex::Block(+0.5f, 0.0f, -0.5f, 0.0f, -1.0f, 0.0f, 1.00f, 0.00f);
	pVertices[35]	= Vertex::Block(+0.5f, 0.0f, +0.5f, 0.0f, -1.0f, 0.0f, 1.00f, 0.66f);

	pBlockVertexBuffer->Unlock();

	return Error_Success;
}