www.pudn.com > Chesssource.rar > Graphics.cpp


#include "stdafx.h" 
 
cGraphics::cGraphics() 
{ 
  m_hWnd = NULL; 
   
  m_pD3DDevice = NULL; 
  m_AmbientRed = m_AmbientGreen = m_AmbientBlue = 255; 
 
  m_Width  = 0; 
  m_Height = 0; 
  m_Windowed = TRUE; 
} 
 
cGraphics::~cGraphics() 
{ 
  Shutdown(); 
} 
 
BOOL cGraphics::SetMode(HWND hWnd, BOOL Windowed, long Width, long Height) 
{ 
    HRESULT hr; 
	RECT ClientRect; 
	m_Windowed = Windowed; 
 
	if( (m_hWnd = hWnd) == NULL ) 
		return FALSE; 
 
    // Construct a new display 
    LPDIRECT3D9 pD3D = Direct3DCreate9( D3D_SDK_VERSION ); 
    if( NULL == pD3D ) 
    {      
		return FALSE; 
    } 
 
    // Get the current desktop format 
    pD3D->GetAdapterDisplayMode( D3DADAPTER_DEFAULT, &m_DesktopMode ); 
 
	if(!Width)  
	{ 
		if(Windowed == FALSE) 
		{ 
			m_Width = m_DesktopMode.Width; 
		}  
		else  
		{ 
			GetClientRect(m_hWnd, &ClientRect); 
			m_Width = ClientRect.right; 
		} 
	}  
	else  
	{ 
		m_Width = Width; 
	} 
 
 
	if(!Height)  
	{ 
		if(Windowed == FALSE)  
		{ 
			m_Height = m_DesktopMode.Height; 
		}  
		else  
		{ 
			GetClientRect(m_hWnd, &ClientRect); 
			m_Height = ClientRect.bottom; 
		} 
	}  
	else  
	{ 
		m_Height = Height; 
	} 
 
    const D3DFORMAT fmtFullscreenArray[] =  
    { 
        D3DFMT_A8R8G8B8, 
        D3DFMT_X8R8G8B8, 
        D3DFMT_X1R5G5B5, 
        D3DFMT_A1R5G5B5, 
        D3DFMT_R5G6B5, 
    }; 
    const INT numFullscreenFmts = sizeof(fmtFullscreenArray) / sizeof(fmtFullscreenArray[0]); 
    INT iFmt; 
 
    // Find a pixel format that will be good for fullscreen back buffers 
    for( iFmt = 0; iFmt < numFullscreenFmts; iFmt++ ) 
    { 
        if( SUCCEEDED( pD3D->CheckDeviceType( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,  
            fmtFullscreenArray[iFmt], fmtFullscreenArray[iFmt], FALSE ) ) ) 
        { 
            m_d3dfmtFullscreen = fmtFullscreenArray[iFmt]; 
            break; 
        } 
    } 
 
    const D3DFORMAT fmtTextureArray[] =  
    { 
        D3DFMT_A8R8G8B8, 
        D3DFMT_A4R4G4B4, 
        D3DFMT_A1R5G5B5, 
    }; 
    const INT numTextureFmts = sizeof(fmtTextureArray) / sizeof(fmtTextureArray[0]); 
 
    // Find a format that is supported as a texture map for the current mode 
    for( iFmt = 0; iFmt < numTextureFmts; iFmt++ ) 
    { 
        if( SUCCEEDED( pD3D->CheckDeviceFormat( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,  
            m_DesktopMode.Format, 0, D3DRTYPE_TEXTURE, fmtTextureArray[iFmt] ) ) ) 
        { 
            m_d3dfmtTexture = fmtTextureArray[iFmt]; 
            break; 
        } 
    } 
 
    // Set up presentation parameters for the display 
    ZeroMemory( &m_d3dpp, sizeof(m_d3dpp) ); 
    m_d3dpp.Windowed         = m_Windowed; 
    m_d3dpp.BackBufferCount  = 1; 
    m_d3dpp.SwapEffect       = D3DSWAPEFFECT_DISCARD; 
	if( SUCCEEDED(pD3D->CheckDeviceMultiSampleType( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, 
		m_d3dfmtTexture, m_Windowed, D3DMULTISAMPLE_4_SAMPLES, NULL))) 
	{ 
		m_d3dpp.MultiSampleType		= D3DMULTISAMPLE_4_SAMPLES; 
		m_d3dpp.MultiSampleQuality	= 0; 
	} 
    m_d3dpp.EnableAutoDepthStencil = TRUE; 
    m_d3dpp.AutoDepthStencilFormat = D3DFMT_D16; 
    m_d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; 
    if( !m_Windowed ) 
    { 
        m_d3dpp.hDeviceWindow    = m_hWnd; 
        m_d3dpp.BackBufferWidth  = m_Width; 
        m_d3dpp.BackBufferHeight = m_Height; 
        m_d3dpp.BackBufferFormat = m_d3dfmtFullscreen; 
    } 
    else 
    { 
        m_d3dpp.BackBufferFormat = m_DesktopMode.Format; 
    } 
 
    D3DDEVTYPE dwDevType = D3DDEVTYPE_HAL; 
    DWORD dwBehaviorFlags = D3DCREATE_SOFTWARE_VERTEXPROCESSING; 
 
    // Create the device 
    hr = pD3D->CreateDevice( D3DADAPTER_DEFAULT, dwDevType, hWnd, 
                             dwBehaviorFlags, &m_d3dpp, &m_pD3DDevice ); 
    pD3D->Release(); 
    if( FAILED(hr) ) 
    { 
        return FALSE; 
    } 
 
	EnableZBuffer(TRUE); 
	EnableAlphaBlending(FALSE); 
	EnableAlphaTesting(FALSE); 
	m_pD3DDevice->SetRenderState( D3DRS_SPECULARENABLE, TRUE ); 
 
	m_pD3DDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE ); 
	m_pD3DDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE ); 
	m_pD3DDevice->SetTextureStageState( 0, D3DTSS_COLOROP,   D3DTOP_MODULATE ); 
 
	m_pD3DDevice->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); 
	m_pD3DDevice->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR); 
 
	SetAmbientLight(255,255,255); 
 
	SetPerspective(D3DX_PI/6,1.33333f,1.0f,1000.0f); 
 
	if(FAILED(D3DXCreateSprite(m_pD3DDevice, &m_pSprite))) 
		return FALSE; 
 
	return TRUE; 
} 
 
