DirectX 3D_实践之在DirectX3D中实现摄像机方位的动态变换

本文介绍了如何在DirectX3D中通过Camera类实现摄像机的动态变换,包括绕3个坐标轴旋转、平移、扫视和升降。通过维护right、up、look和position向量,为飞行模拟器和第一人称视角游戏提供了灵活的摄像机接口。
摘要由CSDN通过智能技术生成

                程序员的身体,众所周知,程序员需要大量的动脑,所以需要大量的供血,进而需要强大的心脏能力。这些无不是一颗定时炸弹,时刻威胁在程序的身体。所以,作为程序员,我们应该珍惜自己的身体。千万记住,你的公司,不会爱惜你的身体的,它只会从你身上进行剥削,榨取剩余价值。所以,我们应该掌握一个度,快到这个度时,忙中偷闲,喝杯茶去。BUG是解不完的,而生命只有一次。为了自己,为了家人,我们应该珍惜,时刻保持警惕。

 

 

              到目前为止,我们已经学会了如果使用D3DXMatrixLookAtLH函数计算出观察矩阵(即取景变换矩阵)。当在某一个固定地点固定摄像机方位时,该函数十分有用,但其对用户接口输入做出响应的移动摄像机来说,就显得力不从心了。本章中,我们实现了一个Camera类,来实现摄像机方位的动态变化,绕3 个坐标轴进行旋转变换,进行平移,扫视,升降。

 

我们先来看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__


再来看DirectX3D.h的代码:

#ifndef __DirectX3DH__
#define __DirectX3DH__

#include <d3dx9.h>
#include <string>
#include <limits>

namespace d3d
{
	bool InitD3D(
		HINSTANCE hInstance,       // [in] Application instance.
		int width, int height,     // [in] Backbuffer dimensions.
		bool windowed,             // [in] Windowed (true)or full screen (false).
		D3DDEVTYPE deviceType,     // [in] HAL or REF
		IDirect3DDevice9** device);// [out]The created device.
	
	int EnterMsgLoop( 
		bool (*ptr_display)(float timeDelta));
	
	LRESULT CALLBACK WndProc(
		HWND hwnd,
		UINT msg, 
		WPARAM wParam,
		LPARAM lParam);
	
	template<class T> void Release(T t)
	{
		if( t )
		{
			t->Release();
			t = 0;
		}
	}
	
	template<class T> void Delete(T t)
	{
		if( t )
		{
			delete t;
			t = 0;
		}
	}
	
	const D3DXCOLOR      WHITE( D3DCOLOR_XRGB(255, 255, 255) );
	const D3DXCOLOR      BLACK( D3DCOLOR_XRGB(  0,   0,   0) );
	const D3DXCOLOR        RED( D3DCOLOR_XRGB(255,   0,   0) );
	const D3DXCOLOR      GREEN( D3DCOLOR_XRGB(  0, 255,   0) );
	const D3DXCOLOR       BLUE( D3DCOLOR_XRGB(  0,   0, 255) );
	const D3DXCOLOR     YELLOW( D3DCOLOR_XRGB(255, 255,   0) );
	const D3DXCOLOR       CYAN( D3DCOLOR_XRGB(  0, 255, 255) );
	const D3DXCOLOR    MAGENTA( D3DCOLOR_XRGB(255,   0, 255) );
	
	//
	// Lights
	//
	
	D3DLIGHT9 InitDirectionalLight(D3DXVECTOR3* direction, D3DXCOLOR* color);
	D3DLIGHT9 InitPointLight(D3DXVECTOR3* position, D3DXCOLOR* color);
	D3DLIGHT9 InitSpotLight(D3DXVECTOR3* position, D3DXVECTOR3* direction, D3DXCOLOR* color);
	
	//
	// Materials
	//
	
	D3DMATERIAL9 InitMtrl(D3DXCOLOR a, D3DXCOLOR d, D3DXCOLOR s, D3DXCOLOR e, float p);
	
	const D3DMATERIAL9 WHITE_MTRL  = InitMtrl(WHITE, WHITE, WHITE, BLACK, 2.0f);
	const D3DMATERIAL9 RED_MTRL    = InitMtrl(RED, RED, RED, BLACK, 2.0f);
	const D3DMATERIAL9 GREEN_MTRL  = InitMtrl(GREEN, GREEN, GREEN, BLACK, 2.0f);
	const D3DMATERIAL9 BLUE_MTRL   = InitMtrl(BLUE, BLUE, BLUE, BLACK, 2.0f);
	const D3DMATERIAL9 YELLOW_MTRL = InitMtrl(YELLOW, YELLOW, YELLOW, BLACK, 2.0f);	

	//
	// 外接体对象
	//
	
	struct BoundingBox
	{
		BoundingBox();
		
		bool isPointInside(D3DXVECTOR3& p);
		
		D3DXVECTOR3 _min;
		D3DXVECTOR3 _max;
	};
	
	struct BoundingSphere
	{
		BoundingSphere();
		
		D3DXVECTOR3 _center;
		float       _radius;
	};

	//
	// Constants
	//
	
	const float INFINITY = FLT_MAX;
	const float EPSILON  = 0.001f;
	// Function references "desert.bmp" internally.  This file must
	// be in the working directory.
	bool DrawBasicScene(
		IDirect3DDevice9* device,// Pass in 0 for cleanup.
		float scale);            // uniform scale 

	struct Vertex
	{
		Vertex(){}
		Vertex(float x, float y, float z, 
			float nx, float ny, float nz, float u, float v)
		{
			_x = x;   _y = y;   _z = z;
			_nx = nx; _ny = ny; _nz = nz;
			_u = u;   _v = v;
		}
		
		float _x, _y, _z, _nx, _ny, _nz, _u, _v;
		
		static const DWORD FVF;
};

	
}




#endif 


再来看camera.cpp的代码:

//
// 
// File: camera.cpp
// 
// Author: Frank Luna (C) All Rights Reserved
//
// System: AMD Athlon 1800+ XP, 512 DDR, Geforce 3, Windows XP, MSVC++ 7.0 
//
// Desc: Defines a camera's position and orientation.
//         
//

#include "camera.h"

/*
这里我们增加了一个Camera类的设计,首先使用了4个摄像机向量,右向量,上向量,观察向量以及位置向量来定义摄像机相对于
世界坐标系的位置和朝向。这些向量实质上为相对世界坐标系描述的摄像机定义了一个局部坐标系。由于右向量,上向量和观察向量定义了
摄像机在世界坐标系中的朝向,有时我们也将这三个向量统称为方向向量。方向向量必须是标准正交的。如果一个向量
集中的向量都彼此正交,并且均为1,则称该向量是标准正交的。前面,我们提到,标准正交矩阵的一个重要性质是其逆矩阵与其转置矩阵相等。
用上述4个向
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值