www.pudn.com > snow.rar > d3dUtility.cpp


 
#include "d3dUtility.h" 
 
// vertex formats 
const DWORD d3d::Vertex::FVF = D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_TEX1; 
 
 
bool d3d::InitD3D( 
	HINSTANCE hInstance, 
	int width, int height, 
	bool windowed, 
	D3DDEVTYPE deviceType, 
	IDirect3DDevice9** device) 
{ 
	// 
	// Create the main application window. 
	// 
 
	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 = "Direct3D9App"; 
 
	if( !RegisterClass(&wc) )  
	{ 
		::MessageBox(0, "RegisterClass() - FAILED", 0, 0); 
		return false; 
	} 
		 
	HWND hwnd = 0; 
	hwnd = ::CreateWindow("Direct3D9App", "¶¬ΘΥ",  
		WS_EX_TOPMOST|WS_EX_WINDOWEDGE  , 
		120, 120, width, height, 
		0 /*parent hwnd*/, 0 /* menu */, hInstance, 0 /*extra*/);  
 
	if( !hwnd ) 
	{ 
		::MessageBox(0, "CreateWindow() - FAILED", 0, 0); 
		return false; 
	} 
 
	::ShowWindow(hwnd, SW_SHOW); 
	::UpdateWindow(hwnd); 
 
	// 
	// Init D3D:  
	// 
 
	HRESULT hr = 0; 
 
	// Step 1: Create the IDirect3D9 object. 
 
	IDirect3D9* d3d9 = 0; 
    d3d9 = Direct3DCreate9(D3D_SDK_VERSION); 
 
    if( !d3d9 ) 
	{ 
		::MessageBox(0, "Direct3DCreate9() - FAILED", 0, 0); 
		return false; 
	} 
 
	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; 
 
 
	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                   = 1; 
	d3dpp.EnableAutoDepthStencil     = true;  
	d3dpp.AutoDepthStencilFormat     = D3DFMT_D24S8; 
	d3dpp.Flags                      = 0; 
	d3dpp.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT; 
	d3dpp.PresentationInterval       = D3DPRESENT_INTERVAL_IMMEDIATE; 
 
 
	hr = d3d9->CreateDevice( 
		D3DADAPTER_DEFAULT, // primary adapter 
		deviceType,         // device type 
		hwnd,               // window associated with device 
		vp,                 // vertex processing 
	    &d3dpp,             // present parameters 
	    device);            // return created device 
 
	if( FAILED(hr) ) 
	{ 
		d3dpp.AutoDepthStencilFormat = D3DFMT_D16; 
		 
		hr = d3d9->CreateDevice( 
			D3DADAPTER_DEFAULT, 
			deviceType, 
			hwnd, 
			vp, 
			&d3dpp, 
			device); 
 
		if( FAILED(hr) ) 
		{ 
			d3d9->Release(); // done with d3d9 object 
			::MessageBox(0, "CreateDevice() - FAILED", 0, 0); 
			return false; 
		} 
	} 
 
	d3d9->Release(); // done with d3d9 object 
	 
	return true; 
} 
 
 
int d3d::EnterMsgLoop( 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::InitDirectionalLight(D3DXVECTOR3* direction, D3DXCOLOR* color) 
{ 
	D3DLIGHT9 light; 
	::ZeroMemory(&light, sizeof(light)); 
 
	light.Type      = D3DLIGHT_DIRECTIONAL; 
	light.Ambient   = *color * 0.4f; 
	light.Diffuse   = *color; 
	light.Specular  = *color * 0.6f; 
	light.Direction = *direction; 
    light.Falloff = 10000; 
	return light; 
} 
 
D3DLIGHT9 d3d::InitPointLight(D3DXVECTOR3* position, D3DXCOLOR* color) 
{ 
	D3DLIGHT9 light; 
	::ZeroMemory(&light, sizeof(light)); 
 
	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::InitSpotLight(D3DXVECTOR3* position, D3DXVECTOR3* direction, D3DXCOLOR* color) 
{ 
	D3DLIGHT9 light; 
	::ZeroMemory(&light, sizeof(light)); 
 
	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::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; 
} 
 
d3d::BoundingBox::BoundingBox() 
{ 
	// infinite small  
	_min.x = d3d::INFINITY; 
	_min.y = d3d::INFINITY; 
	_min.z = d3d::INFINITY; 
 
	_max.x = -d3d::INFINITY; 
	_max.y = -d3d::INFINITY; 
	_max.z = -d3d::INFINITY; 
} 
 
bool d3d::BoundingBox::isPointInside(D3DXVECTOR3& p) 
{ 
	if( p.x >= _min.x && p.y >= _min.y && p.z >= _min.z && 
		p.x <= _max.x && p.y <= _max.y && p.z <= _max.z ) 
	{ 
		return true; 
	} 
	else 
	{ 
		return false; 
	} 
} 
 
d3d::BoundingSphere::BoundingSphere() 
{ 
	_radius = 0.0f; 
} 
 
bool d3d::DrawBasicScene(IDirect3DDevice9* device, float scale) 
{ 
	static IDirect3DVertexBuffer9* floor  = 0; 
	static IDirect3DTexture9*      tex    = 0; 
	static ID3DXMesh*              pillar = 0; 
 
	HRESULT hr = 0; 
 
	if( device == 0 ) 
	{ 
		if( floor && tex && pillar ) 
		{ 
			// they already exist, destroy them 
			d3d::Release(floor); 
			d3d::Release(tex); 
			d3d::Release(pillar); 
		} 
	} 
	else if( !floor && !tex && !pillar ) 
	{ 
		device->CreateVertexBuffer( 
			6 * sizeof(d3d::Vertex), 
			0,  
			d3d::Vertex::FVF, 
			D3DPOOL_MANAGED, 
			&floor, 
			0); 
 
		Vertex* v = 0; 
		floor->Lock(0, 0, (void**)&v, 0); 
 
		v[0] = Vertex(-20.0f, -2.5f, -20.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f); 
		v[1] = Vertex(-20.0f, -2.5f,  20.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f); 
		v[2] = Vertex( 20.0f, -2.5f,  20.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f); 
 
		v[3] = Vertex(-20.0f, -2.5f, -20.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f); 
		v[4] = Vertex( 20.0f, -2.5f,  20.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f); 
		v[5] = Vertex( 20.0f, -2.5f, -20.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f); 
 
		floor->Unlock(); 
 
		D3DXCreateCylinder(device, 0.5f, 0.5f, 5.0f, 20, 20, &pillar, 0); 
 
		D3DXCreateTextureFromFile(device,"desert.bmp",&tex); 
	} 
	else 
	{ 
		// 
		// Pre-Render Setup 
		// 
		device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); 
		device->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR); 
		device->SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_POINT); 
 
		D3DXVECTOR3 dir(15.707f, 15.707f, -5.707f); 
       	D3DXCOLOR col(2.5f, 2.5f, 2.5f, 1.0f); 
		D3DLIGHT9 light = d3d::InitDirectionalLight(&dir, &col); 
		device->SetLight(0, &light); 
		device->LightEnable(0, true);	 
		device->SetRenderState(D3DRS_DIFFUSEMATERIALSOURCE, true); 
		device->SetRenderState(D3DRS_SPECULARENABLE, true); 
 
		// 
		// Render 
		// 
 
		D3DXMATRIX T, R, P, S; 
 
		D3DXMatrixScaling(&S, scale, scale, scale); 
 
		// used to rotate cylinders to be parallel with world's y-axis 
		D3DXMatrixRotationX(&R, -D3DX_PI * 0.5f); 
 
		// draw floor 
		D3DXMatrixIdentity(&T); 
		T = T * S; 
		device->SetTransform(D3DTS_WORLD, &T); 
		device->SetMaterial(&d3d::WHITE_MTRL); 
		device->SetTexture(0, tex); 
		device->SetStreamSource(0, floor, 0, sizeof(Vertex)); 
		device->SetFVF(Vertex::FVF); 
		device->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 2); 
	 
	} 
	return true; 
} 
 
float d3d::GetRandomFloat(float lowBound, float highBound) 
{ 
	if( lowBound >= highBound ) // bad input 
		return lowBound; 
 
	// get random float in [0, 1] interval 
	float f = (rand() % 10000) * 0.0001f;  
 
	// return float in [lowBound, highBound] interval.  
	return (f * (highBound - lowBound)) + lowBound;  
} 
 
void d3d::GetRandomVector( 
	  D3DXVECTOR3* out, 
	  D3DXVECTOR3* min, 
	  D3DXVECTOR3* max) 
{ 
	out->x = GetRandomFloat(min->x, max->x); 
	out->y = GetRandomFloat(min->y, max->y); 
	out->z = GetRandomFloat(min->z, max->z); 
} 
 
DWORD d3d::FtoDw(float f) 
{ 
	return *((DWORD*)&f); 
}