BOOL cGraphics::Shutdown() 
{ 
	SAFE_RELEASE(m_pD3DDevice); 
	SAFE_RELEASE(m_pSprite); 
	return TRUE; 
} 
 
IDirect3DDevice9 *cGraphics::Get3DDevice() 
{ 
	return m_pD3DDevice; 
} 
 
ID3DXSprite *cGraphics::GetSpriteDevice() 
{ 
	return m_pSprite; 
} 
 
BOOL cGraphics::BeginScene() 
{ 
	if(m_pD3DDevice == NULL) 
		return FALSE; 
 
	if(FAILED(m_pD3DDevice->BeginScene())) 
		return FALSE; 
 
	return TRUE; 
} 
 
BOOL cGraphics::EndScene() 
{ 
	DWORD i; 
 
	if(m_pD3DDevice == NULL) 
		return FALSE; 
 
	for(i=0;i<8;i++) 
		m_pD3DDevice->SetTexture(i, NULL); 
 
	if(FAILED(m_pD3DDevice->EndScene())) 
		return FALSE; 
 
	return TRUE; 
} 
 
BOOL cGraphics::Display() 
{ 
	if(m_pD3DDevice == NULL) 
		return FALSE; 
 
	if(FAILED(m_pD3DDevice->Present(NULL, NULL, NULL, NULL))) 
		return FALSE; 
 
	return TRUE; 
} 
 
BOOL cGraphics::Clear(long Color, float ZBuffer) 
{ 
	if(m_pD3DDevice == NULL) 
		return FALSE; 
 
	if(FAILED(m_pD3DDevice->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, Color, ZBuffer, 0))) 
		return FALSE; 
 
	return TRUE;  
} 
 
BOOL cGraphics::ClearDisplay(long Color) 
{ 
	if(m_pD3DDevice == NULL) 
		return FALSE; 
 
	if(FAILED(m_pD3DDevice->Clear(0, NULL, D3DCLEAR_TARGET, Color, 1.0f, 0))) 
		return FALSE; 
 
	return TRUE;  
}   
 
BOOL cGraphics::ClearZBuffer(float ZBuffer) 
{ 
	if(m_pD3DDevice == NULL) 
		return FALSE; 
 
	if(FAILED(m_pD3DDevice->Clear(0, NULL, D3DCLEAR_ZBUFFER, 0, ZBuffer, 0))) 
		return FALSE; 
 
	return TRUE; 
} 
 
long cGraphics::GetWidth() 
{ 
	return m_Width; 
} 
 
long cGraphics::GetHeight() 
{ 
	return m_Height; 
} 
 
