/*
Demo Name: Game Project 8
Author: Allen Sherrod
Chapter: Chapter 9
*/
#include<stdio.h>
#include"D3DRenderer.h"
#include"structs.h"
inline unsigned long FtoDW(float val)
{
return *((unsigned long*)&val);
}
// Our custom FVF, which describes our custom vertex structure
#define D3DFVF_GUI (D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_TEX1)
bool CreateD3DRenderer(CRenderInterface **pObj)
{
if(!*pObj) *pObj = new CD3DRenderer;
else return false;
return true;
}
unsigned long CreateD3DFVF(int flags)
{
unsigned long fvf = 0;
if(flags == GUI_FVF) fvf = D3DFVF_GUI;
return fvf;
}
D3DMULTISAMPLE_TYPE GetD3DMultiSampleType(LPDIRECT3D9 d3d,
UGP_MS_TYPE ms, D3DDEVTYPE type, D3DFORMAT format, bool fullscreen)
{
D3DMULTISAMPLE_TYPE t = D3DMULTISAMPLE_NONE;
if(d3d)
{
switch(ms)
{
case UGP_MS_NONE:
t = D3DMULTISAMPLE_NONE;
break;
case UGP_MS_SAMPLES_2:
if(d3d->CheckDeviceMultiSampleType(D3DADAPTER_DEFAULT,
type, format, !fullscreen, D3DMULTISAMPLE_2_SAMPLES,
NULL) == D3D_OK) t = D3DMULTISAMPLE_2_SAMPLES;
break;
case UGP_MS_SAMPLES_4:
if(d3d->CheckDeviceMultiSampleType(D3DADAPTER_DEFAULT,
type, format, !fullscreen, D3DMULTISAMPLE_2_SAMPLES,
NULL) == D3D_OK) t = D3DMULTISAMPLE_4_SAMPLES;
break;
case UGP_MS_SAMPLES_8:
if(d3d->CheckDeviceMultiSampleType(D3DADAPTER_DEFAULT,
type, format, !fullscreen, D3DMULTISAMPLE_8_SAMPLES,
NULL) == D3D_OK) t = D3DMULTISAMPLE_8_SAMPLES;
break;
case UGP_MS_SAMPLES_16:
if(d3d->CheckDeviceMultiSampleType(D3DADAPTER_DEFAULT,
type, format, !fullscreen, D3DMULTISAMPLE_16_SAMPLES,
NULL) == D3D_OK) t = D3DMULTISAMPLE_16_SAMPLES;
break;
default:
break;
}
}
return t;
}
CD3DRenderer::CD3DRenderer()
{
m_Direct3D = NULL;
m_Device = NULL;
m_renderingScene = false;
m_numStaticBuffers = 0;
m_activeStaticBuffer = UGP_INVALID;
m_staticBufferList = NULL;
m_textureList = NULL;
m_numTextures = 0;
m_totalFonts = 0;
m_guiList = NULL;
m_totalGUIs = 0;
m_fonts = NULL;
}
CD3DRenderer::~CD3DRenderer()
{
Shutdown();
}
bool CD3DRenderer::Initialize(int w, int h, WinHWND mainWin,
bool fullScreen, UGP_MS_TYPE ms)
{
Shutdown();
m_mainHandle = mainWin;
if(!m_mainHandle) return false;
m_fullscreen = fullScreen;
D3DDISPLAYMODE mode;
D3DCAPS9 caps;
D3DPRESENT_PARAMETERS Params;
ZeroMemory(&Params, sizeof(Params));
m_Direct3D = Direct3DCreate9(D3D_SDK_VERSION);
if(!m_Direct3D) return false;
if(FAILED(m_Direct3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT,
&mode))) return false;
if(FAILED(m_Direct3D->GetDeviceCaps(D3DADAPTER_DEFAULT,
D3DDEVTYPE_HAL, &caps))) return false;
DWORD processing = 0;
if(caps.VertexProcessingCaps != 0)
processing = D3DCREATE_HARDWARE_VERTEXPROCESSING |
D3DCREATE_PUREDEVICE;
else
processing = D3DCREATE_SOFTWARE_VERTEXPROCESSING;
if(m_fullscreen)
{
Params.FullScreen_RefreshRateInHz = mode.RefreshRate;
Params.PresentationInterval = D3DPRESENT_INTERVAL_ONE;
}
else
Params.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
Params.Windowed = !m_fullscreen;
Params.BackBufferWidth = w;
Params.BackBufferHeight = h;
Params.hDeviceWindow = m_mainHandle;
Params.SwapEffect = D3DSWAPEFFECT_DISCARD;
Params.BackBufferFormat = mode.Format;
Params.BackBufferCount = 1;
Params.EnableAutoDepthStencil = TRUE;
Params.AutoDepthStencilFormat = D3DFMT_D16;
Params.MultiSampleType = GetD3DMultiSampleType(m_Direct3D, ms,
D3DDEVTYPE_HAL, mode.Format, m_fullscreen);
m_screenWidth = w;
m_screenHeight = h;
if(FAILED(m_Direct3D->CreateDevice(D3DADAPTER_DEFAULT,
D3DDEVTYPE_HAL, m_mainHandle, processing,
&Params, &m_Device))) return false;
if(m_Device == NULL) return false;
OneTimeInit();
return true;
}
void CD3DRenderer::OneTimeInit()
{
if(!m_Device) return;
m_Device->SetRenderState(D3DRS_LIGHTING, FALSE);
m_Device->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
SetTextureFilter(0, MAG_FILTER, ANISOTROPIC_TYPE);
SetTextureFilter(0, MIN_FILTER, ANISOTROPIC_TYPE);
SetTextureFilter(0, MIP_FILTER, ANISOTROPIC_TYPE);
CalculateProjMatrix(D3DX_PI / 4, 0.1f, 1000);
}
void CD3DRenderer::Shutdown()
{
for(int s = 0; s < m_numStaticBuffers; s++)
{
if(m_staticBufferList[s].vbPtr)
{
m_staticBufferList[s].vbPtr->Release();
m_staticBufferList[s].vbPtr = NULL;
}
if(m_staticBufferList[s].ibPtr)
{
m_staticBufferList[s].ibPtr->Release();
m_staticBufferList[s].ibPtr = NULL;
}
}
m_numStaticBuffers = 0;
if(m_staticBufferList) delete[] m_staticBufferList;
m_staticBufferList = NULL;
for(s = 0; s < m_numTextures; s++)
{
if(m_textureList[s].fileName)
{
delete[] m_textureList[s].fileName;
m_textureList[s].fileName = NULL;
}
if(m_textureList[s].image)
{
m_textureList[s].image->Release();
m_textureList[s].image = NULL;
}
}
m_numTextures = 0;
if(m_textureList) delete[] m_textureList;
m_textureList = NULL;
for(s = 0; s < m_totalFonts; s++)
{
if(m_fonts[s])
{
m_fonts[s]->Release();
m_fonts[s] = NULL;
}
}
m_totalFonts = 0;
if(m_fonts) delete[] m_fonts;
m_fonts = NULL;
for(s = 0; s < m_totalGUIs; s++)
{
m_guiList[s].Shutdown();
}
m_totalGUIs = 0;
if(m_guiList) delete[] m_guiList;
m_guiList = NULL;
if(m_Device) m_Device->Release();
if(m_Direct3D) m_Direct3D->Release();
m_Device = NULL;
m_Direct3D = NULL;
}
void CD3DRenderer::SetClearCol(float r, float g, float b)
{
m_Color = D3DCOLOR_COLORVALUE(r, g, b, 1.0f);
}
void CD3DRenderer::StartRender(bool bColor, bool bDepth,
bool bStencil)
{
if(!m_Device) return;
unsigned int buffers = 0;
if(bColor) buffers |= D3DCLEAR_TARGET;
if(bDepth) buffers |= D3DCLEAR_ZBUFFER;
if(bStencil) buffers |= D3DCLEAR_STENCIL;
if(FAILED(m_Device->Clear(0, NULL, buffers, m_Color, 1, 0)))
return;
if(FAILED(m_Device->BeginScene())) return;
m_renderingScene = true;
}
void CD3DRenderer::ClearBuffers(bool bColor, bool bDepth,
bool bStencil)
{
if(!m_Device) return;
unsigned int buffers = 0;
if(bColor) buffers |= D3DCLEAR_TARGET;
if(bDepth) buffers |= D3DCLEAR_ZBUFFER;
if(bStencil) buffers |= D3DCLEAR_STENCIL;
if(m_renderingScene) m_Device->EndScene();
if(FAILED(m_Device->Clear(0, NULL, buffers, m_Color, 1, 0)))
return;
if(m_renderingScene)
if(FAILED(m_Device->BeginScene())) return;
}
void CD3DRenderer::EndRendering()
{
if(!m_Device) return;
m_Device->EndScene();
m_Device->Present(NULL, NULL, NULL, NULL);
m_renderingScene = false;
}
void CD3DRenderer::SetMaterial(stMaterial *mat)
{
if(!mat || !m_Device) return;
D3DMATERIAL9 m = { mat->diffuseR, mat->diffuseG,
mat->diffuseB, mat->diffuseA,
mat->ambientR, mat->ambientG,