www.pudn.com > terrainSimple.rar > SSZd3d.cpp


////////////////////////////////////////////////////////////////////////////////////////////////// 
//  
// File: SSZd3d.cpp 
//  
// Author: 哈尔滨顺时针电脑学校 电话:0451-86220686 
// 
// Desc: 顺时针的D3D的一些通用函数及数据结构 
//           
////////////////////////////////////////////////////////////////////////////////////////////////// 
 
#include "SSZd3d.h" 
#include "DXUtil.h" 
 
// vertex formats 
const DWORD d3d::Vertex::FVF = D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_TEX1; 
 
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; 
 
	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 Ambient, D3DXCOLOR Diffuse, D3DXCOLOR Specular, D3DXCOLOR Emissive, float Power) 
{ 
	D3DMATERIAL9 mtrl; 
	mtrl.Ambient  = Ambient; 
	mtrl.Diffuse  = Diffuse; 
	mtrl.Specular = Specular; 
	mtrl.Emissive = Emissive; 
	mtrl.Power    = Power; 
	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			 
			SAFE_RELEASE(floor);			 
			SAFE_RELEASE(tex); 
			SAFE_RELEASE(pillar); 
		} 
	} 
	else if( !floor && !tex && !pillar ) 
	{ 
		// they don't exist, create them 
		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(0.707f, -0.707f, 0.707f); 
		D3DXCOLOR col(1.0f, 1.0f, 1.0f, 1.0f); 
		D3DLIGHT9 light = d3d::InitDirectionalLight(&dir, &col); 
 
		device->SetLight(0, &light); 
		device->LightEnable(0, true); 
		device->SetRenderState(D3DRS_NORMALIZENORMALS, 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); 
 
		// draw pillars 
		device->SetMaterial(&d3d::BLUE_MTRL); 
		device->SetTexture(0, 0); 
		for(int i = 0; i < 5; i++) 
		{ 
			D3DXMatrixTranslation(&T, -5.0f, 0.0f, -15.0f + (i * 7.5f)); 
			P = R * T * S; 
			device->SetTransform(D3DTS_WORLD, &P); 
			pillar->DrawSubset(0); 
 
			D3DXMatrixTranslation(&T, 5.0f, 0.0f, -15.0f + (i * 7.5f)); 
			P = R * T * S; 
			device->SetTransform(D3DTS_WORLD, &P); 
			pillar->DrawSubset(0); 
		} 
	} 
	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); 
} 
 
float d3d::Lerp(float a, float b, float t) 
{ 
	return a - (a*t) + (b*t); 
}