您的位置:首页 > 其它

龙书笔记(12)

2014-04-21 16:45 162 查看
chap 12 设计一个灵活的Camera类

//主要是创建一个相机类 (Camera)
1.Camera类的设计
右向量(right vector) 上向量(up vector) 观察向量(look vector) 位置向量(position vector)
描述摄像机相对于世界坐标系的位置和朝向,这4个向量描述的摄像机可以进行6中变换
(1) 绕right向量旋转,
俯仰pitch
(2) 绕up向量旋转,
偏航yaw
(3) 绕look向量旋转,
滚动roll
(4) 沿right移动,
扫视strafe(我理解的就是左右移动)
(5) 沿up移动,
升降fly
(6) 沿look移动,
平动forward(我理解的就是前进和后退)
实现:
class Camera
{
public:
enum CameraType( LANDOBJECT, AIRCRAFT );

Camera();
Camera(CameraType cameraType);
~Camera();

void strafe(float units);
void fly(float units);
void walk(float units);

void pitch(float angle);
void yaw(float angle);
void roll(float angle);

void getViewMatrix(D3DXMATRIX *V);					//有一个专门的计算方式
void setCameraType(CameraType *cameratype);
void getPosition(D3DXVECTOR3 *pos);
void setPosition(D3DXVECTOR3 *pos);
void getRight(D3DXVECTOR3 *right);
void getUp(D3DXVECTOR3 *up);
void getLook(D3DXVECTOR3 *look);
private:
CameraType _cameraType;
D3DXVECTOR3 _right;
D3DXVECTOR3 _up;
D3DXVECTOR3 _look;
D3DXVECTOR3 _pos;
};


绕任意轴旋转
D3DXMATRIX *D3DXMatrixRotationAxis(
D3DXMATRIX *pOut,					//输出的矩阵
CONST D3DXVECTOR3 pV,				//围绕的轴
FLOAT Angel							//旋转的角度
);
//eg:
void Camera::yaw(float angle)
{
D3DXMATRIX T;
if(_cameraType == LANDOBJECT)
D3DXMatrixRotationY(&T, angle);
if(_cameraType == AIRCRAFT)
D3DXMatrixRotationAxis(&T, &_up, angle);
D3DXVec3TransformCoord(&_right, &_right, &T);
D3DXVec3TransformCoord(&_look, &_look, &T);
}

d3dUtility.cpp中新添加的方法,这个方法负责管理地面顶点,地面纹理,还有那几个柱子的网格,在不同的时候调用他们会有不同的作用:
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<IDirect3DVertexBuffer9*>(floor);
d3d::Release<IDirect3DTexture9*>(tex);
d3d::Release<ID3DXMesh*>(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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: