//*************************************************************************************//
// Utility.cpp
// 对在Utility.hpp中声明的函数定义
//*************************************************************************************//
#include"d3dUtility.h"
#define WINDOWCLASSNAME TEXT("Direct3D9App")
#define REGISTERFAILED TEXT("RegisterClass()-FAILED")
#define CREATEWINDOWFAILED TEXT("CreateWindow()-FAILED")
#define DIRECT3DCREATE9FAILED TEXT("Direct3DCreate9()-FAILED")
#define CREATEDEVICEFALIED TEXT("CreateDevice()-FAILED")
#define WINDOWNAME TEXT("WindowByJosh")
//***************************初始化函数*******************************************//
bool d3d::InitiateD3D(HINSTANCE hInstance, int iWidth, int iHeight, bool windowed,
D3DDEVTYPE deviceType, IDirect3DDevice9** device)
{
//**************************创建主窗口******************************//
WNDCLASS wc;
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = (WNDPROC)d3d::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(WHITE_BRUSH);
wc.lpszMenuName = 0;
wc.lpszClassName = WINDOWCLASSNAME;
if(!RegisterClass(&wc))
{
::MessageBox(0, REGISTERFAILED, 0, 0);
return false;
}
HWND hWnd = 0;
hWnd = ::CreateWindow(WINDOWCLASSNAME, WINDOWNAME, WS_EX_TOPMOST,
0, 0, iWidth, iHeight, 0, 0, hInstance, 0);
if(!hWnd)
{
::MessageBox(0, CREATEWINDOWFAILED, 0, 0);
return false;
}
::ShowWindow(hWnd, SW_SHOW);
::UpdateWindow(hWnd);
//************************初始化D3D**********************************//
HRESULT hr = 0;
// 1.创建Direct3D设备接口对象,即IDirect3D9对象
IDirect3D9* d3d9;
d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
if(!d3d9)
{
::MessageBox(0, DIRECT3DCREATE9FAILED, 0, 0);
return false;
}
// 2.检验硬件顶点运算
D3DCAPS9 caps;
d3d9->GetDeviceCaps(D3DADAPTER_DEFAULT, deviceType, &caps);
int vp = 0;
if(caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT )
vp = D3DCREATE_HARDWARE_VERTEXPROCESSING;
else
vp = D3DCREATE_SOFTWARE_VERTEXPROCESSING;
// 3.填充D3DPRESENT_PARAMETERS结构
D3DPRESENT_PARAMETERS d3dpp;
d3dpp.BackBufferWidth = iWidth;
d3dpp.BackBufferHeight = iHeight;
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;
// 4.创建Direct3D设备对象
hr = d3d9->CreateDevice(D3DADAPTER_DEFAULT, deviceType, hWnd, vp, &d3dpp, device);
if(FAILED(hr))
{
//尝试使用16bits深度缓存
d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
hr = d3d9->CreateDevice(
D3DADAPTER_DEFAULT,
deviceType,
hWnd,
vp,
&d3dpp,
device);
if(FAILED(hr))
{
::MessageBox(hWnd, CREATEDEVICEFALIED, 0, 0);
return false;
}
}
d3d9->Release(); //释放接口对象
return true;
}
//***************************消息循环函数*****************************************//
int d3d::EnterMessageLoop( bool (*ptr_display)(float timeDelta) )
{
MSG msg;
::ZeroMemory(&msg, sizeof(MSG));
static float lastTime = (float)timeGetTime();
while(msg.message != WM_QUIT)
{
if(::PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
{
::TranslateMessage(&msg);
::DispatchMessage(&msg);
}
else
{
float currTime = (float)timeGetTime();
float timeDelta = (currTime - lastTime)*0.001f;
ptr_display(timeDelta);
lastTime = currTime;
}
}
return msg.wParam;
}
//***************************光照初始化函数************************************************************//
D3DLIGHT9 d3d::IniateDirectionalLight(D3DXVECTOR3* direction, D3DXCOLOR* color)
{
D3DLIGHT9 light;
::ZeroMemory(&light, sizeof(D3DLIGHT9));
light.Type = D3DLIGHT_DIRECTIONAL;
light.Ambient = *color * 0.4f;
light.Diffuse = *color;
light.Specular = *color * 0.6f;
light.Direction = *direction;
return light;
}
D3DLIGHT9 d3d::IniatePointLight(D3DXVECTOR3* position, D3DXCOLOR* color)
{
D3DLIGHT9 light;
::ZeroMemory(&light, sizeof(D3DLIGHT9));
light.Type = D3DLIGHT_POINT;
light.Ambient = *color * 0.4f;
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 d3d::IniateSpotLight(D3DXVECTOR3* position, D3DXVECTOR3* direction, D3DXCOLOR* color)
{
D3DLIGHT9 light;
::ZeroMemory(&light, sizeof(D3DLIGHT9));
light.Type = D3DLIGHT_SPOT;
light.Ambient = *color * 0.4f;
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.5f;
light.Phi = 0.7f;
return light;
}
//***************************材质初始化函数*********************************************//
D3DMATERIAL9 d3d::IniateMaterial(D3DXCOLOR a, D3DXCOLOR d, D3DXCOLOR s, D3DXCOLOR e, float p)
{
D3DMATERIAL9 material;
material.Ambient = a;
material.Diffuse = d;
material.Specular = s;
material.Emissive = e;
material.Power = p;
return material;
}