Schlep’s Labyrinth

Schlep
Here is my final project for my BS in Game Development at Full Sail University.

This is a small teaser trailer for Schlep’s Labyrinth. It’s kinda rough, but we like it.

 

Here again is the Alpha build of our game.

 

Here is the core build of Schlep’s Labyrinth.

Here are a few code samples from the Rendering engine that I designed and implemented for Schlep’s Labyrinth: If you would like a more in depth explanation of the classes and function herein, please grab the explanation Document here.

RenderSet.cpp:

/***********************************************
* Filename: AP_RenderSet.cpp
* Date: 04/29/2011
* Mod. Date: 05/09/2011
* Mod. Initials: ACS
* Author: Aaron Schie
* Purpose: This is the class for the viewable
* RenderSet
************************************************/

#include "StdAfx.h"
#include "AP_RenderSet.h"
#include "AP_Renderer.h"
#include "AP_GameObject.h"
#include "AP_AbstractState.h"
#include "AP_StateMachine.h"
#include "AP_GameplayState.h"
#include "../Common/AP_Model.h"
#include "AP_ModelManager.h"
#include "AP_AnimationManager.h"
#include "AP_TextureManager.h"
#include "AP_AudioManager.h"

CRenderSet::CRenderSet(void)
{
//m_pRendFunc = NULL;

//m_d3dVertexBuffer = NULL;
//m_d3dTransformBuffer = NULL;
//m_d3dIndexBuffer = NULL;

#if _DEBUG
memset(&m_ColMaterial,0,sizeof(D3DMATERIAL9));

m_ColMaterial.Diffuse.a = 1.0f;
m_ColMaterial.Diffuse.r = 1.0f;
m_ColMaterial.Diffuse.g = 1.0f;
m_ColMaterial.Diffuse.b = 1.0f;

m_ColMaterial.Ambient.a = 1.0f;
m_ColMaterial.Ambient.r = 0.0f;
m_ColMaterial.Ambient.g = 1.0f;
m_ColMaterial.Ambient.b = 0.0f;
#endif

m_RenderList.clear();
#if _DEBUG
memset(&m_CollisionBox,0,sizeof(LPD3DXMESH));
#endif
}

CRenderSet::~CRenderSet(void)
{
#if _DEBUG
if(m_CollisionBox)
{
m_CollisionBox->Release();
m_CollisionBox = NULL;
}
#endif
}

/*****************
* Accessors *
*****************/
CVector<CGameObject*>& CRenderSet::GetRenderList()
{
return m_RenderList;
}

CRenderContext* CRenderSet::GetRenderContext()
{
return &m_cContext;
}

#if _DEBUG
LPD3DXMESH CRenderSet::GetCollisionMesh()
{
return m_CollisionBox;
}
#endif

/******************
* Mutators *
******************/
void CRenderSet::SetRenderContext(CRenderContext* cContext)
{
// ATTN_
m_cContext = *cContext;
}

//void CRenderSet::SetRenderFunction(RENDERFUNC func)
//{
// m_pRendFunc = func;
//}

bool CRenderSet::AddObject(CGameObject* cObj)
{
if(cObj)
{
m_RenderList.push(cObj);
return true;
}
return false;
}

bool CRenderSet::RemoveObject(CGameObject* cObj)
{
// ATTN_ write this!
return true;
}

void CRenderSet::ClearList()
{
m_RenderList.clear();
}

void CRenderSet::Render()
{
//////////////////////////////////////////////////////////////////////////////////
// here is where we will get the pointers to all the directX stuff
IDirect3DDevice9* d3dDevice = CRenderer::GetInstance()->GetDevice();
ID3DXEffect* d3dEffect = CRenderer::GetInstance()->GetEffect(m_cContext.GetShaderID());
///////////////////////////////////////////////////////////////////////////////////

for(unsigned int nObj = 0; nObj < m_RenderList.Getsize(); ++nObj)
{
///////////////////////////////
// snatch the type and save it for less accesses
int nObjType = m_RenderList[nObj]->GetType();
int nID = m_RenderList[nObj]->GetId();
///////////////////////////////

int nNumVerts = 0;
int nNumTris = 0;

//d3dDevice->SetRenderState(D3DRS_FILLMODE,D3DFILL_WIREFRAME);
/////////////////////////////////////////
if (d3dEffect)
{
d3dEffect->SetTechnique(m_cContext.GetTechnique());

CModel* cMesh = DetermineMeshAndSetSources(m_RenderList[nObj],nNumVerts,nNumTris);

// shader stuff
UINT uPasses = 0;
d3dEffect->Begin(&uPasses, 0);
for(UINT uPass=0; uPass<uPasses; uPass++)
{
d3dEffect->BeginPass(uPass);

if(cMesh)
{
PassArgsToShader(d3dEffect,cMesh,m_RenderList[nObj]);
}

d3dEffect->CommitChanges();

// draw the triangle
d3dDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST,0,0,nNumVerts,0,nNumTris);

d3dEffect->EndPass();
}
d3dEffect->End();
}
/////////////////////////////////////////
}
}

void CRenderSet::RenderTransparents()
{
//////////////////////////////////////////////////////////////////////////////////
// here is where we will get the pointers to all the directX stuff
IDirect3DDevice9* d3dDevice = CRenderer::GetInstance()->GetDevice();
ID3DXEffect* d3dEffect = CRenderer::GetInstance()->GetEffect(m_cContext.GetShaderID());
///////////////////////////////////////////////////////////////////////////////////

if(m_RenderList.Getsize() > 0)
{
//d3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE,true);
for(int nObj = ((int)m_RenderList.Getsize()-1); nObj >= 0 ; --nObj)
{
///////////////////////////////
// snatch the type and save it for less accesses
int nObjType = m_RenderList[nObj]->GetType();
int nID = m_RenderList[nObj]->GetId();
///////////////////////////////
int nNumVerts = 0;
int nNumTris = 0;

//d3dDevice->SetRenderState(D3DRS_FILLMODE,D3DFILL_WIREFRAME);
/////////////////////////////////////////
if (d3dEffect)
{
d3dEffect->SetTechnique(m_cContext.GetTechnique());
CModel* cMesh = DetermineMeshAndSetSources(m_RenderList[nObj],nNumVerts,nNumTris);

UINT uPasses = 0;
d3dEffect->Begin(&uPasses, 0);
for(UINT uPass=0; uPass<uPasses; uPass++)
{
d3dEffect->BeginPass(uPass);

if(cMesh)
{
PassArgsToShader(d3dEffect,cMesh,m_RenderList[nObj]);
}

d3dEffect->CommitChanges();

// draw the triangle
d3dDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST,0,0,nNumVerts,0,nNumTris);

d3dEffect->EndPass();
}
d3dEffect->End();
}
/////////////////////////////////////////
}
//d3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE,false);
}
}

int CRenderSet::FlickerSwap(CGameObject* pObj)
{
// here we will determine randomly if this particular object should swap or not
// should cause a random flicker effect on objects that need it

if(!pObj)
{
return -1;
}
int nType = pObj->GetType();

if(!pObj->IsFlickering())
{
if(pObj->GetTextSwapID() != TEXTURE_FAIL && pObj->IsPowered())
{
// it should not swap and should not have gotten in here
return pObj->GetTextSwapID();
}
else
{
return pObj->GetMeshTextID();
}
}

static bool bSwap = false;
static int nCount = 1;
// else do this
// random number
int nRand = rand();
nCount += (int)(CGame::GetInstance()->GetDeltaTime()*1000); // makes the time divisible by a whole number(even when it truncates)
if(bSwap && (nRand % nCount) == 0)
{
bSwap = false;
pObj->SetPowered(false);
}
else if((nCount%8) == 0)
{
bSwap = true;
nCount = 1;
pObj->SetPowered(true);
}

int nReturn;
if(bSwap)
{
nReturn = pObj->GetTextSwapID();
// we need to send back the "swap" texture
return (nReturn != TEXTURE_FAIL) ? nReturn : pObj->GetMeshTextID();
}
else
{
return pObj->GetMeshTextID();
}
}

void CRenderSet::PassArgsToShader(ID3DXEffect* d3dEffect, CModel* pModel, CGameObject* pObj)
{
// Here we will determine which arguments to pass and set in the shader passed in
// by using the mesh data and object data passed in
DetermineTextures(d3dEffect,pObj);
DetermineUVScroll(d3dEffect,pModel,pObj);
SetUpWorld(d3dEffect,pObj);
SetUpAnimated(d3dEffect,pObj);
SetUpSceneLights(d3dEffect);
}

void CRenderSet::DetermineTextures(ID3DXEffect* d3dEffect,CGameObject* pObj)
{
/////////////////////////////////////////////////////
// set the shader textures
d3dEffect->SetTexture("g_ObjTexture",CTextureManager::GetInstance()->GetTexture(FlickerSwap(pObj)));
//if(pObj->GetTextSwapID() > TEXTURE_FAIL && pObj->IsPowered())
//{
if(pObj->GetIncandescenseID() > TEXTURE_FAIL && pObj->IsPowered())
{
d3dEffect->SetBool("g_bHasIncan",true);
d3dEffect->SetTexture("g_IncandText",CTextureManager::GetInstance()->GetTexture(pObj->GetIncandescenseID()));
}
else
{
d3dEffect->SetBool("g_bHasIncan",false);
}
//}

// LightMaps
if(pObj->GetLightMapID() > TEXTURE_FAIL)
{
d3dEffect->SetBool("g_bLightMap",true);
d3dEffect->SetTexture("g_LightMap",CTextureManager::GetInstance()->GetTexture(pObj->GetLightMapID()));
}
else
{
d3dEffect->SetBool("g_bLightMap",false);
}
////////////////////////////////////////////////////////////////
}

void CRenderSet::DetermineUVScroll(ID3DXEffect *d3dEffect,CModel* pModel, CGameObject* pObj)
{
//std::string strMeshName = cMesh->GetMeshName();
//int nCheck = strMeshName.find("Outermesh");
//if(nCheck != std::string::npos)
//{
// static float fPrevScroll = 0;
// float fUScroll = m_RenderList[nObj]->GetUScrollAmt()*CGame::GetInstance()->GetCurrTime();
// float fDiff = abs(fUScroll/FLT_MAX);// - fPrevScroll);//abs(fUScroll - fPrevScroll);
// //fDiff = 1/fDiff;
// if(fDiff >= 0.75f && fDiff <= 1.0f)
// {
// CAudioManager::GetInstance()->PlaySoundEvent(AE_MENU_ACCEPT,KGO_MENU);
// }
// fPrevScroll = fUScroll;
//}
//d3dEffect->SetFloat("g_fUScroll",m_RenderList[nObj]->GetUScrollAmt()*CGame::GetInstance()->GetCurrTime());
//d3dEffect->SetFloat("g_fVScroll",m_RenderList[nObj]->GetVScrollAmt()*CGame::GetInstance()->GetCurrTime());

// determine the UV Scroll Values to pass over to the passed in Shader
// for Direction (if needed)
int nDirection = 1;
int nObjType = pObj->GetType();
if(pModel)
{
////////////////////////////////////////////////////////////////////////////////
// Conveyor are a special case that falls in here
if(nObjType == OBJ_CONVEYOR_ENDBELT && nObjType == OBJ_CONVEYOR_MIDDLEBELT)
{
CGameObject* pConvTest = pObj->GetFirstControllingInstance(OBJ_CONVEYOR_BRAIN);
if(pConvTest)
{
///////////////////////////////////////////////////
// this is for if the conveyor is on (belts moving)
if(pConvTest->TestFlag(AIF_CONVEYOR_POWERED))
{
// will be based on direction
if(pConvTest->TestFlag(AIF_CONVEYOR_CLOCKWISE,true))
{
nDirection = -1;
}
else
{
nDirection = 1;
}
d3dEffect->SetFloat("g_fUScroll",nDirection*(pObj->GetUScrollAmt()*CGame::GetInstance()->GetCurrTime()));
d3dEffect->SetFloat("g_fVScroll",nDirection*(pObj->GetVScrollAmt()*CGame::GetInstance()->GetCurrTime()));
}
//////////////////////////////////////////////////
// else it is off (belts not moving)
else
{
d3dEffect->SetFloat("g_fUScroll",0.0f);
d3dEffect->SetFloat("g_fVScroll",0.0f);
}
////////////////////////////////////////////////////
}
}
//////////////////////////////////////////////////////////////////////////////////
// special case for the interpolation between textures on the PowerBay Timer
else if(nObjType == OBJ_BAY_TIMER)
{
CGameObject* pParentObj = pObj->GetFirstControllingInstance(OBJ_BAY);
float fLambda = pParentObj->GetStateTime();
float fNewMax = pParentObj->GetTimerMax()/2.0f;
fLambda -= fNewMax;
if(pParentObj->TestFlag(AIF_POWERBAY_ONOFF) && fLambda > 0.0f)
{
d3dEffect->SetFloat("g_fUScroll", fLambda/fNewMax);
}
else
{
d3dEffect->SetFloat("g_fUScroll", 0.0f);
}
}
// special case for the BUG GLOWS to fade with the beat of the music
else if(nObjType == OBJ_BUG_GLOW)
{
d3dEffect->SetBool("g_bFadeOut",true);
d3dEffect->SetFloat("g_fUScroll",pObj->GetUScrollAmt());
}
////////////////////////////////////////////////////////////////////////////////
// to Set the scroll of every object that isn't a special case ( these are set at object load time)
// this will also happen most frequently
else
{
d3dEffect->SetFloat("g_fUScroll",pObj->GetUScrollAmt()*CGame::GetInstance()->GetCurrTime());
d3dEffect->SetFloat("g_fVScroll",pObj->GetVScrollAmt()*CGame::GetInstance()->GetCurrTime());
}
}
}