BOOL cGraphics::SetAmbientLight(char Red, char Green, char Blue) 
{ 
	D3DCOLOR Color; 
 
	if(m_pD3DDevice == NULL) 
		return FALSE; 
 
	Color = D3DCOLOR_XRGB((m_AmbientRed = Red), (m_AmbientGreen = Green), (m_AmbientBlue = Blue)); 
	if(FAILED(m_pD3DDevice->SetRenderState(D3DRS_AMBIENT, Color))) 
		return FALSE; 
 
	return TRUE; 
} 
 
BOOL cGraphics::GetAmbientLight(char *Red, char *Green, char *Blue) 
{ 
	if(Red != NULL) 
		*Red = m_AmbientRed; 
	if(Green != NULL) 
		*Green = m_AmbientGreen; 
	if(Blue != NULL) 
		*Blue = m_AmbientBlue; 
 
	return TRUE; 
} 
 
BOOL cGraphics::SetPerspective(float FOV, float Aspect, float Near, float Far) 
{ 
	D3DXMATRIX matProjection; 
 
	if(m_pD3DDevice == NULL) 
		return FALSE; 
 
	D3DXMatrixPerspectiveFovLH(&matProjection, FOV, Aspect, Near, Far); 
	if(FAILED(m_pD3DDevice->SetTransform(D3DTS_PROJECTION, &matProjection))) 
		return FALSE; 
	return TRUE; 
} 
 
BOOL cGraphics::EnableLight(long Num, BOOL Enable) 
{ 
	if(m_pD3DDevice == NULL) 
		return FALSE; 
 
	if(FAILED(m_pD3DDevice->LightEnable(Num, Enable))) 
		return FALSE; 
 
	return TRUE; 
} 
 
BOOL cGraphics::EnableLighting(BOOL Enable) 
{ 
	if(m_pD3DDevice == NULL) 
		return FALSE; 
 
	if(FAILED(m_pD3DDevice->SetRenderState(D3DRS_LIGHTING, Enable))) 
		return FALSE; 
 
	return TRUE; 
} 
 
BOOL cGraphics::EnableZBuffer(BOOL Enable) 
{ 
	if(m_pD3DDevice == NULL) 
		return FALSE; 
 
	if(FAILED(m_pD3DDevice->SetRenderState(D3DRS_ZENABLE, (Enable == TRUE) ? D3DZB_TRUE : D3DZB_FALSE))) 
		return FALSE; 
 
	return TRUE; 
} 
 
BOOL cGraphics::EnableAlphaBlending(BOOL Enable, DWORD Src, DWORD Dest) 
{ 
	if(m_pD3DDevice == NULL) 
		return FALSE; 
 
	if(FAILED(m_pD3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, Enable))) 
		return FALSE; 
 
	if(Enable == TRUE)  
	{ 
		m_pD3DDevice->SetRenderState(D3DRS_SRCBLEND,  Src); 
		m_pD3DDevice->SetRenderState(D3DRS_DESTBLEND, Dest); 
	} 
 
	return TRUE; 
} 
 
BOOL cGraphics::EnableAlphaTesting(BOOL Enable) 
{ 
	if(m_pD3DDevice == NULL) 
		return FALSE; 
 
	if(FAILED(m_pD3DDevice->SetRenderState(D3DRS_ALPHATESTENABLE, Enable))) 
		return FALSE; 
 
	if(Enable == TRUE) { 
		m_pD3DDevice->SetRenderState(D3DRS_ALPHAREF, 0x08); 
		m_pD3DDevice->SetRenderState(D3DRS_ALPHAFUNC, D3DCMP_GREATEREQUAL); 
	} 
 
	return TRUE; 
} 
 
cTexture::cTexture() 
{ 
	m_pGraphics = NULL; 
	m_pTexture = NULL; 
	m_pSprite = NULL; 
	m_dwTexWidth = m_dwTexHeight = 0; 
} 
 
cTexture::~cTexture() 
{ 
	Free(); 
} 
 
BOOL cTexture::Load( cGraphics *Graphics, char *strFilename, DWORD dwTransparent, D3DFORMAT fmtFormat ) 
{ 
	Free(); 
 
	if((m_pGraphics = Graphics) == NULL) 
		return FALSE; 
	if(Graphics->Get3DDevice() == NULL) 
		return FALSE; 
	if(strFilename == NULL) 
		return FALSE; 
 
	if( FAILED( D3DXCreateTextureFromFileEx( Graphics->Get3DDevice(), strFilename, D3DX_DEFAULT, 
		D3DX_DEFAULT, D3DX_DEFAULT, 0, fmtFormat, D3DPOOL_MANAGED, D3DX_FILTER_TRIANGLE, D3DX_FILTER_TRIANGLE, 
		dwTransparent, NULL, NULL, &m_pTexture ))) 
		return FALSE; 
 
	m_dwTexWidth = GetTexWidth(); 
	m_dwTexHeight = GetTexHeight(); 
 
	return S_OK; 
} 
 
 
HRESULT cTexture::Create( cGraphics *Graphics, DWORD dwTexWidth, DWORD dwTexHeight, D3DFORMAT fmtFormat ) 
{ 
	Free(); 
	 
	if(( m_pGraphics = Graphics ) == NULL ) 
		return E_FAIL; 
 
	if( FAILED( m_pGraphics->Get3DDevice()->CreateTexture( dwTexWidth, dwTexHeight, 0, 0, fmtFormat, D3DPOOL_MANAGED, &m_pTexture, NULL ))) 
		return DXTRACE_ERR( TEXT("195行"), E_FAIL ); 
 
	return S_OK; 
} 
 
 
HRESULT cTexture::Create( cGraphics *Graphics, IDirect3DTexture9 *Texture ) 
{ 
	D3DLOCKED_RECT SrcRect, DestRect; 
	D3DSURFACE_DESC Desc; 
 
	Free(); 
 
	if(( m_pGraphics = Graphics ) == NULL ) return E_FAIL; 
 
	if( Texture == NULL ) return S_OK; 
 
	Texture->GetLevelDesc( 0, &Desc ); 
	m_dwTexWidth = Desc.Width; 
	m_dwTexHeight = Desc.Height; 
	if( FAILED(m_pGraphics->Get3DDevice()->CreateTexture( m_dwTexWidth, m_dwTexHeight, 0, 0, Desc.Format, D3DPOOL_MANAGED, &m_pTexture, NULL ))) 
		return DXTRACE_ERR( TEXT("216行"), E_FAIL ); 
 
	Texture->LockRect( 0, &SrcRect, NULL, D3DLOCK_READONLY ); 
	m_pTexture->LockRect( 0, &DestRect, NULL, 0 ); 
 
	memcpy( DestRect.pBits, SrcRect.pBits, SrcRect.Pitch * m_dwTexHeight ); 
	m_pTexture->UnlockRect(0); 
	Texture->UnlockRect(0); 
 
	return S_OK; 
} 
 
BOOL cTexture::Blit(long DestX, long DestY, long SrcX, long SrcY, long Width, long Height, float XScale, float YScale, D3DCOLOR Color) 
{ 
	RECT Rect; 
 
	if(m_pTexture == NULL) return FALSE; 
	if(m_pGraphics == NULL) return FALSE; 
	if((m_pSprite = m_pGraphics->GetSpriteDevice()) == NULL) return FALSE; 
 
	if(!Width) Width = m_dwTexWidth; 
	if(!Height) Height = m_dwTexHeight; 
 
	Rect.left = SrcX; 
	Rect.top  = SrcY; 
	Rect.right = Rect.left + Width; 
	Rect.bottom = Rect.top + Height; 
 
	m_pSprite->Begin(D3DXSPRITE_ALPHABLEND | D3DXSPRITE_SORT_TEXTURE); 
	if(FAILED(m_pSprite->Draw(m_pTexture, &Rect, &D3DXVECTOR3(0.0f, 0.0f, 0.0f), &D3DXVECTOR3((float)DestX, (float)DestY, 0.0f), Color))) 
		return FALSE; 
	m_pSprite->End(); 
	return TRUE; 
} 
 
VOID cTexture::Free() 
{ 
	SAFE_RELEASE(m_pTexture); 
	m_pSprite = NULL; 
	m_pGraphics = NULL; 
	m_dwTexWidth = m_dwTexHeight = 0; 
} 
 
 
BOOL cTexture::IsLoaded() 
{ 
	if( m_pTexture == NULL ) 
		return FALSE; 
	return TRUE; 
} 
 
 
IDirect3DTexture9 *cTexture::GetTexDevice() 
{ 
	return m_pTexture; 
} 
 
 
DWORD cTexture::GetTexWidth() 
{ 
	D3DSURFACE_DESC d3dsd; 
 
	if( m_pTexture == NULL ) 
		return 0; 
 
	if( FAILED(m_pTexture->GetLevelDesc( 0, &d3dsd ))) 
		return 0; 
 
	return d3dsd.Width; 
} 
 
 
DWORD cTexture::GetTexHeight() 
{ 
	D3DSURFACE_DESC d3dsd; 
 
	if( m_pTexture == NULL ) 
		return 0; 
 
	if( FAILED(m_pTexture->GetLevelDesc( 0, &d3dsd ))) 
		return 0; 
 
	return d3dsd.Height; 
} 
 
 
D3DFORMAT cTexture::GetTexFormat() 
{ 
	D3DSURFACE_DESC d3dsd; 
 
	if( m_pTexture == NULL ) 
		return D3DFMT_UNKNOWN; 
 
	if( FAILED( m_pTexture->GetLevelDesc( 0, &d3dsd ))) 
		return D3DFMT_UNKNOWN; 
 
	return d3dsd.Format; 
} 
 
 
cCamera::cCamera() 
{ 
	Move( 0.0f, 0.f, 0.0f); 
	Rotate( 0.0f, 0.0f, 0.0f ); 
	Update(); 
} 
 
 
void cCamera::Move( float fXPos, float fYPos, float fZPos ) 
{ 
	m_fXPos = fXPos; 
	m_fYPos = fYPos; 
	m_fZPos = fZPos; 
 
	D3DXMatrixTranslation( &m_matTranslation, -m_fXPos, -m_fYPos, -m_fZPos ); 
} 
 
 
void cCamera::MoveRel( float fXAdd, float fYAdd, float fZAdd ) 
{ 
	Move( m_fXPos + fXAdd, m_fYPos + fYAdd, m_fZPos + fZAdd ); 
} 
 
 
void cCamera::Rotate( float fXRot, float fYRot, float fZRot ) 
{ 
	D3DXMATRIX matXRotation, matYRotation, matZRotation; 
 
	m_fXRot = fXRot; 
	m_fYRot = fYRot; 
	m_fZRot = fZRot; 
 
	D3DXMatrixRotationX( &matXRotation, -m_fXRot ); 
	D3DXMatrixRotationY( &matYRotation, -m_fYRot ); 
	D3DXMatrixRotationZ( &matZRotation, -m_fZRot ); 
 
	m_matRotation = matZRotation; 
	D3DXMatrixMultiply( &m_matRotation, &m_matRotation, &matYRotation ); 
	D3DXMatrixMultiply( &m_matRotation, &m_matRotation, &matXRotation ); 
} 
 
 
void cCamera::RotateRel( float fXAdd, float fYAdd, float fZAdd ) 
{ 
	Rotate( m_fXRot + fXAdd, m_fYRot + fYAdd, m_fZRot + fZAdd ); 
} 
 
 
void cCamera::Point( float fXEye, float fYEye, float fZEye, float fXAt, float fYAt, float fZAt ) 
{ 
	float fXRot, fYRot, fXDiff, fYDiff, fZDiff; 
 
	// 计算两点之间的角度 
	fXDiff = fXAt - fXEye; 
	fYDiff = fYAt - fYEye; 
	fZDiff = fZAt - fZEye; 
 
	fXRot = (float)atan2(-fYDiff, sqrt(fXDiff*fXDiff+fZDiff*fZDiff)); 
	fYRot = (float)atan2(fXDiff, fZDiff); 
 
	Move( fXEye, fYEye, fZEye ); 
	Rotate( fXRot, fYRot, 0.0f ); 
} 
 
 
void cCamera::SetStartTrack() 
{ 
	m_fStartXPos = m_fXPos; 
	m_fStartYPos = m_fYPos; 
	m_fStartZPos = m_fZPos; 
	m_fStartXRot = m_fXRot; 
	m_fStartYRot = m_fYRot; 
	m_fStartZRot = m_fZRot; 
} 
 
 
void cCamera::SetEndTrack() 
{ 
	m_fEndXPos = m_fXPos; 
	m_fEndYPos = m_fYPos; 
	m_fEndZPos = m_fZPos; 
	m_fEndXRot = m_fXRot; 
	m_fEndYRot = m_fYRot; 
	m_fEndZRot = m_fZRot; 
} 
 
 
void cCamera::Track( float fTime, float fLength ) 
{ 
	float x, y, z; 
	float fTimeOffset; 
 
	fTimeOffset = fLength * fTime; 
 
	x = (m_fEndXPos - m_fStartXPos) / fLength * fTimeOffset; 
	y = (m_fEndYPos - m_fStartYPos) / fLength * fTimeOffset; 
	z = (m_fEndZPos - m_fStartZPos) / fLength * fTimeOffset; 
	Move( m_fStartXPos + x, m_fStartYPos + y, m_fStartZPos + z ); 
 
	x = (m_fEndXRot - m_fStartXRot) / fLength * fTimeOffset; 
	y = (m_fEndYRot - m_fStartYRot) / fLength * fTimeOffset; 
	z = (m_fEndZRot - m_fStartZRot) / fLength * fTimeOffset; 
	Rotate( m_fStartXRot + x, m_fStartYRot + y, m_fStartZRot + z ); 
} 
 
 
void cCamera::Update() 
{ 
	D3DXMatrixMultiply( &m_matWorld, &m_matTranslation, &m_matRotation ); 
} 
 
 
D3DXMATRIX *cCamera::GetMatrix() 
{ 
	Update(); 
	return &m_matWorld; 
} 
 
 
float cCamera::GetXPos() 
{ 
  return m_fXPos; 
} 
 
