在上次的框架二基础上,再一次进行了扩充 :)
一.d3dUtility.h中
1.定义了2个外接体结构——BoundingBox ,BoundingSphere
- struct BoundingBox //外接盒
- {
- BoundingBox();
- bool isPointInside(D3DXVECTOR3& p);
- D3DXVECTOR3 _min;
- D3DXVECTOR3 _max;
- };
- struct BoundingSphere //外接球
- {
- BoundingSphere();
- D3DXVECTOR3 _center; //球心
- float _radius; //半径
- };
与之相关定义了2个极限值(姑且如此叫吧)
- const float INFINITY = FLT_MAX;
- const float EPSILON = 0.001f;
注意FLT_MAX宏须#include <limits>
2.声明了一个绘制基本场景的函数
- bool DrawBasicScene(IDirect3DDevice9* device,float scale);
二.d3dUtility.cpp中
1.定义了BoundingBox ,BoundingSphere的构造函数及BoundingBox的成员函数。
- 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;
- }
2.定义了DrawBasicScene函数。
- 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;
- }
三.增加了一个camera头文件:camera.h
// File: camera.h
- #ifndef __cameraH__
- #define __cameraH__
- #include <d3dx9.h>
- class Camera
- {
- public:
- enum CameraType { LANDOBJECT, AIRCRAFT };
- Camera();
- Camera(CameraType cameraType);
- ~Camera();
- void strafe(float units); // left/right
- void fly(float units); // up/down
- void walk(float units); // forward/backward
- void pitch(float angle); // rotate on right vector
- void yaw(float angle); // rotate on up vector
- void roll(float angle); // rotate on look vector
- 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;
- };
- #endif // __cameraH__
四.其实现文件:camera.cpp
- // File: camera.cpp
- #include "camera.h"
- Camera::Camera()
- {
- _cameraType = AIRCRAFT;
- _pos = D3DXVECTOR3(0.0f, 0.0f, 0.0f);
- _right = D3DXVECTOR3(1.0f, 0.0f, 0.0f);
- _up = D3DXVECTOR3(0.0f, 1.0f, 0.0f);
- _look = D3DXVECTOR3(0.0f, 0.0f, 1.0f);
- }
- Camera::Camera(CameraType cameraType)
- {
- _cameraType = cameraType;
- _pos = D3DXVECTOR3(0.0f, 0.0f, 0.0f);
- _right = D3DXVECTOR3(1.0f, 0.0f, 0.0f);
- _up = D3DXVECTOR3(0.0f, 1.0f, 0.0f);
- _look = D3DXVECTOR3(0.0f, 0.0f, 1.0f);
- }
- Camera::~Camera()
- {
- }
- void Camera::getPosition(D3DXVECTOR3* pos)
- {
- *pos = _pos;
- }
- void Camera::setPosition(D3DXVECTOR3* pos)
- {
- _pos = *pos;
- }
- void Camera::getRight(D3DXVECTOR3* right)
- {
- *right = _right;
- }
- void Camera::getUp(D3DXVECTOR3* up)
- {
- *up = _up;
- }
- void Camera::getLook(D3DXVECTOR3* look)
- {
- *look = _look;
- }
- void Camera::walk(float units)
- {
- // move only on xz plane for land object
- if( _cameraType == LANDOBJECT )
- _pos += D3DXVECTOR3(_look.x, 0.0f, _look.z) * units;
- if( _cameraType == AIRCRAFT )
- _pos += _look * units;
- }
- void Camera::strafe(float units)
- {
- // move only on xz plane for land object
- if( _cameraType == LANDOBJECT )
- _pos += D3DXVECTOR3(_right.x, 0.0f, _right.z) * units;
- if( _cameraType == AIRCRAFT )
- _pos += _right * units;
- }
- void Camera::fly(float units)
- {
- // move only on y-axis for land object
- if( _cameraType == LANDOBJECT )
- _pos.y += units;
- if( _cameraType == AIRCRAFT )
- _pos += _up * units;
- }
- void Camera::pitch(float angle)
- {
- D3DXMATRIX T;
- D3DXMatrixRotationAxis(&T, &_right, angle);
- // rotate _up and _look around _right vector
- D3DXVec3TransformCoord(&_up,&_up, &T);
- D3DXVec3TransformCoord(&_look,&_look, &T);
- }
- void Camera::yaw(float angle)
- {
- D3DXMATRIX T;
- // rotate around world y (0, 1, 0) always for land object
- if( _cameraType == LANDOBJECT )
- D3DXMatrixRotationY(&T, angle);
- // rotate around own up vector for aircraft
- if( _cameraType == AIRCRAFT )
- D3DXMatrixRotationAxis(&T, &_up, angle);
- // rotate _right and _look around _up or y-axis
- D3DXVec3TransformCoord(&_right,&_right, &T);
- D3DXVec3TransformCoord(&_look,&_look, &T);
- }
- void Camera::roll(float angle)
- {
- // only roll for aircraft type
- if( _cameraType == AIRCRAFT )
- {
- D3DXMATRIX T;
- D3DXMatrixRotationAxis(&T, &_look, angle);
- // rotate _up and _right around _look vector
- D3DXVec3TransformCoord(&_right,&_right, &T);
- D3DXVec3TransformCoord(&_up,&_up, &T);
- }
- }
- void Camera::getViewMatrix(D3DXMATRIX* V)
- {
- // 取得取景变换矩阵
- // _ _
// | rx ux dx 0 |
// | |
// | ry uy dy 0 |
// | |
// | rz uz dz 0 |
// | |
// | -p.r -p.u -p.d 1 |
// |_ _| - D3DXVec3Normalize(&_look, &_look);
- D3DXVec3Cross(&_up, &_look, &_right);
- D3DXVec3Normalize(&_up, &_up);
- D3DXVec3Cross(&_right, &_up, &_look);
- D3DXVec3Normalize(&_right, &_right);
- // Build the view matrix:
- float x = -D3DXVec3Dot(&_right, &_pos);
- float y = -D3DXVec3Dot(&_up, &_pos);
- float z = -D3DXVec3Dot(&_look, &_pos);
- (*V)(0,0) = _right.x; (*V)(0, 1) = _up.x; (*V)(0, 2) = _look.x; (*V)(0, 3) = 0.0f;
- (*V)(1,0) = _right.y; (*V)(1, 1) = _up.y; (*V)(1, 2) = _look.y; (*V)(1, 3) = 0.0f;
- (*V)(2,0) = _right.z; (*V)(2, 1) = _up.z; (*V)(2, 2) = _look.z; (*V)(2, 3) = 0.0f;
- (*V)(3,0) = x; (*V)(3, 1) = y; (*V)(3, 2) = z; (*V)(3, 3) = 1.0f;
- }
- void Camera::setCameraType(CameraType cameraType)
- {
- _cameraType = cameraType;
- }
其中摄像机(camera)类提供了一些接口,维护了4个向量——right,up,look,position来表示摄像机在世界坐标系中的位置和朝向。有了这些描述工具就可以轻松实现具有6个自由度的摄像机。