void CRenderSet::SetUpWorld(ID3DXEffect* d3dEffect,CGameObject* pObj)
{
///////////////////////
//// camera pointer
CCamera* cCamera = CRenderer::GetInstance()->GetCamera();
///////////////////////

// getting the matrices from the Camera and the object
D3DXMATRIX d3dObjMatrix = pObj->GetWorldMat();
D3DXMATRIX d3dLocalMat = pObj->GetLocalMat();
d3dObjMatrix = (d3dLocalMat*d3dObjMatrix);
D3DXMATRIX d3dWVP = (d3dObjMatrix*(*cCamera->GetViewMatrix())*(*cCamera->GetProjectionMatrix()));

D3DXMATRIX invTransMat;
D3DXMatrixInverse(&invTransMat,NULL,&d3dObjMatrix);
D3DXMatrixTranspose(&invTransMat,&invTransMat);

d3dEffect->SetMatrix("g_mWorld",&d3dObjMatrix);
d3dEffect->SetMatrix("g_mInverseTransWorld",&invTransMat);
d3dEffect->SetMatrix("g_mWVP", &d3dWVP);

// for debug drawing of collision boxes and normals
#if _DEBUG
// for debugging purposes we will draw the collision boxes
if(CRenderer::GetInstance()->GetDebugCollision())
{
D3DXMATRIX identity;
D3DXMatrixIdentity(&identity);

TAABB tCollisionBox = pObj->GetCollisionBox();

float tempWidth = tCollisionBox.d3dBotRight.x - tCollisionBox.d3dTopLeft.x;
float tempHeight = tCollisionBox.d3dTopLeft.y - tCollisionBox.d3dBotRight.y;
float tempDepth = tCollisionBox.d3dBotRight.z - tCollisionBox.d3dTopLeft.z;

D3DXMATRIX tempMatrix = d3dObjMatrix;
switch(pObj->GetType())
{
case OBJ_BAY:
{
tempMatrix._42 += ((0.5f)*tempHeight);
tempMatrix._41 += ((0.5f)*tempWidth);
tempMatrix._43 += ((0.5f)*tempDepth);
}
break;
case OBJ_GROUND0:
{
tempMatrix._41 += ((0.5f)*tempWidth);
tempMatrix._42 -= ((0.5f)*tempHeight);
tempMatrix._43 += ((0.5f)*tempDepth);
}
break;
case OBJ_GROUND1:
{
tempMatrix._41 += ((0.5f)*tempWidth);
tempMatrix._42 -= ((0.5f)*tempHeight);
tempMatrix._43 += ((0.5f)*tempDepth);
}
break;
case OBJ_GROUND2:
{
tempMatrix._41 += ((0.5f)*tempWidth);
tempMatrix._42 -= ((0.5f)*tempHeight);
tempMatrix._43 += ((0.5f)*tempDepth);
}
break;
case OBJ_GROUND3:
{
tempMatrix._41 += ((0.5f)*tempWidth);
tempMatrix._42 -= ((0.5f)*tempHeight);
tempMatrix._43 += ((0.5f)*tempDepth);
}
break;
case OBJ_WALL:
{
tempMatrix._41 -= ((0.5f)*tempWidth);
tempMatrix._42 += ((0.5f)*tempHeight);
tempMatrix._43 += ((0.5f)*tempDepth);
}
break;
case OBJ_DOOR_TRAP:
{
tempMatrix._41 += ((0.5f)*tempWidth);
tempMatrix._42 -= ((0.5f)*tempHeight);
tempMatrix._43 += ((0.5f)*tempDepth);
}
break;
case OBJ_SCHLEP:
{
tCollisionBox.d3dBotRight;// /= DEF_MODEL_SCALE;
tCollisionBox.d3dTopLeft;// /= DEF_MODEL_SCALE;

tempWidth = tCollisionBox.d3dBotRight.x - tCollisionBox.d3dTopLeft.x;
tempHeight = tCollisionBox.d3dTopLeft.y - tCollisionBox.d3dBotRight.y;
tempDepth = tCollisionBox.d3dBotRight.z - tCollisionBox.d3dTopLeft.z;

//tempMatrix._41 += ((0.5f)*tempWidth);
tempMatrix._42 += ((0.5f)*tempHeight);
}
break;
default:
{
tempMatrix._42 += ((0.5f)*tempHeight);
}
break;
};

D3DXCreateBox(CRenderer::GetInstance()->GetDevice(),tempWidth,tempHeight,tempDepth,&m_CollisionBox,NULL);
//D3DXCreateSphere(d3dDevice,tempWidth/2,12,6,&m_CollisionBox,NULL);

CRenderer::GetInstance()->GetDevice()->SetMaterial(&m_ColMaterial);
CRenderer::GetInstance()->GetDevice()->SetTransform(D3DTS_VIEW,cCamera->GetViewMatrix());
CRenderer::GetInstance()->GetDevice()->SetTransform(D3DTS_PROJECTION,cCamera->GetProjectionMatrix());
CRenderer::GetInstance()->GetDevice()->SetTransform(D3DTS_WORLD,&tempMatrix);

CRenderer::GetInstance()->GetDevice()->SetRenderState(D3DRS_LIGHTING,false);
CRenderer::GetInstance()->GetDevice()->SetRenderState(D3DRS_FILLMODE,D3DFILL_WIREFRAME);
m_CollisionBox->DrawSubset(0);
CRenderer::GetInstance()->GetDevice()->SetRenderState(D3DRS_FILLMODE,D3DFILL_SOLID);
CRenderer::GetInstance()->GetDevice()->SetRenderState(D3DRS_LIGHTING,true);
m_CollisionBox->Release();
m_CollisionBox = NULL;
}

if(CRenderer::GetInstance()->GetDebugNormals())
{
//////////////////////////////////
// attempt to render the normal vectors of the normals using lines
ID3DXLine* d3dLine = CRenderer::GetInstance()->GetLineObject();

if(pObj->GetType() > OBJ_MOVING && pObj->GetType() < OBJ_ANIMATED)
{
// it will be moving, so I can safely cast the model to a moving model
CMovingModel* cModel = (CMovingModel*)pObj->GetMeshPointer();
CVector vVerts = cModel->GetUniqueVertsByValue();
for(unsigned int nVert = 0; nVert < vVerts.Getsize();++nVert)
{
D3DXVECTOR3 vNormal[2];
vNormal[0] = vVerts[nVert].d3dVert;
vNormal[1] = vVerts[nVert].d3dVert + (vVerts[nVert].d3dNormal * 1.0f);
d3dLine->DrawTransform(vNormal,2,&(d3dObjMatrix*(*cCamera->GetViewMatrix())*(*cCamera->GetProjectionMatrix())),
D3DCOLOR_XRGB(255,0,255));
}
}
}
//////////////////////////////////
#endif
}

void CRenderSet::SetUpAnimated(ID3DXEffect* d3dEffect,CGameObject* pObj)
{
// if its animated, get it's interpolator and pass over the matrices
if(pObj->GetType() > OBJ_ANIMATED)
{
CInterpolator* pInterp = CAnimationManager::GetInstance()->GetInterpolator(pObj->GetId(), pObj->GetType());
d3dEffect->SetMatrixArray("Bones", CAnimationManager::GetInstance()->GetCurrentMatrices(pObj->GetId(), pObj->GetType()),
pInterp->GetCurFrame().Getsize());
}
}

void CRenderSet::SetUpSceneLights(ID3DXEffect* d3dEffect)
{
// pass the lights over to be calculated

// static created lights for the load state
if(CGame::GetInstance()->IsLoadState())
{
TLight* tLoadLight = CRenderer::GetInstance()->GetLoadLight();
d3dEffect->SetRawValue("g_Lights",&tLoadLight[0],0,(sizeof(TLight)*2));
d3dEffect->SetInt("g_nNumLights",2);
}
// lights loaded in from the level
// pass the Light structure array over to the shader
else
{
TLight* tLights = CRenderer::GetInstance()->GetLights();
int numLights = CRenderer::GetInstance()->GetNumLights();

d3dEffect->SetRawValue("g_Lights",&tLights[0],0,
(sizeof(TLight)*numLights));

d3dEffect->SetInt("g_nNumLights",numLights);
}
// level ambient light
d3dEffect->SetValue("g_vAmbientLightColor", &CRenderer::GetInstance()->GetLevelAmbient(), sizeof(D3DXCOLOR));
// level dependant ligthmap brightening value
d3dEffect->SetFloat("g_fLevelValue",CRenderer::GetInstance()->GetLevelLightMapRatio());
// material attributes (mostly standard white)
d3dEffect->SetValue("g_vDiffuseMaterial", &m_cContext.GetMaterialAttributes()->diffuseMatColor, sizeof(D3DXCOLOR));
d3dEffect->SetValue("g_vAmbientMaterial", &m_cContext.GetMaterialAttributes()->ambientMatColor, sizeof(D3DXCOLOR));
d3dEffect->SetValue("g_vSpecMaterial", &m_cContext.GetMaterialAttributes()->specMatColor, sizeof(D3DXCOLOR));
}

CModel* CRenderSet::DetermineMeshAndSetSources(CGameObject* pObj,int& nNumVertsOut,int& nNumTrisOut)
{
// grab the device from the Renderer
IDirect3DDevice9* d3dDevice = CRenderer::GetInstance()->GetDevice();
d3dDevice->AddRef();

// find out the type and set the sources accordingly
if(pObj->GetType() > OBJ_ANIMATED)
{
CAnimModel* cAnim = (CAnimModel*)pObj->GetMeshPointer();

nNumVertsOut = cAnim->GetAnimUniqueVerts()->Getsize();
nNumTrisOut = cAnim->GetTris()->Getsize();

d3dDevice->SetVertexDeclaration(CRenderer::GetInstance()->GetAnimDecl());
d3dDevice->SetStreamSource(0, *(cAnim->GetVertexBuffer()), 0, sizeof(TAnimVertex));
d3dDevice->SetIndices(*(cAnim->GetIndexBuffer()));

// release Device
d3dDevice->Release();

return cAnim;
}
else
{
CModel* cMesh = pObj->GetMeshPointer();

if(cMesh->isMoving())
{
CMovingModel* cMovModel = (CMovingModel*)pObj->GetMeshPointer();

nNumVertsOut = cMovModel->GetUniqueVerts()->Getsize();
nNumTrisOut = cMovModel->GetTris()->Getsize();

d3dDevice->SetVertexDeclaration(CRenderer::GetInstance()->GetMovingDecl());
d3dDevice->SetStreamSource(0, *(cMovModel->GetVertexBuffer()), 0, sizeof(TVertex));
d3dDevice->SetIndices(*(cMesh->GetIndexBuffer()));

// release Device
d3dDevice->Release();

return cMovModel;
}
else
{
nNumVertsOut = cMesh->GetUniqueVerts()->Getsize();
nNumTrisOut = cMesh->GetTris()->Getsize();

d3dDevice->SetVertexDeclaration(CRenderer::GetInstance()->GetVertDecl());
d3dDevice->SetStreamSource(0, *(cMesh->GetVertexBuffer()), 0, sizeof(TStaticVertex));
d3dDevice->SetIndices(*(cMesh->GetIndexBuffer()));

// release Device
d3dDevice->Release();

return cMesh;
}
}
}

Renderer.cpp:

/***********************************************
* Filename: AP_Renderer.cpp
* Date: 04/29/2011
* Mod. Date: 05/12/2011
* Mod. Initials: ACS
* Author: Aaron Schie
* Purpose: This class houses the specific
* API code for Rendering all the
* objects in the viewable set.
************************************************/

#include "StdAfx.h"
#include "AP_Renderer.h"
#include "AP_RenderSet.h"
#include "AP_RenderContext.h"
#include "AP_ObjectManager.h"
#include "AP_Gameplaystate.h"
#include "AP_StateMachine.h"
#include "AP_FontManager.h"
#include "AP_Interpolator.h"
#include "../Common/AP_Model.h"
#include "AP_AnimationManager.h"
#include "AP_ParticleManager.h"
#include "AP_TextureManager.h"
#include "AP_LoseState.h"
#include "AP_SubtitleManager.h"
#include "AP_InputManager.h"

// TEMPORARY
#include "AP_AbstractState.h"
#include "AP_GamePlayState.h"

///////////////////////////////
// HUD defines
#define TIMER_POS_X 87
#define TIMER_POS_Y 98
#define HUD_BUG_POS_X 6
#define HUD_BUG_POS_Y 38
#define HUD_BUG_WIDTH 64
#define FPS_POS_X 500
#define FPS_POS_Y 64
#define LEVEL_TEXT_POSX 256
#define LEVEL_TEXT_POSY 120
///////////////////////////////

////////////////
// Global Shader strings
char g_chShaders[SHADER_EFFECT_TOTAL][64];
////////////////

/////////////////////////////
// initialize the instance member
CRenderer* CRenderer::m_pInstance = NULL;
/////////////////////////////

CRenderer::CRenderer(void)
{
m_tMasterLightList.clear();
m_tDeathLights.clear();
m_szDebugStrings.clear();

memset(&m_tLevelAttributes,0,sizeof(TLevelAttributes));
}

CRenderer* CRenderer::GetInstance()
{
if(!m_pInstance)
{
m_pInstance = new CRenderer();
}
return m_pInstance;
}
void CRenderer::Initialize(HWND hWnd, float fFieldOfView, float fAspectRatio, float fNearPlane, float fFarPlane)
{
m_pd3dDevice = NULL;
m_pd3dD3D = NULL;
m_d3dSprMgr = NULL;
m_d3dFont = NULL;
#if _DEBUG
m_d3dLine = NULL;
#endif
m_pd3dVertDecl = NULL;
m_pd3dAnimDecl = NULL;

// effect files NULL
for(int nShaderLoop = 0; nShaderLoop < SHADER_EFFECT_TOTAL; ++nShaderLoop)
{
m_pd3dEffects[nShaderLoop] = NULL;
}

//////////////////////////
// init the shader file array
for(int nShader = 0; nShader < SHADER_EFFECT_TOTAL;++nShader)
{
if(nShader == SHADER_EFFECT_BASIC)
{
strcpy_s(g_chShaders[nShader],24,"Assets/Shaders/basic.fx");
}
else if(nShader == SHADER_EFFECT_BASIC_LIT)
{
strcpy_s(g_chShaders[nShader],27,"Assets/Shaders/basicLit.fx");
}
else if(nShader == SHADER_EFFECT_SKINNING)
{
strcpy_s(g_chShaders[nShader],27,"Assets/Shaders/Skinning.fx");
}
else if(nShader == SHADER_EFFECT_PARTICLE)
{
strcpy_s(g_chShaders[nShader],33,"Assets/Shaders/ParticleShader.fx");
}
else if(nShader == SHADER_EFFECT_POWER_BAY)
{
strcpy_s(g_chShaders[nShader],33,"Assets/Shaders/PowerBayShader.fx");
}
}
///////////////////////////

////////////////////////////////////////////
// Register for events for the
// achieve pop-up and the end of level light
CEventSystem::GetInstance()->Register(EV_GINPUT_PAUSE,this);
CEventSystem::GetInstance()->Register(EV_DEATH_RESET_ALL,this);
CEventSystem::GetInstance()->Register(EV_ENVINT_BAY_LOCK,this);
CEventSystem::GetInstance()->Register(EV_ENVINT_BAY_ON,this);
CEventSystem::GetInstance()->Register(EV_ENVINT_BAY_OFF,this);
CEventSystem::GetInstance()->Register(EV_DISPLAY_TOGGLE,this);

//m_HUDBugList = NULL;
m_bPopUp = false;
m_nEOLLockCount = 0;
m_fBayTimeRemaining = 0;
m_fGamma = 0.0f;
////////////////////////////////////////////

////////////////////////
// Lights
m_nLightCount = 0;
memset(m_tLights,0,sizeof(TLight)*MAX_LIGHTS);

// this is just a default ambient light amount, the real one will get read in and set on level load
m_tLevelAttributes.d3dAmbientLightColor = D3DXCOLOR(.01f,.01f,.01f,0.1f);
m_tLevelAttributes.fLevelLightMapRatio = 0.25f;
// Load level light
memset(&m_tLoadLight,0,sizeof(TLight)*2);
////////////////////////

m_bDebugMode = false;
m_bDebugCollision = false;
m_bDebugNormals = false;

D3DXMatrixOrthoRH(&m_d3dOrthoMatrix,8.0f,6.0f,0.2f,500.0f);

///////////////////////////
m_cCamera.BuildPerspective(fFieldOfView,fAspectRatio,fNearPlane,fFarPlane);
m_cCamera.ViewTranslateLocal(CAMERA_X,CAMERA_Y,-CAMERA_DISTANCE);
///////////////////////////

///////////////////////////
// initialize the renderer
InitD3D(hWnd);
///////////////////////////

for(int nSet = 0; nSet < OBJ_TOTAL; ++nSet)
{
//if(nSet == OBJ_BUG_EYE_L || nSet == OBJ_BUG_EYE_R || nSet == OBJ_BUG_EYE_C || nSet == OBJ_SCHLEP_EYE_C || nSet == OBJ_SCHLEP_EYE_R
// || nSet == OBJ_SCHLEP_EYE_L || nSet == OBJ_SPIDER_EYE_A || nSet == OBJ_SPIDER_EYE_B || nSet == OBJ_SPIDER_EYE_C
// || nSet == OBJ_WALKER_EYE_L || nSet == OBJ_WALKER_EYE_R)
//{
// m_RenderSets[nSet].GetRenderContext()->SetShaderID(SHADER_EFFECT_BASIC_LIT);
//}
if(nSet == OBJ_BAY )
{
m_RenderSets[nSet].GetRenderContext()->SetShaderID(SHADER_EFFECT_POWER_BAY);
}
else if((nSet < OBJ_MOVING && nSet != OBJ_CONVEYOR_BASE&& nSet != OBJ_CONVEYOR_MIDDLEBELT && nSet != OBJ_CONVEYOR_ENDBELT)
|| nSet == OBJ_DOOR_SLIDING_FRAME || nSet == OBJ_LOAD_BAR || nSet == OBJ_DOOR_TRAP)
{
m_RenderSets[nSet].GetRenderContext()->SetShaderID(SHADER_EFFECT_BASIC);
}
else if(nSet < OBJ_ANIMATED && nSet != OBJ_DOOR_SLIDING_FRAME && nSet != OBJ_BAY)// && nSet != OBJ_CONVEYOR_BASE)// && nSet != OBJ_CONVEYOR_MIDDLEBELT &&
//nSet != OBJ_CONVEYOR_ENDBELT)
{
m_RenderSets[nSet].GetRenderContext()->SetShaderID(SHADER_EFFECT_BASIC_LIT);
}
else if(nSet < OBJ_TOTAL)// || nSet == OBJ_CONVEYOR_MIDDLEBELT || nSet == OBJ_CONVEYOR_ENDBELT ||
//nSet == OBJ_CONVEYOR_BASE)
{
m_RenderSets[nSet].GetRenderContext()->SetShaderID(SHADER_EFFECT_SKINNING);
}
}
int nTechnique = 0;
// init the initial techniques for the rendersets
// special for the Decorative objects
for(nTechnique = OBJ_DECORATIVE_BACKGROUND; nTechnique < OBJ_STATIC;++nTechnique)
{
if(nTechnique == OBJ_SPIDER_WEB)
{
m_RenderSets[nTechnique].GetRenderContext()->SetTechnique("Transparent");
}
else if(nTechnique == OBJ_DEATH_FADE_CARD)
{
m_RenderSets[nTechnique].GetRenderContext()->SetTechnique("DeathFade");
}
else if(nTechnique == OBJ_BUG_GLOW)
{
m_RenderSets[nTechnique].GetRenderContext()->SetTechnique("BeatFade");
}
else if(nTechnique == OBJ_BAY)
{
m_RenderSets[nTechnique].GetRenderContext()->SetTechnique("PowerBay");
}
else
{
m_RenderSets[nTechnique].GetRenderContext()->SetTechnique("LightMap");
}
}
for(nTechnique = OBJ_STATIC; nTechnique < OBJ_ANIMATED;++nTechnique)
{
m_RenderSets[nTechnique].GetRenderContext()->SetMaterialAttributes(g_AmbientMatColor,g_DiffuseMatColor,g_SpecMatColor);
if(nTechnique == OBJ_BAY_TIMER || nTechnique == OBJ_ARROW)
{
m_RenderSets[nTechnique].GetRenderContext()->SetTechnique("BayBar");
}
else if((nTechnique < OBJ_MOVING && nTechnique != OBJ_CONVEYOR_BASE && nTechnique != OBJ_CONVEYOR_MIDDLEBELT && nTechnique != OBJ_CONVEYOR_ENDBELT
&& nTechnique != OBJ_ARROW) || nTechnique == OBJ_BAY || nTechnique == OBJ_DOOR_SLIDING_FRAME || nTechnique == OBJ_DOOR_TRAP)
{
m_RenderSets[nTechnique].GetRenderContext()->SetTechnique("LightMap");
}
else if(nTechnique == OBJ_TEST_LIGHT)
{
m_RenderSets[nTechnique].GetRenderContext()->SetTechnique("TestLight");
}
else
{
m_RenderSets[nTechnique].GetRenderContext()->SetTechnique("Basic");
}
}
for(nTechnique = OBJ_ANIMATED; nTechnique < OBJ_TOTAL;++nTechnique)
{
m_RenderSets[nTechnique].GetRenderContext()->SetMaterialAttributes(g_AmbientMatColor,g_DiffuseMatColor,g_SpecMatColor);
if(nTechnique >= OBJ_SCHLEP && nTechnique <= OBJ_SPIDER)
{
m_RenderSets[nTechnique].GetRenderContext()->SetTechnique("Schlep");
}
else if(nTechnique == OBJ_NOTIFICATION)
{
m_RenderSets[nTechnique].GetRenderContext()->SetTechnique("UnlitAnimated");
}
else if(nTechnique >= OBJ_HUD_BASE && nTechnique <= OBJ_PAUSE_BASE)
{
m_RenderSets[nTechnique].GetRenderContext()->SetTechnique("Basic");
}
else
{
m_RenderSets[nTechnique].GetRenderContext()->SetTechnique("Animated");
}
}
//////////////////////////////
//////////////////////////
}
void CRenderer::Shutdown()
{
///////////////////////////////////////
// Unregister for events
CEventSystem::GetInstance()->UnregisterClientEx(this);
///////////////////////////////////////

///////////////////////////////////////
// ShutDown the D3D
ShutdownD3D();

delete m_pInstance;
///////////////////////////////////////////////////////
}

CRenderSet* CRenderer::GetRenderSets(int objType)
{
return &m_RenderSets[objType];
}

void CRenderer::InitD3D(HWND hWnd)
{
/////////////////////////////////////////////
// create the direct3D device
m_pd3dD3D = Direct3DCreate9(D3D_SDK_VERSION);
//////////////////////////////////////////////

m_pHwnd = hWnd;

//////////////////////////////////////////////
// declare the present parameters for the game
ZeroMemory(&m_d3dPresentParams,sizeof(m_d3dPresentParams));
//////////////////////////////////////////////

//////////////////////////////////////////////
if(CGame::GetInstance()->IsWindowed())
{
// set the parameters
m_d3dPresentParams.hDeviceWindow = m_pHwnd;
m_d3dPresentParams.Windowed = true;
m_d3dPresentParams.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
m_d3dPresentParams.BackBufferCount = 1;
m_d3dPresentParams.SwapEffect = D3DSWAPEFFECT_DISCARD;
m_d3dPresentParams.BackBufferHeight = WINDOW_HEIGHT;
m_d3dPresentParams.BackBufferWidth = WINDOW_WIDTH;
}
else
{
// set the parameters
//int nScreenWidth = GetSystemMetrics(SM_CXSCREEN);
//int nScreenHeight = GetSystemMetrics(SM_CYSCREEN);
//g_nWindowWidth = nScreenWidth;
//g_nWindowHeight = nScreenHeight;
m_d3dPresentParams.hDeviceWindow = m_pHwnd;
m_d3dPresentParams.Windowed = false;
m_d3dPresentParams.PresentationInterval = D3DPRESENT_INTERVAL_ONE;
m_d3dPresentParams.BackBufferCount = 1;
m_d3dPresentParams.BackBufferWidth = WINDOW_WIDTH;
m_d3dPresentParams.BackBufferHeight = WINDOW_HEIGHT;
m_d3dPresentParams.BackBufferFormat = D3DFMT_A8R8G8B8;
m_d3dPresentParams.SwapEffect = D3DSWAPEFFECT_DISCARD;

SetWindowLong(m_pHwnd, GWL_STYLE, WS_POPUP|WS_VISIBLE);
}
// ATTN_ toggle fullscreen with ALT+ENTER
///////////////////////////////////////////////
////////////////////////////////////////////////
// add for 3D
// depth /stencil
// stencil format
m_d3dPresentParams.EnableAutoDepthStencil = true;
m_d3dPresentParams.AutoDepthStencilFormat = D3DFMT_D16;
////////////////////////////////////////////////

//////////////////////////////////////////////////////
// set up and create the device using those parameters
HRESULT hr = m_pd3dD3D->CreateDevice(0,D3DDEVTYPE_HAL, hWnd, D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_MULTITHREADED, &m_d3dPresentParams, &m_pd3dDevice);
//////////////////////////////////////////////////////

// sprite setup
D3DXCreateSprite(m_pd3dDevice, &m_d3dSprMgr);

//font setup
D3DXCreateFont(m_pd3dDevice, 16, 0, FW_NORMAL, NULL, false,
DEFAULT_CHARSET, OUT_DEFAULT_PRECIS,
ANTIALIASED_QUALITY, DEFAULT_PITCH | FF_DONTCARE,
"Arial", &m_d3dFont);

#if _DEBUG
// create line object
D3DXCreateLine(m_pd3dDevice,&m_d3dLine);
#endif

// can also create the vertex declaration here since its the same for all
D3DVERTEXELEMENT9 d3dDecl[] =
{
{0,0,D3DDECLTYPE_FLOAT3,D3DDECLMETHOD_DEFAULT,D3DDECLUSAGE_POSITION,0},
{0,12,D3DDECLTYPE_FLOAT3,D3DDECLMETHOD_DEFAULT,D3DDECLUSAGE_NORMAL,0},
{0,24,D3DDECLTYPE_FLOAT2,D3DDECLMETHOD_DEFAULT,D3DDECLUSAGE_TEXCOORD,0},
{0,32,D3DDECLTYPE_FLOAT2,D3DDECLMETHOD_DEFAULT,D3DDECLUSAGE_TEXCOORD,1},
D3DDECL_END()
};

m_pd3dDevice->CreateVertexDeclaration(d3dDecl, &GetVertDecl());

D3DVERTEXELEMENT9 d3dMovingDecl[] =
{
{0,0,D3DDECLTYPE_FLOAT3,D3DDECLMETHOD_DEFAULT,D3DDECLUSAGE_POSITION,0},
{0,12,D3DDECLTYPE_FLOAT3,D3DDECLMETHOD_DEFAULT,D3DDECLUSAGE_NORMAL,0},
{0,24,D3DDECLTYPE_FLOAT2,D3DDECLMETHOD_DEFAULT,D3DDECLUSAGE_TEXCOORD,0},
D3DDECL_END()
};

m_pd3dDevice->CreateVertexDeclaration(d3dMovingDecl, &GetMovingDecl());

D3DVERTEXELEMENT9 d3dAnimDecl[] =
{
{0,0,D3DDECLTYPE_FLOAT3,D3DDECLMETHOD_DEFAULT,D3DDECLUSAGE_POSITION,0},
{0,12,D3DDECLTYPE_FLOAT3,D3DDECLMETHOD_DEFAULT,D3DDECLUSAGE_NORMAL,0},
{0,24,D3DDECLTYPE_FLOAT2,D3DDECLMETHOD_DEFAULT,D3DDECLUSAGE_TEXCOORD,0},
{0,32,D3DDECLTYPE_FLOAT3,D3DDECLMETHOD_DEFAULT,D3DDECLUSAGE_BLENDINDICES,0},
{0,44,D3DDECLTYPE_FLOAT3,D3DDECLMETHOD_DEFAULT,D3DDECLUSAGE_BLENDWEIGHT,0},
D3DDECL_END()
};

m_pd3dDevice->CreateVertexDeclaration(d3dAnimDecl,&GetAnimDecl());

LoadEffects();

m_pd3dDevice->SetRenderState(D3DRS_CULLMODE,D3DCULL_CW);
}
void CRenderer::LoadEffects()
{
////////////////////////////////////////////////////////////////////
// SHADERS
ID3DXBuffer *d3dErrors = NULL;
for(int nShader = 0; nShader < SHADER_EFFECT_TOTAL;++nShader)
{
HRESULT hr = D3DXCreateEffectFromFile(m_pd3dDevice, g_chShaders[nShader], 0, 0,
D3DXSHADER_DEBUG,0, &m_pd3dEffects[nShader], &d3dErrors);
if (d3dErrors)
MessageBox(0,(char*)d3dErrors->GetBufferPointer(),0,0);
}
////////////////////////////////////////////////////////////////////
}

void CRenderer::ShutdownD3D()
{
////////////////////////////////
// shutdown all direct3D stuff
// in reverse order
/////////////////////////////////////
// release the shader effects
for(int nLoop = 0; nLoop < SHADER_EFFECT_TOTAL;++nLoop)
{
if(m_pd3dEffects[nLoop])
{
unsigned long uTest = m_pd3dEffects[nLoop]->Release();
m_pd3dEffects[nLoop] = NULL;
}
}
if(m_pd3dAnimDecl)
{
unsigned long uCheck = m_pd3dAnimDecl->Release();
m_pd3dAnimDecl = NULL;
}
if(m_pd3dMovingDecl)
{
unsigned long uFind = m_pd3dMovingDecl->Release();
m_pd3dMovingDecl = NULL;
}
if(m_pd3dVertDecl)
{
unsigned long uLook = m_pd3dVertDecl->Release();
m_pd3dVertDecl = NULL;
}
/////////////////////////////////////
// release COM objects
#if _DEBUG
if(m_d3dLine)
{
unsigned long uMight = m_d3dLine->Release();
m_d3dLine = NULL;
}
#endif
if(m_d3dFont)
{
unsigned long uBe = m_d3dFont->Release();
m_d3dFont = NULL;
}
if(m_d3dSprMgr)
{
unsigned long uCausing = m_d3dSprMgr->Release();
m_d3dSprMgr = NULL;
}
//////////////////////////////
// release the d3d object and device
if (m_pd3dDevice)
{
m_pd3dDevice->EvictManagedResources();
unsigned long uToo = m_pd3dDevice->Release();
m_pd3dDevice = NULL;
}
if (m_pd3dD3D)
{
unsigned long uMany = m_pd3dD3D->Release();
m_pd3dD3D = NULL;
}
/////////////////////////////////////

// uProblems?
}

IDirect3DDevice9* CRenderer::GetDevice()
{
return m_pd3dDevice;
}

IDirect3D9* CRenderer::GetD3D()
{
return m_pd3dD3D;
}

IDirect3DVertexDeclaration9*& CRenderer::GetVertDecl()
{
return m_pd3dVertDecl;
}

IDirect3DVertexDeclaration9*& CRenderer::GetAnimDecl()
{
return m_pd3dAnimDecl;
}

IDirect3DVertexDeclaration9*& CRenderer::GetMovingDecl()
{
return m_pd3dMovingDecl;
}

ID3DXEffect* CRenderer::GetEffect(int nIndex)
{
return m_pd3dEffects[nIndex];
}

ID3DXEffect* CRenderer::GetParticleShaderEffect()
{
return m_pd3dEffects[SHADER_EFFECT_PARTICLE];
}

ID3DXSprite* CRenderer::GetSpriteManager()
{
return m_d3dSprMgr;
}
ID3DXFont* CRenderer::GetFontObject()
{
return m_d3dFont;
}

bool CRenderer::GetDebugMode()
{
return m_bDebugMode;
}

bool CRenderer::GetDebugCollision()
{
return m_bDebugCollision;
}

bool CRenderer::GetDebugNormals()
{
return m_bDebugNormals;
}

TLight* CRenderer::GetLights()
{
#if DEF_USE_MMLIGHTS
return m_tRenderLights;
#else
return m_tLights;
#endif
}

int CRenderer::GetNumLights()
{
#if DEF_USE_MMLIGHTS
return m_nFrameLightCount;
#else
return m_nLightCount;
#endif
}

D3DXVECTOR4 CRenderer::GetLightPosition(unsigned int nLightIndex)
{
if(nLightIndex < MAX_LIGHTS)
{
return m_tLights[nLightIndex].d3dPosition;
}
return D3DXVECTOR4(0,0,0,0);
}

D3DXVECTOR4 CRenderer::GetDiffuseColor(unsigned int nLightIndex)
{
if(nLightIndex < MAX_LIGHTS)
{
return m_tLights[nLightIndex].d3dDiffuse;
}
return D3DXVECTOR4(0,0,0,0); // black if no value
}

D3DXVECTOR4 CRenderer::GetSpecularColor(unsigned int nLightIndex)
{
if(nLightIndex < MAX_LIGHTS)
{
return m_tLights[nLightIndex].d3dSpecular;
}
return D3DXVECTOR4(0,0,0,0); // black if no value
}