float cCamera::GetYPos() 
{ 
  return m_fYPos; 
} 
 
float cCamera::GetZPos() 
{ 
  return m_fZPos; 
} 
 
float cCamera::GetXRotation() 
{ 
  return m_fXRot; 
} 
 
float cCamera::GetYRotation() 
{ 
  return m_fYRot; 
} 
 
float cCamera::GetZRotation() 
{ 
  return m_fZRot; 
} 
 
 
cLight::cLight() 
{ 
	ZeroMemory( &m_pLight, sizeof( D3DLIGHT9)); 
} 
 
 
void cLight::SetType( D3DLIGHTTYPE Type ) 
{ 
	m_pLight.Type = Type; 
} 
 
 
void cLight::Move( float fXPos, float fYPos, float fZPos ) 
{ 
	m_pLight.Position.x = fXPos; 
	m_pLight.Position.y = fYPos; 
	m_pLight.Position.z = fZPos; 
} 
 
 
void cLight::MoveRel( float fXPos, float fYPos, float fZPos ) 
{ 
	m_pLight.Position.x += fXPos; 
	m_pLight.Position.y += fYPos; 
	m_pLight.Position.z += fZPos; 
} 
 
 
void cLight::GetPos( float *fXPos, float *fYPos, float *fZPos ) 
{ 
	if( fXPos != NULL ) 
		*fXPos = m_pLight.Position.x; 
	if( fYPos != NULL ) 
		*fYPos = m_pLight.Position.y; 
	if( fZPos != NULL ) 
		*fZPos = m_pLight.Position.z; 
} 
 
 
void cLight::Point( float fXFrom, float fYFrom, float fZFrom, float fXAt, float fYAt, float fZAt ) 
{ 
	Move( fXFrom, fYFrom, fZFrom ); 
 
	m_pLight.Direction.x = fXAt; 
	m_pLight.Direction.y = fYAt; 
	m_pLight.Direction.z = fZAt; 
} 
 
 
void cLight::GetDirection( float *fXDir, float *fYDir, float *fZDir ) 
{ 
	if( fXDir != NULL ) 
		*fXDir = m_pLight.Direction.x; 
	if( fYDir != NULL ) 
		*fYDir = m_pLight.Direction.y; 
	if( fZDir != NULL ) 
		*fZDir = m_pLight.Direction.z; 
} 
 
 
void cLight::SetDiffuseColor( char cRed, char cGreen, char cBlue ) 
{ 
	m_pLight.Diffuse.r = 1.0f / 255.0f * (float)cRed; 
	m_pLight.Diffuse.g = 1.0f / 255.0f * (float)cGreen; 
	m_pLight.Diffuse.b = 1.0f / 255.0f * (float)cBlue; 
} 
 
 
void cLight::GetDiffuseColor( char *cRed, char *cGreen, char *cBlue ) 
{ 
	if( cRed != NULL ) 
		*cRed = (char)(255.0f * m_pLight.Diffuse.r ); 
	if( cGreen != NULL ) 
		*cGreen = (char)(255.0f * m_pLight.Diffuse.g ); 
	if( cBlue != NULL ) 
		*cBlue = (char)(255.0f * m_pLight.Diffuse.b ); 
} 
 
 
void cLight::SetSpecularColor( char cRed, char cGreen, char cBlue ) 
{ 
	m_pLight.Specular.r = 1.0f / 255.0f * (float)cRed; 
	m_pLight.Specular.g = 1.0f / 255.0f * (float)cGreen; 
	m_pLight.Specular.b = 1.0f / 255.0f * (float)cBlue; 
} 
 
 
void cLight::GetSpecularColor( char *cRed, char *cGreen, char *cBlue ) 
{ 
	if(cRed != NULL) 
		*cRed = (char)(255.0f * m_pLight.Specular.r); 
	if(cGreen != NULL) 
		*cGreen = (char)(255.0f * m_pLight.Specular.g); 
	if(cBlue != NULL) 
		*cBlue = (char)(255.0f * m_pLight.Specular.b); 
} 
 
 
void cLight::SetAmbientColor(char cRed, char cGreen, char cBlue) 
{ 
	m_pLight.Ambient.r = 1.0f / 255.0f * (float)cRed; 
	m_pLight.Ambient.g = 1.0f / 255.0f * (float)cGreen; 
	m_pLight.Ambient.b = 1.0f / 255.0f * (float)cBlue; 
} 
 
 
void cLight::GetAmbientColor(char *cRed, char *cGreen, char *cBlue) 
{ 
	if(cRed != NULL) 
		*cRed = (char)(255.0f * m_pLight.Ambient.r); 
	if(cGreen != NULL) 
		*cGreen = (char)(255.0f * m_pLight.Ambient.g); 
	if(cBlue != NULL) 
		*cBlue = (char)(255.0f * m_pLight.Ambient.b); 
} 
 
 
void cLight::SetRange( float fRange ) 
{ 
	m_pLight.Range = fRange; 
} 
 
 
float cLight::GetRange() 
{ 
	return m_pLight.Range; 
} 
 
 
void cLight::SetFalloff( float fFalloff ) 
{ 
	m_pLight.Falloff = fFalloff; 
} 
 
 
float cLight::GetFalloff() 
{ 
	return m_pLight.Falloff; 
} 
 
 
void cLight::SetAttenuation0( float fAttenuation ) 
{ 
	m_pLight.Attenuation0 = fAttenuation; 
} 
 
 
float cLight::GetAttenuation0() 
{ 
	return m_pLight.Attenuation0; 
} 
 
 
void cLight::SetAttenuation1(float fAttenuation) 
{ 
	m_pLight.Attenuation1 = fAttenuation; 
} 
 
 
float cLight::GetAttenuation1() 
{ 
	return m_pLight.Attenuation1; 
} 
 
 
void cLight::SetAttenuation2(float fAttenuation) 
{ 
	m_pLight.Attenuation2 = fAttenuation; 
} 
 
 
float cLight::GetAttenuation2() 
{ 
	return m_pLight.Attenuation2; 
} 
 
 
void cLight::SetTheta(float fTheta) 
{ 
	m_pLight.Theta = fTheta; 
} 
 
 
float cLight::GetTheta() 
{ 
	return m_pLight.Theta; 
} 
 
 
void cLight::SetPhi(float fPhi) 
{ 
	m_pLight.Phi = fPhi; 
} 
 
 
float cLight::GetPhi() 
{ 
	return m_pLight.Phi; 
} 
 
