DirectX 3D 基本框架(三)

来源:互联网 发布:新加坡地图中文软件 编辑:程序博客网 时间:2024/04/29 03:19

在上次的框架二基础上,再一次进行了扩充 :)

一.d3dUtility.h中

1.定义了2个外接体结构——BoundingBox ,BoundingSphere

  1.     struct BoundingBox    //外接盒
  2.     {
  3.         BoundingBox();
  4.         bool isPointInside(D3DXVECTOR3& p);
  5.         D3DXVECTOR3 _min;
  6.         D3DXVECTOR3 _max;
  7.     };
  8.     struct BoundingSphere    //外接球
  9.     {
  10.         BoundingSphere();
  11.         D3DXVECTOR3 _center;  //球心
  12.         float       _radius;   //半径
  13.     };

与之相关定义了2个极限值(姑且如此叫吧)

  1.     const float INFINITY = FLT_MAX;
  2.     const float EPSILON  = 0.001f;

注意FLT_MAX宏须#include <limits>

 

2.声明了一个绘制基本场景的函数

  1.     bool DrawBasicScene(IDirect3DDevice9* device,float scale);    

二.d3dUtility.cpp中

1.定义了BoundingBox ,BoundingSphere的构造函数及BoundingBox的成员函数。

  1. d3d::BoundingBox::BoundingBox()
  2. {
  3.     // infinite small 
  4.     _min.x = d3d::INFINITY;
  5.     _min.y = d3d::INFINITY;
  6.     _min.z = d3d::INFINITY;
  7.     _max.x = -d3d::INFINITY;
  8.     _max.y = -d3d::INFINITY;
  9.     _max.z = -d3d::INFINITY;
  10. }
  11. bool d3d::BoundingBox::isPointInside(D3DXVECTOR3& p)
  12. {
  13.     if( p.x >= _min.x && p.y >= _min.y && p.z >= _min.z &
  14.         p.x <= _max.x && p.y <= _max.y && p.z <= _max.z )
  15.     {
  16.         return true;
  17.     }
  18.     else
  19.     {
  20.         return false;
  21.     }
  22. }
  23. d3d::BoundingSphere::BoundingSphere()
  24. {
  25.     _radius = 0.0f;
  26. }

2.定义了DrawBasicScene函数。

  1. bool d3d::DrawBasicScene(IDirect3DDevice9* device, float scale)
  2. {
  3.     static IDirect3DVertexBuffer9* floor  = 0;
  4.     static IDirect3DTexture9*      tex    = 0;
  5.     static ID3DXMesh*              pillar = 0;
  6.     HRESULT hr = 0;
  7.     if( device == 0 )
  8.     {
  9.         if( floor && tex && pillar )
  10.         {
  11.             // they already exist, destroy them
  12.             d3d::Release<IDirect3DVertexBuffer9*>(floor);
  13.             d3d::Release<IDirect3DTexture9*>(tex);
  14.             d3d::Release<ID3DXMesh*>(pillar);
  15.         }
  16.     }
  17.     else if( !floor && !tex && !pillar )
  18.     {
  19.         // they don't exist, create them
  20.         device->CreateVertexBuffer(
  21.             6 * sizeof(d3d::Vertex),
  22.             0, 
  23.             d3d::Vertex::FVF,
  24.             D3DPOOL_MANAGED,
  25.             &floor,
  26.             0);
  27.         Vertex* v = 0;
  28.         floor->Lock(0, 0, (void**)&v, 0);
  29.         v[0] = Vertex(-20.0f, -2.5f, -20.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f);
  30.         v[1] = Vertex(-20.0f, -2.5f,  20.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f);
  31.         v[2] = Vertex( 20.0f, -2.5f,  20.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f);
  32.         v[3] = Vertex(-20.0f, -2.5f, -20.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f);
  33.         v[4] = Vertex( 20.0f, -2.5f,  20.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f);
  34.         v[5] = Vertex( 20.0f, -2.5f, -20.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f);
  35.         floor->Unlock();
  36.         D3DXCreateCylinder(device, 0.5f, 0.5f, 5.0f, 20, 20, &pillar, 0);
  37.         D3DXCreateTextureFromFile(
  38.             device,
  39.             "desert.bmp",
  40.             &tex);
  41.     }
  42.     else
  43.     {
  44.         //
  45.         // Pre-Render Setup
  46.         //
  47.         device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
  48.         device->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
  49.         device->SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
  50.         D3DXVECTOR3 dir(0.707f, -0.707f, 0.707f);
  51.         D3DXCOLOR col(1.0f, 1.0f, 1.0f, 1.0f);
  52.         D3DLIGHT9 light = d3d::InitDirectionalLight(&dir, &col);
  53.         device->SetLight(0, &light);
  54.         device->LightEnable(0, true);
  55.         device->SetRenderState(D3DRS_NORMALIZENORMALS, true);
  56.         device->SetRenderState(D3DRS_SPECULARENABLE, true);
  57.         //
  58.         // Render
  59.         //
  60.         D3DXMATRIX T, R, P, S;
  61.         D3DXMatrixScaling(&S, scale, scale, scale);
  62.         // used to rotate cylinders to be parallel with world's y-axis
  63.         D3DXMatrixRotationX(&R, -D3DX_PI * 0.5f);
  64.         // draw floor
  65.         D3DXMatrixIdentity(&T);
  66.         T = T * S;
  67.         device->SetTransform(D3DTS_WORLD, &T);
  68.         device->SetMaterial(&d3d::WHITE_MTRL);
  69.         device->SetTexture(0, tex);
  70.         device->SetStreamSource(0, floor, 0, sizeof(Vertex));
  71.         device->SetFVF(Vertex::FVF);
  72.         device->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 2);
  73.         
  74.         // draw pillars
  75.         device->SetMaterial(&d3d::BLUE_MTRL);
  76.         device->SetTexture(0, 0);
  77.         for(int i = 0; i < 5; i++)
  78.         {
  79.             D3DXMatrixTranslation(&T, -5.0f, 0.0f, -15.0f + (i * 7.5f));
  80.             P = R * T * S;
  81.             device->SetTransform(D3DTS_WORLD, &P);
  82.             pillar->DrawSubset(0);
  83.             D3DXMatrixTranslation(&T, 5.0f, 0.0f, -15.0f + (i * 7.5f));
  84.             P = R * T * S;
  85.             device->SetTransform(D3DTS_WORLD, &P);
  86.             pillar->DrawSubset(0);
  87.         }
  88.     }
  89.     return true;
  90. }