float CRenderer::GetLightRange(unsigned int nLightIndex)
{
if(nLightIndex < MAX_LIGHTS)
{
return m_tLights[nLightIndex].d3dPosition.w;
}
return 0.0f; // no range if the light isn't there
}

TLight* CRenderer::GetLoadLight()
{
return m_tLoadLight;
}
// for level attribs
D3DXCOLOR CRenderer::GetLevelAmbient()
{
return m_tLevelAttributes.d3dAmbientLightColor;
}

float CRenderer::GetLevelLightMapRatio()
{
return m_tLevelAttributes.fLevelLightMapRatio;
}

#if _DEBUG
ID3DXLine* CRenderer::GetLineObject()
{
return m_d3dLine;
}
#endif

CCamera* CRenderer::GetCamera()
{
return &m_cCamera;
}

D3DXMATRIX CRenderer::GetOrthoMatrix()
{
return m_d3dOrthoMatrix;
}

void CRenderer::SetDebugMode(bool bMode)
{
m_bDebugMode = bMode;
}

void CRenderer::SetDebugNormals(bool bSet)
{
m_bDebugNormals = bSet;
}

void CRenderer::SetDebugCollision(bool bSet)
{
m_bDebugCollision = bSet;
}

bool CRenderer::SetLightPosition(unsigned int nLightIndex,D3DXVECTOR4 d3dPos)
{
if(nLightIndex < MAX_LIGHTS)
{
m_tLights[nLightIndex].d3dPosition = d3dPos;
return true;
}
return false;
}

bool CRenderer::SetLightDiffuse(unsigned int nLightIndex,D3DXVECTOR4 d3dDiffuse)
{
if(nLightIndex < MAX_LIGHTS)
{
m_tLights[nLightIndex].d3dDiffuse = d3dDiffuse;
return true;
}
return false;
}

bool CRenderer::SetLightSpecular(unsigned int nLightIndex,D3DXVECTOR4 d3dSpec)
{
if(nLightIndex < MAX_LIGHTS)
{
m_tLights[nLightIndex].d3dSpecular = d3dSpec;
return true;
}
return false;
}
bool CRenderer::SetLightRange(unsigned int nLightIndex, float fRange)
{
if(nLightIndex < MAX_LIGHTS)
{
m_tLights[nLightIndex].d3dPosition.w = fRange;
return true;
}
return false;
}

// for level attribs
void CRenderer::SetLevelAmbient(D3DXCOLOR d3dAmbient)
{
m_tLevelAttributes.d3dAmbientLightColor = d3dAmbient;
}

void CRenderer::SetLevelLightMapRatio(float fRatio)
{
m_tLevelAttributes.fLevelLightMapRatio = fRatio;
}

void CRenderer::SetParticleShaderEffect(ID3DXEffect* pEffect)
{
m_pd3dEffects[SHADER_EFFECT_PARTICLE] = pEffect;
}

void CRenderer::BuildRenderSets(CAbstractState* pState)
{
////////////////////////////////////////////////////////////////////////////////////////
// this is where we will call the Object Manager's GetRenderables() function
// and sort the returned list according to their rendersets.
// They will already be Z-Sorted, so once I decide which contexts need to draw first
// we can just sort them by context and then draw them all in order, except for the
// transparent objects will need to be reversed in render order. The objMan will give
// me everything sorted front to back for faster fill rate, but transparents need to
// render back to front for proper see through. That reverse will happen here.
vector<CGameObject*> cObjectList = pState->GetObjectManager()->GetRenderSet(m_cCamera.GetViewFrustum());

for(int nSet = 0; nSet < OBJ_TOTAL;++nSet)
{
m_RenderSets[nSet].ClearList();
}

if(cObjectList.empty())
{
return; // not sure if this is needed
}

////////////////////////////////////////////////////////////
for(unsigned int uObj = 0; uObj < cObjectList.size();++uObj)
{
int nObjType = cObjectList[uObj]->GetType();
int nID = cObjectList[uObj]->GetId();
m_RenderSets[nObjType].AddObject(cObjectList[uObj]);
}
/////////////////////////////////////////////////////////////////////////////////////////
}
void CRenderer::RenderProcess(CAbstractState* pState)
{
/////////////////////
// camera pointer
CCamera* cCamera = CRenderer::GetInstance()->GetCamera();
/////////////////////

cCamera->Update(CGame::GetInstance()->GetDeltaTime());

///////////////////////////////////////////////////////
// here we will build the rendersets
BuildRenderSets(pState);
///////////////////////////////////////////////////////
#if DEF_USE_MMLIGHTS

m_nFrameLightCount = FillRenderLightsList();

#endif

////////////////////////////////////////////////////////////////////////////////////
// here is where we will loop through the render sets and call the render functions
for(unsigned int uSet = 0; uSet < OBJ_TOTAL;++uSet)
{
if(uSet == OBJ_DECORATIVE_ALPHA || uSet == OBJ_DECORATIVE_FOREGROUND_ALPHA || uSet == OBJ_TEST_LIGHT || uSet == OBJ_SCHLEP_SHADOW_BLOB || uSet == OBJ_BUG_GLOW
|| uSet == OBJ_LOAD_BOX /*|| uSet == OBJ_LOAD_SCREEN*/ || (uSet >= OBJ_BUG_POPUP && uSet <= OBJ_BAY_POPUP))
{
continue;
}
else if(uSet == OBJ_SCHLEP)
{
m_RenderSets[uSet].Render();
}
else
{
m_RenderSets[uSet].Render();
}
}

//Render BG Effects
CParticleManager::GetInstance()->RenderBG();

for(int nTrans = 0; nTrans < OBJ_STATIC;++nTrans)
{
if(nTrans == OBJ_BUG_GLOW || nTrans == OBJ_SCHLEP_SHADOW_BLOB)
{
// set to not render Z-Depth
m_pd3dDevice->SetRenderState(D3DRS_ZWRITEENABLE,false);
m_RenderSets[nTrans].RenderTransparents();
m_pd3dDevice->SetRenderState(D3DRS_ZWRITEENABLE,true);
}
// Particles and other transparents aren't being sorted properly because
// all the decorative objects are being rendered at once then stuff in between them is not showing up
else if(nTrans == OBJ_DECORATIVE_ALPHA || nTrans == OBJ_LOAD_BOX || //nTrans == OBJ_LOAD_SCREEN ||
(nTrans >= OBJ_BUG_POPUP && nTrans <= OBJ_BAY_POPUP))
{
m_RenderSets[nTrans].RenderTransparents();
}
// skip foreground transparents
else if(nTrans == OBJ_DECORATIVE_FOREGROUND_ALPHA)
{
continue;
}
}
//render any particles
CParticleManager::GetInstance()->Render();
// render all forground pieces
m_RenderSets[OBJ_DECORATIVE_FOREGROUND_ALPHA].RenderTransparents();
/////////////////////////////////////////////////////////////////////////////////////

#if _DEBUG
if(m_bDebugMode)
{
///////////////////////////////
// DRAW FPS
char chFPS[16];
sprintf_s(chFPS,16,"FPS: %d ",CGame::GetInstance()->GetFPS());
AddDebugText(chFPS);
//////////////////////////////////////

//draw the timer in the HUD - MAKE SURE ITS DRAWN LAST!
char chText[24];
int nMinutes = (int)(CGame::GetInstance()->GetLevelTime()/60);
int nSeconds = ((int)CGame::GetInstance()->GetLevelTime())%60;
sprintf_s(chText,24, "TIME:%.2d:%.2d",nMinutes,nSeconds); // this is where the timer will actually count
AddDebugText(chText);

// Draw the bay timer if there is one
if(m_fBayTimeRemaining > 0)
{
m_fBayTimeRemaining -= CGame::GetInstance()->GetDeltaTime();
char chBayTimer[16];
sprintf_s(chBayTimer,16,"BAY: %.1f",m_fBayTimeRemaining);
AddDebugText(chBayTimer);
}

D3DXMATRIX d3dCamMat = *m_cCamera.GetCameraMatrix();
char szCamPos[48];
char szCamForward[48];
sprintf_s(szCamPos, 48, "CAMPOS:(%.4f, %.4f, %.4f)", d3dCamMat._41, d3dCamMat._42, d3dCamMat._43);
sprintf_s(szCamForward, 48, "ZAXIS:(%.4f, %.4f, %.4f)", d3dCamMat._31, d3dCamMat._32, d3dCamMat._33);

AddDebugText(szCamPos);
AddDebugText(szCamForward);
//////////////////////////////////////
PrintDebug();
}
#endif

//Render FG Effects
CParticleManager::GetInstance()->RenderFG();

if( !(CInputManager::GetInstance()->IsSpaceDown()) )
{
DrawOrthoObjects(pState);
}

CParticleManager::GetInstance()->RenderOrtho();

////////////////////////////
m_d3dSprMgr->Begin(D3DXSPRITE_ALPHABLEND | D3DXSPRITE_SORT_DEPTH_BACKTOFRONT);

DrawMenuTextures();
pState->Print();

m_d3dSprMgr->End();
////////////////////////////

int nState = CGame::GetInstance()->GetStateMachinePointer()->GetCurrentState()->GetStateID();
if(CGame::GetInstance()->IsGamePlayState() || (nState == GSTATE_LOSE_STATE && !CLoseState::GetInstance()->IsDeathEvent()) ||
(nState == GSTATE_PAUSE_STATE) || (nState == GSTATE_WIN_STATE))
{
if( !(CInputManager::GetInstance()->IsSpaceDown()) )
{
DrawHUD();
}
}
}