D3DLIGHT9 *cLight::GetLight() 
{ 
	return &m_pLight; 
} 
 
 
cFont::cFont() 
{ 
	m_Font = NULL; 
} 
 
cFont::~cFont() 
{ 
	Free(); 
} 
 
ID3DXFont *cFont::GetFontDevice() 
{ 
	return m_Font; 
} 
 
BOOL cFont::Create(cGraphics *Graphics, char *Name, long Size, BOOL Bold, BOOL Italic, BOOL Underline, BOOL Strikeout) 
{ 
    HRESULT hr; 
    int nHeight; 
 
    HDC hDC = GetDC( NULL ); 
    int nLogPixelsY = GetDeviceCaps(hDC, LOGPIXELSY); 
    ReleaseDC( NULL, hDC ); 
 
	if(Size == 0) 
		nHeight = -12 * nLogPixelsY / 72; 
	else 
		nHeight = Size; 
	hr = D3DXCreateFont( Graphics->Get3DDevice(),          // D3D device 
                         nHeight,               // Height 
                         0,                     // Width 
                         FW_BOLD,               // Weight 
                         0,                     // MipLevels, 0 = autogen mipmaps 
                         FALSE,                 // Italic 
                         DEFAULT_CHARSET,       // CharSet 
                         OUT_DEFAULT_PRECIS,    // OutputPrecision 
                         DEFAULT_QUALITY,       // Quality 
                         DEFAULT_PITCH | FF_DONTCARE, // PitchAndFamily 
                         Name,              // pFaceName 
                         &m_Font);  
	return TRUE; 
} 
 
BOOL cFont::Free() 
{ 
	SAFE_RELEASE(m_Font); 
	return TRUE; 
} 
 
BOOL cFont::Print(char *Text, long XPos, long YPos, long Width, long Height, D3DCOLOR Color, DWORD Format) 
{ 
	RECT Rect; 
 
	if(m_Font == NULL) 
		return FALSE; 
 
	if(!Width) 
		Width = 65535; 
	if(!Height) 
		Height = 65536; 
 
	Rect.left   = XPos; 
	Rect.top    = YPos; 
	Rect.right  = Rect.left + Width; 
	Rect.bottom = Rect.top + Height; 
	if(FAILED(m_Font->DrawText(NULL, Text, -1, &Rect, Format, Color))) 
		return FALSE; 
	return TRUE; 
} 
 