三.增加了一个camera头文件:camera.h

                    // File: camera.h

  1. #ifndef __cameraH__
  2. #define __cameraH__
  3. #include <d3dx9.h>
  4. class Camera
  5. {
  6. public:
  7.     enum CameraType { LANDOBJECT, AIRCRAFT };
  8.     Camera();
  9.     Camera(CameraType cameraType);
  10.     ~Camera();
  11.     void strafe(float units); // left/right
  12.     void fly(float units);    // up/down
  13.     void walk(float units);   // forward/backward
  14.     
  15.     void pitch(float angle); // rotate on right vector
  16.     void yaw(float angle);   // rotate on up vector
  17.     void roll(float angle);  // rotate on look vector
  18.     void getViewMatrix(D3DXMATRIX* V); 
  19.     void setCameraType(CameraType cameraType); 
  20.     void getPosition(D3DXVECTOR3* pos); 
  21.     void setPosition(D3DXVECTOR3* pos); 
  22.     void getRight(D3DXVECTOR3* right);
  23.     void getUp(D3DXVECTOR3* up);
  24.     void getLook(D3DXVECTOR3* look);
  25. private:
  26.     CameraType  _cameraType;
  27.     D3DXVECTOR3 _right;
  28.     D3DXVECTOR3 _up;
  29.     D3DXVECTOR3 _look;
  30.     D3DXVECTOR3 _pos;
  31. };
  32. #endif // __cameraH__

