DirectX入门之添加移动摄像机

来源:互联网 发布:c语言标识符可分为 编辑:程序博客网 时间:2024/05/19 08:36

前言,在上篇三角形基础上,我准备增设一个可移动的摄像机。这样我们就可以为所欲为地看三角形了。

运行截图

初始:
这里写图片描述
前后移动:
这里写图片描述
左右平动
这里写图片描述
滚动
这里写图片描述

俯仰
这里写图片描述

实现流程图

这里写图片描述

摄像机用法

一、创建摄像机全局变量

//三种方法创建摄像机Camera TheCamera(Camera::AIRCRAFT);Camera TheCamera(Camera::LANDOBJECT);Camera TheCamera();

二、在Display()函数中设置控制摄像机移动的按键

        //可移动的摄像机        if (::GetAsyncKeyState('W') & 0x8000f)            TheCamera.walk(4.0f * timeDelta);        if (::GetAsyncKeyState('S') & 0x8000f)            TheCamera.walk(-4.0f * timeDelta);        if (::GetAsyncKeyState('A') & 0x8000f)            TheCamera.strafe(-4.0f * timeDelta);        if (::GetAsyncKeyState('D') & 0x8000f)            TheCamera.strafe(4.0f * timeDelta);        if (::GetAsyncKeyState('R') & 0x8000f)            TheCamera.fly(4.0f * timeDelta);        if (::GetAsyncKeyState('F') & 0x8000f)            TheCamera.fly(-4.0f * timeDelta);        if (::GetAsyncKeyState(VK_UP) & 0x8000f)            TheCamera.pitch(1.0f * timeDelta);        if (::GetAsyncKeyState(VK_DOWN) & 0x8000f)            TheCamera.pitch(-1.0f * timeDelta);        if (::GetAsyncKeyState(VK_LEFT) & 0x8000f)            TheCamera.yaw(-1.0f * timeDelta);        if (::GetAsyncKeyState(VK_RIGHT) & 0x8000f)            TheCamera.yaw(1.0f * timeDelta);        if (::GetAsyncKeyState('N') & 0x8000f)            TheCamera.roll(1.0f * timeDelta);        if (::GetAsyncKeyState('M') & 0x8000f)            TheCamera.roll(-1.0f * timeDelta);

三、进行取景变换
取景变换:每个物体创建时都是包含一个单独坐标系(局部坐标系。然后将这些创建好的物体添加到世界中(世界坐标系)。添加摄像机后,物体又位于摄像机的坐标系中(观察坐标系)。这里通过Device->SetTransform(D3DTS_VIEW, &V);函数将世界坐标系的物体变换到观察者坐标系中。

        D3DXMATRIX V;        TheCamera.getViewMatrix(&V);        Device->SetTransform(D3DTS_VIEW, &V);

摄像机实现代码

camera.h

#pragma once#include "stdafx.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

#include "stdafx.h"#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){    // Keep camera's axes orthogonal to eachother    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;}