龙书笔记(12)

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值