四.其实现文件:camera.cpp

  1. // File: camera.cpp
  2. #include "camera.h"
  3. Camera::Camera()
  4. {
  5.     _cameraType = AIRCRAFT;
  6.     _pos   = D3DXVECTOR3(0.0f, 0.0f, 0.0f);
  7.     _right = D3DXVECTOR3(1.0f, 0.0f, 0.0f);
  8.     _up    = D3DXVECTOR3(0.0f, 1.0f, 0.0f);
  9.     _look  = D3DXVECTOR3(0.0f, 0.0f, 1.0f);
  10. }
  11. Camera::Camera(CameraType cameraType)
  12. {
  13.     _cameraType = cameraType;
  14.     _pos   = D3DXVECTOR3(0.0f, 0.0f, 0.0f);
  15.     _right = D3DXVECTOR3(1.0f, 0.0f, 0.0f);
  16.     _up    = D3DXVECTOR3(0.0f, 1.0f, 0.0f);
  17.     _look  = D3DXVECTOR3(0.0f, 0.0f, 1.0f);
  18. }
  19. Camera::~Camera()
  20. {
  21. }
  22. void Camera::getPosition(D3DXVECTOR3* pos)
  23. {
  24.     *pos = _pos;
  25. }
  26. void Camera::setPosition(D3DXVECTOR3* pos)
  27. {
  28.     _pos = *pos;
  29. }
  30. void Camera::getRight(D3DXVECTOR3* right)
  31. {
  32.     *right = _right;
  33. }
  34. void Camera::getUp(D3DXVECTOR3* up)
  35. {
  36.     *up = _up;
  37. }
  38. void Camera::getLook(D3DXVECTOR3* look)
  39. {
  40.     *look = _look;
  41. }
  42. void Camera::walk(float units)
  43. {
  44.     // move only on xz plane for land object
  45.     if( _cameraType == LANDOBJECT )
  46.         _pos += D3DXVECTOR3(_look.x, 0.0f, _look.z) * units;
  47.     if( _cameraType == AIRCRAFT )
  48.         _pos += _look * units;
  49. }
  50. void Camera::strafe(float units)
  51. {
  52.     // move only on xz plane for land object
  53.     if( _cameraType == LANDOBJECT )
  54.         _pos += D3DXVECTOR3(_right.x, 0.0f, _right.z) * units;
  55.     if( _cameraType == AIRCRAFT )
  56.         _pos += _right * units;
  57. }
  58. void Camera::fly(float units)
  59. {
  60.     // move only on y-axis for land object
  61.     if( _cameraType == LANDOBJECT )
  62.         _pos.y += units;
  63.     if( _cameraType == AIRCRAFT )
  64.         _pos += _up * units;
  65. }
  66. void Camera::pitch(float angle)
  67. {
  68.     D3DXMATRIX T;
  69.     D3DXMatrixRotationAxis(&T, &_right, angle);
  70.     // rotate _up and _look around _right vector
  71.     D3DXVec3TransformCoord(&_up,&_up, &T);
  72.     D3DXVec3TransformCoord(&_look,&_look, &T);
  73. }
  74. void Camera::yaw(float angle)
  75. {
  76.     D3DXMATRIX T;
  77.     // rotate around world y (0, 1, 0) always for land object
  78.     if( _cameraType == LANDOBJECT )
  79.         D3DXMatrixRotationY(&T, angle);
  80.     // rotate around own up vector for aircraft
  81.     if( _cameraType == AIRCRAFT )
  82.         D3DXMatrixRotationAxis(&T, &_up, angle);
  83.     // rotate _right and _look around _up or y-axis
  84.     D3DXVec3TransformCoord(&_right,&_right, &T);
  85.     D3DXVec3TransformCoord(&_look,&_look, &T);
  86. }
  87. void Camera::roll(float angle)
  88. {
  89.     // only roll for aircraft type
  90.     if( _cameraType == AIRCRAFT )
  91.     {
  92.         D3DXMATRIX T;
  93.         D3DXMatrixRotationAxis(&T, &_look,  angle);
  94.         // rotate _up and _right around _look vector
  95.         D3DXVec3TransformCoord(&_right,&_right, &T);
  96.         D3DXVec3TransformCoord(&_up,&_up, &T);
  97.     }
  98. }
  99. void Camera::getViewMatrix(D3DXMATRIX* V)
  100. {
  101.      // 取得取景变换矩阵
  102.  //  _                          _
     //  | rx   ux   dx   0       |
     // |                              |
     // | ry   uy   dy   0      |
     // |                              |
     // | rz   uz   dz   0       |
     // |                              |
     // |  -p.r -p.u  -p.d 1   |
     //  |_                         _|
  103.     D3DXVec3Normalize(&_look, &_look);
  104.     D3DXVec3Cross(&_up, &_look, &_right);
  105.     D3DXVec3Normalize(&_up, &_up);
  106.     D3DXVec3Cross(&_right, &_up, &_look);
  107.     D3DXVec3Normalize(&_right, &_right);
  108.     // Build the view matrix:
  109.     float x = -D3DXVec3Dot(&_right, &_pos);
  110.     float y = -D3DXVec3Dot(&_up, &_pos);
  111.     float z = -D3DXVec3Dot(&_look, &_pos);
  112.     (*V)(0,0) = _right.x; (*V)(0, 1) = _up.x; (*V)(0, 2) = _look.x; (*V)(0, 3) = 0.0f;
  113.     (*V)(1,0) = _right.y; (*V)(1, 1) = _up.y; (*V)(1, 2) = _look.y; (*V)(1, 3) = 0.0f;
  114.     (*V)(2,0) = _right.z; (*V)(2, 1) = _up.z; (*V)(2, 2) = _look.z; (*V)(2, 3) = 0.0f;
  115.     (*V)(3,0) = x;        (*V)(3, 1) = y;     (*V)(3, 2) = z;       (*V)(3, 3) = 1.0f;
  116. }
  117. void Camera::setCameraType(CameraType cameraType)
  118. {
  119.     _cameraType = cameraType;
  120. }

其中摄像机(camera)类提供了一些接口,维护了4个向量——right,up,look,position来表示摄像机在世界坐标系中的位置和朝向。有了这些描述工具就可以轻松实现具有6个自由度的摄像机。

原创粉丝点击