void CRenderer::DrawHUD()
{
// here we will draw the HUD elements
D3DXMATRIX d3dMat;
D3DXMatrixIdentity(&d3dMat);

// set the transform to identity (clears the matrix)
m_d3dSprMgr->SetTransform(&d3dMat);

// tell the sprite manager that drawing is about to start
m_d3dSprMgr->Begin(D3DXSPRITE_ALPHABLEND | D3DXSPRITE_SORT_DEPTH_BACKTOFRONT);

if(CGame::GetInstance()->IsGamePlayState())
{
CSubtitleManager::GetInstance()->Render();

///////////////////////////////////////
// Turn on the end of level light
if(CGameplayState::GetInstance()->GetBugsSaved() >= CGameplayState::GetInstance()->GetBugsSavedNeeded())
{
// put this end of level light on top of the HUD background at the lights position
m_d3dSprMgr->Draw(CTextureManager::GetInstance()->GetHUDEndLightTexture(),0,0,&D3DXVECTOR3(166,91,0),
D3DCOLOR_ARGB(255,255,255,255));
}
///////////////////////////////////////

char* szString = "Hello World!";
/////////////////////
//draw the timer in the HUD - MAKE SURE ITS DRAWN LAST!
char chText[24];
int nMinutes = (int)(CGameplayState::GetInstance()->GetLevelTime()/60);
int nSeconds = ((int)CGameplayState::GetInstance()->GetLevelTime())%60;
sprintf_s(chText,24, "%.2d:%.2d",nMinutes,nSeconds); // this is where the timer will actually count
RECT rTimer = {TIMER_POS_X,TIMER_POS_Y,TIMER_POS_X+200,TIMER_POS_Y+200};

char cHudStrings[3][10];

int nNumBugs = CGameplayState::GetInstance()->GetBatterBeesPointers()->size();
int nNumSaved = CGameplayState::GetInstance()->GetBugsSaved();
int nNumKilled = CGameplayState::GetInstance()->GetBugsKilled();
sprintf_s(cHudStrings[0], 10,"%d",
(nNumBugs - (nNumKilled+nNumSaved)));
//AddStringToPrint(D2D_FONT_MENU, m_cHudStrings[0],50,30, 0.5f, 0.5f, D3DCOLOR_XRGB(2,149,255));

sprintf_s(cHudStrings[1], 10,"%d",
nNumKilled);
//AddStringToPrint(D2D_FONT_MENU, m_cHudStrings[0],70,30, 0.5f, 0.5f, D3DCOLOR_XRGB(2,149,255));

sprintf_s(cHudStrings[2], 10,"%d",
nNumSaved);
//AddStringToPrint(D2D_FONT_MENU, m_cHudStrings[0],50,30, 0.5f, 0.5f, D3DCOLOR_XRGB(2,149,255));

if(CGameplayState::GetInstance()->GetFinishedPan() && CGameplayState::GetInstance()->GetRenderHud())
{
CFontManager::GetInstance()->Print(D2D_FONT_HUD,chText, TIMER_POS_X,TIMER_POS_Y,
1.35f, 1.35f,D3DCOLOR_XRGB(255,255,255));
CFontManager::GetInstance()->Print(D2D_FONT_MENU,cHudStrings[0],155,65,0.5f,0.5f,D3DCOLOR_XRGB(2,149,255));
CFontManager::GetInstance()->Print(D2D_FONT_MENU,cHudStrings[1],250,65,0.5f,0.5f,D3DCOLOR_XRGB(2,149,255));
CFontManager::GetInstance()->Print(D2D_FONT_MENU,cHudStrings[2],345,65,0.5f,0.5f,D3DCOLOR_XRGB(2,149,255));
}
if(CGameplayState::GetInstance()->ShowLevelName())
{
char szLevBuffer[256];
std::string Catcher;
std::string Sender;
LookUpLevelText( CGame::GetInstance()->GetLevelToLoad(), Sender);

sprintf_s(szLevBuffer,256, "Puzzle #%i - ", CGame::GetInstance()->GetLevelToLoad() + 1);
Catcher = szLevBuffer;

Catcher += Sender;
memset(szLevBuffer, 0, sizeof(szLevBuffer));
strcpy_s(szLevBuffer, 256, Catcher.c_str());

CFontManager::GetInstance()->Print(D2D_FONT_MENU,szLevBuffer, LEVEL_TEXT_POSX,LEVEL_TEXT_POSY,
0.75f, 0.75f,D3DCOLOR_XRGB(45,200,80));
}
if(!CGameplayState::GetInstance()->GetFinishedPan())
{
CFontManager::GetInstance()->Print(D2D_FONT_MENU,"Press \"Esc\" or \"P\" to Skip",
650,715,0.5f,0.5f,D3DCOLOR_XRGB(2,149,255));
}
}
m_d3dSprMgr->End();
////////////////////////
}

void CRenderer::ResetHUD()
{
m_fBayTimeRemaining = 0.0f;
m_nEOLLockCount = 0;
}

void CRenderer::IncrGamma(void)
{
m_fGamma += 0.05f;

if(m_fGamma > 1.0f)
{
m_fGamma = 1.0f;
}

UpdateGamma();
}

void CRenderer::DecrGamma(void)
{
m_fGamma -= 0.05f;

if(m_fGamma < -.90f)
{
m_fGamma = -.90f;
}

UpdateGamma();
}

void CRenderer::UpdateGamma()
{
D3DGAMMARAMP gammaRamp;
m_pd3dDevice->GetGammaRamp(0, &gammaRamp);

for(unsigned int i = 0; i < 256; i++)
{
gammaRamp.red[i] = unsigned short(min(255, i * (m_fGamma + 1.0f))) << 8;
gammaRamp.green[i] = unsigned short(min(255, i * (m_fGamma + 1.0f))) << 8;
gammaRamp.blue[i] = unsigned short(min(255, i * (m_fGamma + 1.0f))) << 8;
}

m_pd3dDevice->SetGammaRamp(0, D3DSGR_CALIBRATE, &gammaRamp);
}

float CRenderer::GetGamma(void)
{
return m_fGamma;
}
void CRenderer::SetGamma(float fGamma)
{
m_fGamma = fGamma;
UpdateGamma();
}
void CRenderer::HandleEvent(TEvent* pEvent)
{
switch(pEvent->m_nEventID)
{
case EV_GINPUT_PAUSE:
{
}
break;
case EV_ENVINT_BAY_LOCK:
{
// here we will increment our counter to check against for the
// end of level light
m_nEOLLockCount++;
m_fBayTimeRemaining = 0;
}
break;
case EV_DEATH_RESET_ALL:
{
// here we will reset the end of level bug counter to 0
m_nEOLLockCount = 0;
}
break;
case EV_ENVINT_BAY_ON:
{
if(CGame::GetInstance()->IsGamePlayState())
{
int* pnBayID = (int*)(pEvent->m_pData);
CGameObject* pcBay = CGameplayState::GetInstance()->GetObjectManager()->GetObjectPointer(pnBayID[0]);
m_fBayTimeRemaining = pcBay->GetTimerMax();
}

}
break;
case EV_ENVINT_BAY_OFF:
{
m_fBayTimeRemaining = 0;
}
break;
case EV_DISPLAY_TOGGLE:
{
ToggleFullScreenDisplay();
}
break;
};
}
void CRenderer::AddLight(TLight tLight)
{
#if DEF_USE_MMLIGHTS
if(CGame::GetInstance()->IsLoseState())
{
m_tDeathLights.push(tLight);

}
else
{
m_tMasterLightList.push(tLight);
}

#else

if(m_nLightCount < MAX_LIGHTS)
{
m_tLights[m_nLightCount] = tLight;
m_nLightCount++;
}

#endif
}

void CRenderer::AddLight(D3DXVECTOR4 d3dPos,D3DXVECTOR4 d3dDiffuse,D3DXVECTOR4 d3dSpec,float fRange)
{

// new light
TLight tNewLight;
tNewLight.d3dPosition = d3dPos;
tNewLight.d3dDiffuse = d3dDiffuse;
tNewLight.d3dSpecular = d3dSpec;
tNewLight.d3dPosition.w = fRange;
//tNewLight.fRange = D3DXVECTOR4(fRange,0.0f,0.0f,0.0f);

#if DEF_USE_MMLIGHTS
if(CGame::GetInstance()->IsLoseState())
{
m_tDeathLights.push(tNewLight);

}
else
{
m_tMasterLightList.push(tNewLight);
}
#else

if(m_nLightCount < MAX_LIGHTS)
{
m_tLights[m_nLightCount] = tNewLight;
m_nLightCount++;
}

#endif
}

void CRenderer::SetLoadLight(D3DXVECTOR4 d3dPos,D3DXVECTOR4 d3dDiffuse,D3DXVECTOR4 d3dSpec,float fRange)
{
TLight tNewLight;
tNewLight.d3dPosition = d3dPos;
tNewLight.d3dDiffuse = d3dDiffuse;
tNewLight.d3dSpecular = d3dSpec;
tNewLight.d3dPosition.w = fRange;

m_tLoadLight[0] = tNewLight;
tNewLight.d3dPosition.x += 2.0f;
m_tLoadLight[1] = tNewLight;
}

void CRenderer::ClearLights()
{
memset(m_tLights,0,sizeof(TLight)*m_nLightCount);
m_nLightCount = 0;

#if DEF_USE_MMLIGHTS
memset(m_tRenderLights,0, sizeof(TLight) * MAX_LIGHTS);
m_tMasterLightList.clear();
#endif
}

void CRenderer::AddDebugText(char* szString)
{
std::string szNewString = szString;
m_szDebugStrings.push(szNewString);
}

void CRenderer::PrintDebug()
{
// hardcoded spot for the debug stuff
RECT rDebugRect = {768,75,1000,500};
std::string szFinalString = "DEBUGGING:\n\n";
for(unsigned int nString = 0; nString < m_szDebugStrings.Getsize();++nString)
{
szFinalString += (m_szDebugStrings[nString] + "\n");
}
m_d3dFont->DrawTextA(0,szFinalString.c_str(),-1,&rDebugRect,0,D3DCOLOR_XRGB(255,255,80));

m_szDebugStrings.clear();
}

void CRenderer::DrawMenuTextures()
{
// loop through the state's list of Textures
CAbstractState* iCurState = CStateMachine::GetInstance()->GetCurrentState();

CVector& vtTextures = iCurState->GetMenuTextures();
for(unsigned int nText = 0; nText < vtTextures.Getsize(); ++nText)
{
m_d3dSprMgr->Draw(CTextureManager::GetInstance()->GetTexture(vtTextures[nText].nTextureID),
vtTextures[nText].rSrcRect,vtTextures[nText].d3dCenter,vtTextures[nText].d3dPosition,vtTextures[nText].d3dColor);
}
}

