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);
}