#include "zfxd3dUtility.h"


bool InitD3DApp(HINSTANCE hInstance,  // 程序实例句柄
	bool windowed,             // 布尔变量，是否为窗口模式
	D3DDEVTYPE deviceType,     // HAL or REF
	IDirect3D9** pd3d9,      // D3D对象接口
	IDirect3DDevice9** pd3dDevice,// D3D设备接口
	PCTSTR szTitle,           // 窗口标题名
	int width, int height)
{
	// 注册窗口类
	WNDCLASS wc;

	wc.style         = CS_HREDRAW | CS_VREDRAW;
	wc.lpfnWndProc   = (WNDPROC)WndProc; 
	wc.cbClsExtra    = 0;
	wc.cbWndExtra    = 0;
	wc.hInstance     = hInstance;
	wc.hIcon         = LoadIcon(0, IDI_APPLICATION);
	wc.hCursor       = LoadCursor(0, IDC_ARROW);
	wc.hbrBackground = (HBRUSH)GetStockObject(LTGRAY_BRUSH);
	wc.lpszMenuName  = 0;
	wc.lpszClassName = L"ZFXD3DApp";

	if( !RegisterClass(&wc) ) 
	{
		::MessageBox(0, L"FAILED to register WND class", 0, 0);
		return false;
	}
	
	// 创建窗口
	HWND hWnd = 0;
	hWnd = ::CreateWindow(L"ZFXD3DApp", szTitle, 
		WS_OVERLAPPEDWINDOW ,
		50, 50, width, height,
		0 /*父窗口*/, 0 /* 菜单名 */, hInstance, 0); 

	if( !hWnd )
	{
		::MessageBox(0, L"FAILED to create a window", 0, 0);
		return false;
	}

	::ShowWindow(hWnd, SW_SHOW);
	::UpdateWindow(hWnd);

	// 准备创建设备
	if(!((*pd3d9) = Direct3DCreate9(D3D_SDK_VERSION)))
	{
		::MessageBox(0, L"Create D3D Object FAILED", 0, 0);
		return false;
	}

	// 检查硬件是否支持顶点处理

	D3DCAPS9 caps;
	(*pd3d9)->GetDeviceCaps(D3DADAPTER_DEFAULT, deviceType, &caps);

	DWORD vp = 0;
	if( caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT )
		vp = D3DCREATE_HARDWARE_VERTEXPROCESSING;
	else
		vp = D3DCREATE_SOFTWARE_VERTEXPROCESSING;

	// 填充D3DPRESENT_PARAMETERS结构体.
 
	D3DPRESENT_PARAMETERS d3dpp;
	d3dpp.BackBufferWidth            = width;
	d3dpp.BackBufferHeight           = height;
	d3dpp.BackBufferFormat           = D3DFMT_A8R8G8B8;
	d3dpp.BackBufferCount            = 1;
	d3dpp.MultiSampleType            = D3DMULTISAMPLE_NONE;
	d3dpp.MultiSampleQuality         = 0;
	d3dpp.SwapEffect                 = D3DSWAPEFFECT_DISCARD; 
	d3dpp.hDeviceWindow              = hWnd;
	d3dpp.Windowed                   = windowed;
	d3dpp.EnableAutoDepthStencil     = true; 
	d3dpp.AutoDepthStencilFormat     = D3DFMT_D24S8;
	d3dpp.Flags                      = 0;
	d3dpp.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT;
	d3dpp.PresentationInterval       = D3DPRESENT_INTERVAL_IMMEDIATE;

	// 创建设备

	HRESULT hr;
	hr = (*pd3d9)->CreateDevice(
		D3DADAPTER_DEFAULT,
		deviceType,
		hWnd,
		vp,
	    &d3dpp,
	    pd3dDevice);

	if( FAILED(hr) )
	{
		(*pd3d9)->Release(); // 释放D3D对象资源
		::MessageBox(0, L"Create Device FAILED", 0, 0);
		return false;
	}

	return true;
}

bool InitDXFont(IDirect3DDevice9* pd3dDevice, ID3DXFont** pFont, PCTSTR szFontType, 
				bool isItalic, int height, int width, int weight)
{
	//创建字体
	D3DXFONT_DESC fontDesc;
	ZeroMemory( &fontDesc, sizeof(D3DXFONT_DESC) );
	fontDesc.Height = height;
	fontDesc.Width = width;
	fontDesc.Weight = weight;
	fontDesc.Italic = isItalic;
	wcscpy( fontDesc.FaceName, szFontType);

	if( SUCCEEDED( D3DXCreateFontIndirect( pd3dDevice, &fontDesc, pFont )))
		return true;
	else
		return false;
}

D3DLIGHT9 InitDirectionalLight(D3DXVECTOR3* direction, D3DXCOLOR* color)
{
	D3DLIGHT9 light;
	::ZeroMemory(&light, sizeof(light));

	light.Type      = D3DLIGHT_DIRECTIONAL;
	light.Ambient   = *color * 0.6f;
	light.Diffuse   = *color;
	light.Specular  = *color * 0.6f;
	light.Direction = *direction;

	return light;
}

D3DLIGHT9 InitPointLight(D3DXVECTOR3* position, D3DXCOLOR* color)
{
	D3DLIGHT9 light;
	::ZeroMemory(&light, sizeof(light));

	light.Type      = D3DLIGHT_POINT;
	light.Ambient   = *color * 0.6f;
	light.Diffuse   = *color;
	light.Specular  = *color * 0.6f;
	light.Position  = *position;
	light.Range        = 1000.0f;
	light.Falloff      = 1.0f;
	light.Attenuation0 = 1.0f;
	light.Attenuation1 = 0.0f;
	light.Attenuation2 = 0.0f;

	return light;
}

D3DLIGHT9 InitSpotLight(D3DXVECTOR3* position, D3DXVECTOR3* direction, D3DXCOLOR* color)
{
	D3DLIGHT9 light;
	::ZeroMemory(&light, sizeof(light));

	light.Type      = D3DLIGHT_SPOT;
	light.Ambient   = *color * 0.0f;
	light.Diffuse   = *color;
	light.Specular  = *color * 0.6f;
	light.Position  = *position;
	light.Direction = *direction;
	light.Range        = 1000.0f;
	light.Falloff      = 1.0f;
	light.Attenuation0 = 1.0f;
	light.Attenuation1 = 0.0f;
	light.Attenuation2 = 0.0f;
	light.Theta        = 0.4f;
	light.Phi          = 0.9f;

	return light;
}

D3DMATERIAL9 InitMtrl(D3DXCOLOR a, D3DXCOLOR d, D3DXCOLOR s, D3DXCOLOR e, float p)
{
	D3DMATERIAL9 mtrl;
	mtrl.Ambient  = a;
	mtrl.Diffuse  = d;
	mtrl.Specular = s;
	mtrl.Emissive = e;
	mtrl.Power    = p;
	return mtrl;
}