void CRenderer::DrawOrthoObjects(CAbstractState* pState)
{
// Draw Any Orthographic 3D objects... including HUD and some menus
ID3DXEffect* d3dEffect = NULL;
CRenderContext* pContext = NULL;
CModel* cMesh = NULL;
CMovingModel* cMovModel = NULL;
CAnimModel* cAnim = NULL;
int nNumVerts = 0;
int nNumTris = 0;

// Should render these back to front since most ortho objects have alpha
int nOrthosVecSize = (int)pState->GetOrthoObjects().Getsize();
for(int nOrthoLoop = 0; nOrthoLoop < nOrthosVecSize; ++nOrthoLoop)
{
CGameObject* pObject = pState->GetOrthoObjects()[nOrthoLoop];
if(pObject->TestFlag(AIF_ANY_DONTRENDER))
{
continue;
}
// leaving these as they are that way I don't have to cast the object type to get the right buffers
IDirect3DVertexBuffer9* d3dVertBuffer = *(pState->GetOrthoObjects()[nOrthoLoop]->GetMeshPointer()->GetVertexBuffer());
IDirect3DIndexBuffer9* d3dIndexBuffer = *(pState->GetOrthoObjects()[nOrthoLoop]->GetMeshPointer()->GetIndexBuffer());

D3DXMATRIX d3dObjMatrix = pObject->GetWorldMat();
IDirect3DTexture9* d3dTexture = CTextureManager::GetInstance()->GetTexture(pObject->GetMeshTextID());
IDirect3DTexture9* d3dSwapText = CTextureManager::GetInstance()->GetTexture(pObject->GetTextSwapID());

int nObjType = pObject->GetType();
int nID = pObject->GetId();

// Render the ortho stuff from this state
// since they are all animated objects we will use the Animated Effect file
if(nObjType > OBJ_ANIMATED)
{
d3dEffect = GetEffect(SHADER_EFFECT_SKINNING); // because its animated
pContext = m_RenderSets[nObjType].GetRenderContext();
d3dEffect->SetTechnique(pContext->GetTechnique()); // Should be "Basic"

cAnim = (CAnimModel*)pObject->GetMeshPointer();

nNumVerts = cAnim->GetAnimUniqueVerts()->Getsize();
nNumTris = cAnim->GetTris()->Getsize();

m_pd3dDevice->SetVertexDeclaration(m_pd3dAnimDecl);
m_pd3dDevice->SetStreamSource(0, d3dVertBuffer, 0, sizeof(TAnimVertex));
m_pd3dDevice->SetIndices(d3dIndexBuffer);
}
else
{
d3dEffect = GetEffect(SHADER_EFFECT_BASIC); // because its animated
pContext = m_RenderSets[nObjType].GetRenderContext();
d3dEffect->SetTechnique(pContext->GetTechnique());

cMesh = (CModel*)pObject->GetMeshPointer();

if(cMesh->isMoving())
{
cMovModel = (CMovingModel*)pObject->GetMeshPointer();
nNumVerts = cMovModel->GetUniqueVerts()->Getsize();
nNumTris = cMovModel->GetTris()->Getsize();

m_pd3dDevice->SetVertexDeclaration(m_pd3dMovingDecl);
m_pd3dDevice->SetStreamSource(0, d3dVertBuffer, 0, sizeof(TVertex));
m_pd3dDevice->SetIndices(d3dIndexBuffer);
}
else
{
nNumVerts = cMesh->GetUniqueVerts()->Getsize();
nNumTris = cMesh->GetTris()->Getsize();

m_pd3dDevice->SetVertexDeclaration(m_pd3dVertDecl);
m_pd3dDevice->SetStreamSource(0, d3dVertBuffer, 0, sizeof(TStaticVertex));
m_pd3dDevice->SetIndices(d3dIndexBuffer);
}
}

if(d3dEffect)
{
UINT uPasses = 0;
d3dEffect->Begin(&uPasses, 0);
for(UINT uPass=0; uPass<uPasses; uPass++)
{
d3dEffect->BeginPass(uPass);

// set the shader constants
d3dEffect->SetFloat("g_fUScroll",pObject->GetUScrollAmt()*CGame::GetInstance()->GetCurrTime());
d3dEffect->SetFloat("g_fVScroll",pObject->GetVScrollAmt()*CGame::GetInstance()->GetCurrTime());

if(pObject->IsPowered() && d3dSwapText)
{
d3dEffect->SetTexture("g_ObjTexture",d3dSwapText);
}
else
{
d3dEffect->SetTexture("g_ObjTexture",d3dTexture);
}
if(nObjType == OBJ_NOTIFICATION || nObjType == OBJ_ARROW)
{
d3dEffect->SetTexture("g_LightMap", CTextureManager::GetInstance()->GetTexture(pObject->GetLightMapID()));
d3dEffect->SetFloat("g_fUScroll",pObject->GetUScrollAmt());
d3dEffect->SetFloat("g_fVScroll",pObject->GetVScrollAmt());
}

d3dEffect->SetBool("g_bLightMap",false);
d3dEffect->SetMatrix("g_mWorld",&d3dObjMatrix);

d3dEffect->SetMatrix("g_mWVP", &(d3dObjMatrix*m_d3dOrthoMatrix));

if(nObjType == OBJ_DEATH_FADE_CARD)
{
if(CGame::GetInstance()->IsLoseState())
{
d3dEffect->SetBool("g_bFadeIn",false);
d3dEffect->SetBool("g_bFadeOut",true);
}
else if(CGame::GetInstance()->IsGamePlayState())
{
d3dEffect->SetBool("g_bFadeIn",true);
d3dEffect->SetBool("g_bFadeOut",false);
}
d3dEffect->SetFloat("g_fUScroll",pObject->GetUScrollAmt());
d3dEffect->SetFloat("g_fVScroll",pObject->GetVScrollAmt());
}

if(pObject->GetType() > OBJ_ANIMATED)
{
CInterpolator* pInterp = CAnimationManager::GetInstance()->GetInterpolator(pObject->GetId(), pObject->GetType());
d3dEffect->SetMatrixArray("Bones",
&pInterp->GetCurFrame()[0],
pInterp->GetCurFrame().Getsize());
}
d3dEffect->CommitChanges();

// draw the triangle
m_pd3dDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST,0,0,nNumVerts,0,nNumTris);

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

void CRenderer::ToggleFullScreenDisplay()
{
// toggle the global bool
CGame::GetInstance()->SetWindowed(!(CGame::GetInstance()->IsWindowed()));

// set up the present parameters
//////////////////////////////////////////////
// declare the present parameters for the game
//////////////////////////////////////////////
if(CGame::GetInstance()->IsWindowed())
{
m_d3dPresentParams.Windowed = true;
m_d3dPresentParams.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
m_d3dPresentParams.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT;
}
else
{
m_d3dPresentParams.Windowed = false;
m_d3dPresentParams.PresentationInterval = D3DPRESENT_INTERVAL_ONE;
m_d3dPresentParams.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT;
}

ReleaseAndResetResourceHelper();

// Setup window style flags
DWORD dwWindowStyleFlags = 0;

if (CGame::GetInstance()->IsWindowed())
{
dwWindowStyleFlags |= WS_OVERLAPPEDWINDOW;
//ShowCursor(TRUE); // show the mouse cursor
}
else
{
dwWindowStyleFlags |= WS_POPUP;
//ShowCursor(FALSE); // hide the mouse cursor
}

SetWindowLong(m_pHwnd, GWL_STYLE, dwWindowStyleFlags);

// Set the window to the middle of the screen.
if (CGame::GetInstance()->IsWindowed())
{
// Setup the desired client area size
//RECT rWindow;
//rWindow.left = 0;
//rWindow.top = 0;
//rWindow.right = WINDOW_WIDTH;
//rWindow.bottom = WINDOW_HEIGHT;

// Get the dimensions of a window that will have a client rect that
// will really be the resolution we're looking for.
//AdjustWindowRectEx(&rWindow,
// dwWindowStyleFlags,
// FALSE,
// WS_EX_APPWINDOW);

// Calculate the width/height of that window's dimensions
//int windowWidth = rWindow.right - rWindow.left;
//int windowHeight = rWindow.bottom - rWindow.top;

SetWindowPos(m_pHwnd, HWND_NOTOPMOST, 0, 0, WINDOW_WIDTH, WINDOW_HEIGHT, SWP_FRAMECHANGED | SWP_SHOWWINDOW | SWP_NOMOVE | SWP_NOSIZE);
}
else
{
// Let windows know the window has changed.
SetWindowPos(m_pHwnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_FRAMECHANGED | SWP_SHOWWINDOW | SWP_NOMOVE | SWP_NOSIZE);

}
m_pd3dDevice->SetRenderState(D3DRS_CULLMODE,D3DCULL_CW);
}

void CRenderer::ReleaseAndResetResourceHelper()
{
// unload all DEFAULT_POOL objects
m_d3dFont->OnLostDevice();
m_d3dSprMgr->OnLostDevice();
#if _DEBUG
m_d3dLine->OnLostDevice();
#endif
for(unsigned int nEff = 0; nEff < SHADER_EFFECT_TOTAL;++nEff)
{
m_pd3dEffects[nEff]->OnLostDevice();
}

// reset the device
HRESULT hr = m_pd3dDevice->Reset(&m_d3dPresentParams);

for(unsigned int nEff = 0; nEff < SHADER_EFFECT_TOTAL;++nEff)
{
m_pd3dEffects[nEff]->OnResetDevice();
}
#if _DEBUG
m_d3dLine->OnResetDevice();
#endif
m_d3dSprMgr->OnResetDevice();
m_d3dFont->OnResetDevice();
}

Here is a couple example shaders written in HLSL that I wrote for Schlep’s Labyrinth. You can find a more in depth explanation here.

basic.fx:

///////////////////////////////////////////////////////////////////////
// File: basic.fx
//
// This Shader houses all the techniques for basic rendered objects,
// including LightMapped object and a few special cases. There is no
// actual lighting calculations done in this file, nor is there animations
// being done.
//
// Author: Aaron Schie
// Date: 5/12/2011
// Last Mod: 8/22/2011
///////////////////////////////////////////////////////////////////////

//////////////////////////////////////////
// SHADER CONSTANT VARIABLES
//////////////////////////////////////////
// globals
float4x4 g_mWVP; // model-View-projection matrix
bool g_bLightMap; // if it has a lightmap
bool g_bHasIncan; // if it has an incandescense map
bool g_bFadeIn;
bool g_bFadeOut;
float g_fUScroll;
float g_fVScroll;
float g_fLevelValue; // level lightmap ratio for lightening the lightmaps
texture g_ObjTexture; // normal texture
texture g_LightMap; // Lightmap texture
texture g_IncandText; // incandescense texture

////////////////////////////////////////////
// Structures
////////////////////////////////////////////
// Define a vertex shader output structure;
struct OutputVS
{
float4 posH:POSITION0;
float2 texcoord:TEXCOORD0;
};

struct OutputLightMapVS
{
float4 posH:POSITION0;
float2 texCoord:TEXCOORD0;
float2 lightMapCoord:TEXCOORD1;
};
////////////////////////////////////////////

////////////////////////////////////////////
// TEXTURE SAMPLERS
////////////////////////////////////////////
// name of the sampler
sampler texturesamp
{
// texture this sampler uses
Texture = < g_ObjTexture >;

// texture filtering
MinFilter = LINEAR;
MagFilter = LINEAR;
MipFilter = POINT;

// texture address modes (available options are WRAP, MIRROR, BORDER, and CLAMP)
AddressU = WRAP;
AddressV = WRAP;
};

sampler lightMapSamp
{
// texture this sampler uses
Texture = < g_LightMap >;

// texture filtering
MinFilter = LINEAR;
MagFilter = LINEAR;
MipFilter = POINT;

// texture address modes (available options are WRAP, MIRROR, BORDER, and CLAMP)
AddressU = CLAMP;
AddressV = CLAMP;
};

sampler incandescenseSamp
{
// texture this sampler uses
Texture = < g_IncandText >;

// texture filtering
MinFilter = POINT;
MagFilter = POINT;
MipFilter = NONE;

// texture address modes (available options are WRAP, MIRROR, BORDER, and CLAMP)
AddressU = CLAMP;
AddressV = CLAMP;
};
///////////////////////////////////////////

///////////////////////////////////////////
// Vertex shaders
///////////////////////////////////////////

// Normal Transform of vertices
OutputVS TransformVS(float3 position:POSITION0, float2 texcoord:TEXCOORD0)
{
// output structure
OutputVS outVS;

outVS.posH = mul(float4(position, 1.0f), g_mWVP);
outVS.texcoord = texcoord;

return outVS;
}

// Lightmapped object transform (has a second UV set)
OutputLightMapVS TransformLightMapVS(float3 position:POSITION0, float2 texcoord:TEXCOORD0, float2 lightMapCoord:TEXCOORD1)
{
// output structure
OutputLightMapVS outVS;

outVS.posH = mul(float4(position, 1.0f), g_mWVP);
outVS.texCoord = texcoord;
outVS.lightMapCoord = lightMapCoord;

return outVS;
}

///////////////////////////////////////////////
// Pixel Shader
///////////////////////////////////////////////

// Normal pixel shader
float4 TransformPS(float4 c:COLOR0,float2 uv0:TEXCOORD0):COLOR
{
// determine the pixel to sampler from
float4 texCol;
float4 incCol;

if(g_bHasIncan)
{
float4 tempCol = tex2D(texturesamp,uv0);
incCol = tex2D(incandescenseSamp,uv0);
texCol.r = tempCol.r < 0.5f ? (2*tempCol.r*incCol.r) /1.0f : 1.0f - (2.0f*(1.0f-tempCol.r)*(1.0f-incCol.r)/1.0f);
texCol.g = tempCol.g < 0.5f ? (2*tempCol.g*incCol.g) /1.0f : 1.0f - (2.0f*(1.0f-tempCol.g)*(1.0f-incCol.g)/1.0f);
texCol.b = tempCol.b < 0.5f ? (2*tempCol.b*incCol.b) /1.0f : 1.0f - (2.0f*(1.0f-tempCol.b)*(1.0f-incCol.b)/1.0f);
}
else
{
uv0.x += g_fUScroll;
uv0.y += g_fVScroll;
texCol = tex2D(texturesamp, uv0);
}

if(texCol.a <= 0.1f)
discard;

return texCol;
}

// To interp between two textures
float4 LerpPS(float4 c:COLOR0,float2 uv0:TEXCOORD0):COLOR
{
float4 texCol1 = tex2D(texturesamp, uv0);
float4 texCol2 = tex2D(lightMapSamp, uv0);

float4 texCol = lerp(texCol1, texCol2, g_fUScroll);
return texCol;
}

// to Fade In or Out
float4 FadeInOutPS(float4 c:COLOR0,float2 uv0:TEXCOORD0):COLOR
{
float4 texCol = tex2D(texturesamp, uv0);
float fAlpha = 0.0f;
if(g_bFadeIn)
{
fAlpha += g_fUScroll;
if(fAlpha > 1.0f)
fAlpha = 1.0f;
}
else if(g_bFadeOut)
{
fAlpha = texCol.a;
fAlpha -= g_fUScroll;
if(fAlpha < 0.0f)
{
fAlpha = 0.0f;
}
}
texCol.a = fAlpha;
return texCol;
}

// Special UV scroll fade effect
float4 DeathFadePS(float4 c:COLOR0,float2 uv0:TEXCOORD0):COLOR
{
if(g_bFadeIn)
{
// move to total V value
uv0.y -= g_fUScroll;
}
else if(g_bFadeOut)
{
// move from VScroll to 0
uv0.y -= g_fVScroll;
uv0.y += g_fUScroll;
}
return tex2D(texturesamp,uv0);
}

// Lightmap pixel Shader
float4 TransformLightMapPS(float4 c:COLOR0,float2 uv0:TEXCOORD0,float2 uv1:TEXCOORD1):COLOR
{
// determine the pixel to sampler from
float4 texCol;

// Scroll the UV's (will be 0 if no scrolling)
uv0.x += g_fUScroll;
uv0.y += g_fVScroll;

// normal texture lookup (first set of UVs)
texCol = tex2D(texturesamp, uv0);

// if the object has a lightmap applied
if(g_bLightMap)
{
// lightmap texture lookup on the second set of UVs
float4 lightCol = tex2D(lightMapSamp,uv1);

// how much of the lightmap texture is applied to the normal texture
lightCol.r = (1-((1-lightCol.r)*(1 - g_fLevelValue))); // to adjust how bright the lightmaps appear
lightCol.g = (1-((1-lightCol.g)*(1 - g_fLevelValue))); // on a per level basis to bring out the color and brightness
lightCol.b = (1-((1-lightCol.b)*(1 - g_fLevelValue))); // of the lightmaps

texCol *= (lightCol*1.25f); // lightmap is scaled a little to bring out the color without brightening the whole object
}

// if it needs an incandescense map applied
// this is used if the texture has a "light" in it, that would normally emit light. This "light" on the texture
// needs to ignore other lighting calculations, either lightmap or lighting
if(g_bHasIncan)
{
// look up incandescence texture
float4 incCol = tex2D(incandescenseSamp,uv0);

// if theres value in all three color channels of the incandescense, then we need to apply the incandescense to
// the texture so that lightmaps or lighting doesn't affect actual painted lights in the texture
if(incCol.r > 0.0f)
if(incCol.g > 0.0f)
if(incCol.b > 0.0f)
{
float4 fReturnCol = float4((((texCol.rgb+incCol.rgb)/2.0f)*1.5f),texCol.a);

if(fReturnCol.a <= 0.0f)
{
discard;
}

return fReturnCol;
}
}

if(texCol.a <= 0.0f)
{
discard;
}

return texCol;
}

///////////////////////////////////////////
// Techniques
///////////////////////////////////////////
technique Basic
{
pass P0
{
vertexShader = compile vs_2_0 TransformVS();
pixelShader = compile ps_2_0 TransformPS();
}
}

// For the Power Bay Timer
technique BayBar
{
pass P0
{
vertexShader = compile vs_2_0 TransformVS();
pixelShader = compile ps_2_0 LerpPS();
}
}

technique Transparent
{
pass P0
{
vertexShader = compile vs_2_0 TransformVS();
pixelShader = compile ps_2_0 TransformPS();

AlphaBlendEnable = true;
SrcBlend = SrcAlpha;
DestBlend = InvSrcAlpha;
BlendOp = Add;
}
}

technique LightMap
{
pass P0
{
vertexShader = compile vs_2_0 TransformLightMapVS();
pixelShader = compile ps_2_0 TransformLightMapPS();

AlphaBlendEnable = true;
SrcBlend = SrcAlpha;
DestBlend = InvSrcAlpha;
BlendOp = Add;
}
}

// For the Death State Transition Fade
technique DeathFade
{
pass p0
{
vertexShader = compile vs_2_0 TransformVS();
pixelShader = compile ps_2_0 DeathFadePS();

AlphaBlendEnable = true;
SrcBlend = SrcAlpha;
DestBlend = InvSrcAlpha;
BlendOp = Add;
}
}

// To Fade Glow's based on music beat
technique BeatFade
{
pass p0
{
vertexShader = compile vs_2_0 TransformVS();
pixelShader = compile ps_2_0 FadeInOutPS();

AlphaBlendEnable = true;
SrcBlend = SrcAlpha;
DestBlend = InvSrcAlpha;
BlendOp = Add;
}
}

basicLit.fx:

///////////////////////////////////////////////////////////////////////
// File: basicLit.fx
//
// This Shader houses all the techniques for lit rendered objects,
// including how to deal with incandescense maps and lighting.
// there are no animations being done in this file.
//
//
// Author: Aaron Schie
// Date: 5/12/2011
// Last Mod: 8/22/2011
///////////////////////////////////////////////////////////////////////

////////////////////////////////////
// SHADER CONSTANT VARIABLES
////////////////////////////////////
// globals
float4x4 g_mWorld; // used to move object into same world space as light
float4x4 g_mWVP;
float4x4 g_mVP;
float3 g_vLightPosition;
bool g_bHasIncan;
float g_fUScroll;
float g_fVScroll;
texture g_ObjTexture;
texture g_IncandText;
////////////////////////////////////

////////////////////////////////////
// STRUCTURES
////////////////////////////////////
// vertex shader output structure;
struct OutputLitDiffuseVS
{
float4 vPosition:POSITION0;
float2 vTexCoord:TEXCOORD0;
float4 vDiffuseOut:TEXCOORD1;
float3 vAmbientOut:TEXCOORD2;
float3 vAttenuation:TEXCOORD3;
};

// structure for the lights being passed in
// declared for max 14 lights as well
struct LightInput
{
float4 vPosition; // range is the W component
float4 vDiffuseLightColor;
float4 vSpecularLightColor;
} g_Lights[14];
////////////////////////////////////

////////////////////////////////////
// number of actual lights passed over
int g_nNumLights;
////////////////////////////////////

////////////////////////////////////
// Material colors
float4 g_vDiffuseMaterial; // the diffuse color of the material
float4 g_vAmbientMaterial; // the color of the ambient light
float4 g_vAmbientLightColor; // the diffuse color of the material
float4 g_vSpecMaterial; // the color of the diffuse light
////////////////////////////////////

////////////////////////////////////
// TEXTURE SAMPLERS
////////////////////////////////////
// name of the sampler
sampler2D texturesamp = sampler_state
{
// texture this sampler uses
Texture = < g_ObjTexture >;

// texture filtering
MinFilter = LINEAR;
MagFilter = LINEAR;
MipFilter = POINT;

// texture address modes (available options are WRAP, MIRROR, BORDER, and CLAMP)
AddressU = WRAP;
AddressV = WRAP;
};

sampler incandescenseSamp
{
// texture this sampler uses
Texture = < g_IncandText >;

// texture filtering
MinFilter = POINT;
MagFilter = POINT;
MipFilter = NONE;

// texture address modes (available options are WRAP, MIRROR, BORDER, and CLAMP)
AddressU = CLAMP;
AddressV = CLAMP;
};
////////////////////////////////////

////////////////////////////////////
// VERTEX SHADERS
////////////////////////////////////
// Normal Lit Transform (Basic Vertex Lighting)
OutputLitDiffuseVS TransformDiffuseVS(float3 _vPosition:POSITION0, float3 _vNormal:NORMAL0, float2 _vTexCoord:TEXCOORD0)
{
// output structure
OutputLitDiffuseVS outVS = (OutputLitDiffuseVS)0; // zero out the memory

// transform the vertex into world
outVS.vPosition = mul(float4(_vPosition, 1.0f), g_mWVP);

// get the world position of the vertex for lighting calculations
float4 vWorldPosition = mul(float4(_vPosition, 1.0f), g_mWorld);

// get the normal, not transformed, but oriented by the world
float4 vWorldNormal = mul(float4(_vNormal, 0.0f), g_mWorld);
// normalize the normal
vWorldNormal = normalize(vWorldNormal);

float3 vLightVector;
// loop through the lights passed in
for(int nLoop = 0; nLoop < g_nNumLights; ++nLoop)
{
// get the light vector (from the light's position to the vertex in world)
vLightVector = g_Lights[nLoop].vPosition.xyz - vWorldPosition.xyz;

// distance to the vertex from the light
float dist = abs(distance(g_Lights[nLoop].vPosition.xyz,vWorldPosition.xyz));

// if it is outside the range, go to the next light
if(dist > g_Lights[nLoop].vPosition.w)
{
continue;
}
// otherwise, normalize the lightvector, and calulate the amount of light hitting the vertex
vLightVector = normalize(vLightVector);
float fLightAmount = saturate(dot(vWorldNormal.xyz, vLightVector));

// add the light from this light to the total light received for this vertex
outVS.vDiffuseOut.rgb += (fLightAmount * (g_vDiffuseMaterial * g_Lights[nLoop].vDiffuseLightColor).rgb);

// set the alpha (intensity) to the alpha passed in (given by the artists)
outVS.vDiffuseOut.a = 1.0f;//g_Lights[nLoop].vDiffuseLightColor.a;
}
// Clamp the values, so that the maximum light amount given this vertex does not exceed a set amount
// and blow out/ wash out the object
outVS.vDiffuseOut.r = min(outVS.vDiffuseOut.r,1.25f);
outVS.vDiffuseOut.g = min(outVS.vDiffuseOut.g,1.25f);
outVS.vDiffuseOut.b = min(outVS.vDiffuseOut.b,1.25f);
// set the ambient color
outVS.vAmbientOut = g_vAmbientLightColor.rgb;// * g_vAmbientMaterial
// pass along the texture coordinates
outVS.vTexCoord = _vTexCoord;

// ambient intensity is the alpha of the ambient color passed in
float ambientIntensity = g_vAmbientLightColor.a;//* g_vAmbientMaterial.a

// calculate the final color
float3 finalColor = (outVS.vAmbientOut * ambientIntensity) + (outVS.vDiffuseOut.rgb);

// set the final diffuse color and pass the struct to the pixel shader
outVS.vDiffuseOut.rgb = finalColor;
return outVS;
}
////////////////////////////////////

////////////////////////////////////
// PIXEL SHADERS
////////////////////////////////////
// Normal Textured
float4 TransformTexturedPS(OutputLitDiffuseVS input):COLOR
{
// initialize the texture color for this pixel
float4 texCol = float4(1.0f,1.0f,1.0f,1.0f);

// if the texture needs to scroll it is changed here
input.vTexCoord.x += g_fUScroll;
input.vTexCoord.y += g_fVScroll;

// now do the lookup based on the passed in structures texture coordinates
texCol = tex2D(texturesamp, input.vTexCoord);

// a temporary final pixel color of the lit vertex multiplied by the texture color
float4 tempFinal = float4(input.vDiffuseOut.rgb,input.vDiffuseOut.a)*texCol;

// if it needs an incandescense map applied
// this is used if the texture has a "light" in it, that would normally emit light. This "light" on the texture
// needs to ignore other lighting calculations, either lightmap or lighting
if(g_bHasIncan)
{
// lookup of the incandescense map, based on the passed in structure's texture coordinates
float4 incCol = tex2D(incandescenseSamp,input.vTexCoord);

// check if all three channel of the incandescense map are above black
if(incCol.r > 0.0f)
if(incCol.g > 0.0f)
if(incCol.b > 0.0f)
{
// if they are, add the incandescense value to the texture and ignore the lighting for this pixel
// and return the color as such
return (tex2D(texturesamp,input.vTexCoord)+(incCol/2.0f));
}
}

// if it doesn't have an incandescense map then we return the lit textured pixel color
return tempFinal;
}
/////////////////////////////////////

/////////////////////////////////////
// TECHNIQUES
/////////////////////////////////////
technique Basic
{
pass P0
{
vertexShader = compile vs_2_0 TransformDiffuseVS();
pixelShader = compile ps_2_0 TransformTexturedPS();
}
}