cVertexBuffer::cVertexBuffer() 
{ 
  m_Graphics = NULL; 
  m_pVB = NULL; 
  m_NumVertices = 0; 
  m_FVF = 0; 
  m_Locked = FALSE; 
  m_Ptr = NULL; 
} 
 
cVertexBuffer::~cVertexBuffer() 
{ 
  Free(); 
} 
 
IDirect3DVertexBuffer9 *cVertexBuffer::GetVertexBufferCOM() 
{ 
  return m_pVB; 
} 
 
unsigned long cVertexBuffer::GetVertexSize() 
{ 
  return D3DXGetFVFVertexSize(m_FVF); 
} 
 
unsigned long cVertexBuffer::GetVertexFVF() 
{ 
  return m_FVF; 
} 
 
unsigned long cVertexBuffer::GetNumVertices() 
{ 
  return m_NumVertices; 
} 
 
BOOL cVertexBuffer::Create(cGraphics *Graphics, unsigned long NumVertices, DWORD Descriptor, long VertexSize) 
{ 
	Free(); 
 
	if((m_Graphics = Graphics) == NULL) 
		return FALSE; 
	if(m_Graphics->Get3DDevice() == NULL) 
		return FALSE; 
	if(!(m_NumVertices = NumVertices) || !(m_FVF = Descriptor) || !(m_VertexSize = VertexSize)) 
		return FALSE; 
 
	if(FAILED(m_Graphics->Get3DDevice()->CreateVertexBuffer(m_NumVertices * m_VertexSize,0, m_FVF,D3DPOOL_MANAGED, &m_pVB, NULL))) 
		return FALSE; 
 
	return TRUE; 
} 
 
BOOL cVertexBuffer::Free() 
{ 
	Unlock(); 
	SAFE_RELEASE(m_pVB); 
	m_Graphics = NULL; 
	m_NumVertices = 0; 
	m_FVF = 0; 
	m_Locked = FALSE; 
	m_Ptr = NULL; 
 
	return TRUE; 
} 
 
BOOL cVertexBuffer::Set(unsigned long FirstVertex, unsigned long NumVertices, void *VertexList) 
{ 
	if(m_Graphics == NULL || VertexList == NULL || m_pVB == NULL) 
		return FALSE; 
	if(m_Graphics->Get3DDevice() == NULL) 
		return FALSE; 
 
	// Lock the vertex buffer 
	if(Lock(FirstVertex, NumVertices) == FALSE) 
		return FALSE; 
 
	// Copy vertices to vertex buffer 
	memcpy(m_Ptr, VertexList, NumVertices * m_VertexSize); 
 
	// Unlock vertex buffer 
	if(Unlock() == FALSE) 
		return FALSE; 
 
	return TRUE; 
} 
 
BOOL cVertexBuffer::Render(unsigned long FirstVertex, unsigned long NumPrimitives, DWORD Type) 
{ 
  if(m_Graphics->Get3DDevice() == NULL || m_pVB == NULL) 
    return FALSE; 
 
  m_Graphics->Get3DDevice()->SetStreamSource(0, m_pVB, 0, m_VertexSize); 
  m_Graphics->Get3DDevice()->SetFVF(m_FVF); 
  m_Graphics->Get3DDevice()->DrawPrimitive((D3DPRIMITIVETYPE)Type, FirstVertex, NumPrimitives); 
   
  return TRUE; 
} 
 
BOOL cVertexBuffer::Lock(unsigned long FirstVertex, unsigned long NumVertices) 
{ 
  if(m_pVB == NULL) 
    return FALSE; 
 
  if(FAILED(m_pVB->Lock(FirstVertex * m_VertexSize,  
            NumVertices * m_VertexSize, (void**)&m_Ptr,  
            0))) 
    return FALSE; 
 
  m_Locked = TRUE; 
 
  return TRUE; 
} 
 
BOOL cVertexBuffer::Unlock() 
{  
  if(m_pVB == NULL) 
    return FALSE; 
 
  if(FAILED(m_pVB->Unlock())) 
    return FALSE; 
 
  m_Locked = FALSE; 
 
  return TRUE; 
} 
 
BOOL cVertexBuffer::IsLoaded() 
{ 
  return (m_pVB == NULL) ? FALSE : TRUE; 
} 
 
void *cVertexBuffer::GetPtr() 
{ 
  return (void*)m_Ptr; 
}