DirectX11 学习笔记7 - 支持自由移动的摄像机
如今将又一次制定一个camera摄像机。能够自由移动。
比方前进 后退,上游 下潜。 各个方向渲染之类的。
首先设置按键。
这个时候须要在
XWindow.h 里面
bool XWindow::frame()
{
//推断是否按下ESC键
if(x_input->isKeyDown(VK_ESCAPE))
return false;
//假设A,S,D,W,Q,E,Z,X,C键按下。移动摄像机
if(GetAsyncKeyState('W') & 0x8000) //前后
x_graphics->x_camera->walk(-0.1f);
if(GetAsyncKeyState('S') & 0x8000)
x_graphics->x_camera->walk(0.1f);
if(GetAsyncKeyState('A') & 0x8000) //左右
x_graphics->x_camera->strafe(-0.1f);
if(GetAsyncKeyState('D') & 0x8000)
x_graphics->x_camera->strafe(0.1f);
//if(GetAsyncKeyState('Q') & 0x8000) //上下
// x_graphics->x_camera->fly(-0.1f);
//if(GetAsyncKeyState('E') & 0x8000)
// x_graphics->x_camera->fly(0.1f);
//if(GetAsyncKeyState('Z') & 0x8000)
// x_graphics->x_camera->pitch(PI/180);
//if(GetAsyncKeyState('X') & 0x8000)
// x_graphics->x_camera->yaw(PI/180);
//if(GetAsyncKeyState('C') & 0x8000)
// x_graphics->x_camera->roll(PI/180); //动画。旋转摄像机
//x_graphics->x_camera->roll(PI/180); //開始渲染
return x_graphics->frame();
}
加入一些按键。假设报错的话, 可能是x_camera 在XGraphics.h 类里面是私有的,能够设置成公有
private:
bool render();
public:
XCamera *x_camera;//摄像机
private:
XD3Device *x_d3d;//3D设备
XModel *x_model;//模型
XShader *x_shader;//渲染器
HWND hwnd;
然后非常easy吧
然后就是改动摄像机了
先上代码再解说吧
#pragma once
#include <xnamath.h>
class XCamera
{
public:
enum CameraType { LANDOBJECT, AIRCRAFT };
XCamera();
void strafe(float units); // l左右
//void fly(float units); // 上下
void walk(float units); // 前后 //void pitch(float angle); // 旋转view坐标系right向量
//void yaw(float angle); // 旋转up向量
//void roll(float angle); // 旋转look向量 void getViewMatrix(XMMATRIX& V);
void setCameraType(CameraType cameraType);
void getPosition(XMFLOAT3* pos);
void setPosition(XMFLOAT3* pos); void getRight(XMFLOAT3* right);
void getUp(XMFLOAT3* up);
void getLook(XMFLOAT3* look);
private:
CameraType _cameraType;
XMFLOAT3 _right,_up,_look,_pos;
};
XCamera::XCamera()
{
_cameraType=AIRCRAFT;
_pos=XMFLOAT3(0.0f, 0.0f, -10.0f);
_right=XMFLOAT3(1.0f,0.0f,0.0f);
_up=XMFLOAT3(0.0f,1.0f,0.0f);
_look=XMFLOAT3(0.0f,0.0f,1.0f);
}
void XCamera::getPosition(XMFLOAT3* pos)
{
*pos = _pos;
} void XCamera::setPosition(XMFLOAT3* pos)
{
_pos = *pos;
} void XCamera::getRight(XMFLOAT3* right)
{
*right = _right;
} void XCamera::getUp(XMFLOAT3* up)
{
*up = _up;
} void XCamera::getLook(XMFLOAT3* look)
{
*look = _look;
} //行走,沿着摄像机观察方向的移动
void XCamera::walk(float units)
{
XMVECTOR vpos,vlook;
vpos=XMLoadFloat3(&_pos);
vlook=XMLoadFloat3(&_look);
// 仅在x,z平面移动
if( _cameraType == LANDOBJECT )
{
vpos += XMVectorSet(_look.x, 0.0f, _look.z,0)*units;
}
if( _cameraType == AIRCRAFT )
vpos += vlook * units;
XMStoreFloat3(&_pos,vpos);
} //扫视。是指保持观察方向不变,沿向量right方向从一边平移到还有一边
void XCamera::strafe(float units)
{
XMVECTOR vpos,vright;
vpos=XMLoadFloat3(&_pos);
vright=XMLoadFloat3(&_right);
// 仅在x,z平面移动
if( _cameraType == LANDOBJECT )
vpos += XMVectorSet(_right.x, 0.0f, _right.z,0.0f) * units; if( _cameraType == AIRCRAFT )
vpos += vright * units;
XMStoreFloat3(&_pos,vpos);
}/*
//飞行模式,升降,指沿着向量up方向的移动
void XCamera::fly(float units)
{
// 仅在y轴移动
if( _cameraType == LANDOBJECT )
_pos.y += units; if( _cameraType == AIRCRAFT )
_pos += _up * units;
} void XCamera::pitch(float angle)
{
XMMATRIX T;
T=XMMatrixRotationAxis( _right, angle); // 绕着right向量。旋转up和look
_up=XMVector3TransformCoord(_up,_up, T);
_look=XMVector3TransformCoord(_look, T);
} void XCamera::yaw(float angle)
{
D3DXMATRIX T; //对LANDOBJECT,总是绕着(0,1,0)旋转。 if( _cameraType == LANDOBJECT )
T=XMMatrixRotationY(angle); //对于aircraft,绕着up向量旋转
if( _cameraType == AIRCRAFT )
T=XMMatrixRotationAxis(_up, angle); // 绕着up或者y轴,旋转right和look
_right=XMVector3TransformCoord(_right, T);
_look=XMVector3TransformCoord(_look, T);
} void XCamera::roll(float angle)
{
//仅仅对aircraft模式才左roll旋转
if( _cameraType == AIRCRAFT )
{
D3DXMATRIX T;
T=XMMatrixRotationAxis(_look, angle); // 绕着look向量,旋转up和right
_right=XMVector3TransformCoord(_right, T);
_up=XMVector3TransformCoord(_up, T);
}
}
*/
void XCamera::getViewMatrix(XMMATRIX &V)
{
XMVECTOR vlook,vup,vright,vpos;
vpos=XMLoadFloat3(&_pos);
vlook=XMLoadFloat3(&_look);
vup=XMLoadFloat3(&_up);
vright=XMLoadFloat3(&_right);
// 保持view局部坐标系,各轴的彼此正交
vlook=XMVector3Normalize(vlook);
// look X right
vup=XMVector3Cross(vlook, vright);
vup=XMVector3Normalize(vup); vright=XMVector3Cross(vup, vlook);
vright=XMVector3Normalize(vright);
V=XMMatrixLookAtLH( vpos,vlook, vup);
// 生成view矩阵:
//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 XCamera::setCameraType(CameraType cameraType)
{
_cameraType = cameraType;
}
凝视掉的地方是一个坑。为什么呢。
以下就要讲XMVECTOR 和XMFloat3的差别
前者是向量。后者就是一个点结构
前者支持各种运算。
差 点 乘 加减
后者 仅仅能赋值啊什么的。
是不是特别奇怪。
由于XMVECTOR
看源代码
// Vector intrinsic: Four 32 bit floating point components aligned on a 16 byte
// boundary and mapped to hardware vector registers
#if defined(_XM_SSE_INTRINSICS_) && !defined(_XM_NO_INTRINSICS_)
typedef __m128 XMVECTOR;
#else
128位懂了吧。不能随便玩, 不然会报错 涉及到对齐问题
上节说了。全局变量和局部变量能够用XMVECTOR 可是类变量不建议用
偏偏这个摄像机是类变量。
作死啊。仅仅有设成XMFloat3了
看源代码
// 3D Vector; 32 bit floating point components
typedef struct _XMFLOAT3
{
FLOAT x;
FLOAT y;
FLOAT z; #ifdef __cplusplus _XMFLOAT3() {};
_XMFLOAT3(FLOAT _x, FLOAT _y, FLOAT _z) : x(_x), y(_y), z(_z) {};
_XMFLOAT3(CONST FLOAT *pArray); _XMFLOAT3& operator= (CONST _XMFLOAT3& Float3); #endif // __cplusplus
32位的 仅仅能赋值 怎么玩 怎么玩
上面摄像机类加凝视了的函数是之前悲剧了的,我以为Float能够做运算。结果悲剧了。
后来查了一下。 能够用一个转换
XMVECTOR vpos,vright;
vpos=XMLoadFloat3(&_pos);
vright=XMLoadFloat3(&_right);
// 仅在x,z平面移动
if( _cameraType == LANDOBJECT )
vpos += XMVectorSet(_right.x, 0.0f, _right.z,0.0f) * units; if( _cameraType == AIRCRAFT )
vpos += vright * units;
XMStoreFloat3(&_pos,vpos);
看懂了吗 看懂了吗。 先load 把float装到vector局部变量 然后进行运算
运算完毕后 再store
是不是非常烦
是不是
没办法。
眼下我仅仅会这样弄。你嫌烦 直接全局变量吧。
或者回归dx10math.h
废话不说 效果图。
仅仅改了walk函数。 其它自己改改吧,锻炼下自己
//(*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;
对了还有上面这个。原教程是直接这样算的一个矩阵,麻烦吧。
麻烦吧。 懂不起含义了吧 快看龙书就懂了。
懂了之后怎么办。还敲这么多??
V=XMMatrixLookAtLH( vpos,vlook, vup);
一句话搞定。就不要造轮子了
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvY3EzNjExMDYzMDY=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="">
DirectX11 学习笔记7 - 支持自由移动的摄像机的更多相关文章
- Directx11学习笔记【十九】 摄像机的实现
本文由zhangbaochong原创,转载请注明出处:http://www.cnblogs.com/zhangbaochong/p/5785100.html 之前为了方便观察场景,我们采用的方法是鼠标 ...
- Directx11学习笔记【八】 龙书D3DApp的实现
原文:Directx11学习笔记[八] 龙书D3DApp的实现 directx11龙书中的初始化程序D3DApp跟我们上次写的初始化程序大体一致,只是包含了计时器的内容,而且使用了深度模板缓冲. D3 ...
- Directx11学习笔记【二十二】 用高度图实现地形
本文由zhangbaochong原创,转载请注明出处http://www.cnblogs.com/zhangbaochong/p/5827714.html 在前面我们曾经实现过简单的地形(Direct ...
- Directx11学习笔记【二】 将HelloWin封装成类
我们把上一个教程的代码封装到一个类中来方便以后的使用. 首先新建一个空工程叫做MyHelloWin,添加一个main.cpp文件,然后新建一个类叫做MyWindow,将于窗体有关的操作封装到里面 My ...
- Directx11学习笔记【一】 最简单的windows程序HelloWin
声明:本系列教程代码有部分来自dx11龙书及dx11游戏编程入门两本书,后面不再说明 首先,在vs2013中创建一个空的解决方案Dx11Demo,以后的工程都会放在这个解决方案下面.然后创建一个win ...
- SQL反模式学习笔记6 支持可变属性【实体-属性-值】
目标:支持可变属性 反模式:使用泛型属性表.这种设计成为实体-属性-值(EAV),也可叫做开放架构.名-值对. 优点:通过增加一张额外的表,可以有以下好处 (1)表中的列很少: (2)新增属性时,不需 ...
- Directx11学习笔记【二十一】 封装键盘鼠标响应类
原文:Directx11学习笔记[二十一] 封装键盘鼠标响应类 摘要: 本文由zhangbaochong原创,转载请注明出处:http://www.cnblogs.com/zhangbaochong/ ...
- Directx11学习笔记【九】 3D渲染管线
原文:Directx11学习笔记[九] 3D渲染管线 原文地址:http://blog.csdn.net/bonchoix/article/details/8298116 3D图形学研究的基本内容,即 ...
- Directx11学习笔记【十七】纹理贴图
本文由zhangbaochong原创,转载请注明出处http://www.cnblogs.com/zhangbaochong/p/5596180.html 在之前的例子中,我们实现了光照和材质使得场景 ...
随机推荐
- 删数问题(Noip1994)
1321:[例6.3]删数问题(Noip1994) 时间限制: 1000 ms 内存限制: 65536 KB提交数: 5127 通过数: 1595 [题目描述] 输入一个高精度 ...
- ubuntu apt-update NO_PUBKEY 40976EAF437D05B5 NO_PUBKEY 3B4FE6ACC0B21F32
Fetched 28.1 MB in 11s (2344 kB/s) W: GPG error: http://archive.canonical.com xenial Release: The fo ...
- ubuntu 16.04 数据库mysql安装与管理
1.安装mysql的客户端与服务器端 $>sudo apt-get install mysql-server mysql-client 2.管理服务 1.启动 $>sudo service ...
- UVA 230 Borrowers (STL 行读入的处理 重载小于号)
题意: 输入若干书籍和作者名字,然后先按作者名字升序排列,再按标题升序排列,然后会有3种指令,BORROW,RETURN, SHELVE. BORROW 和 RETURN 都会带有一个书名在后面,如: ...
- ppt_旋转抽奖_制作步骤
1 ppt制作抽奖转盘 插入饼状图,更改比例,更改颜色(一般选取相邻的一组颜色匹配比较好看): 插入竖文本框,编辑每一个部分为特等奖.一等奖.二等奖.三等奖: 全部选中,ctrl+G组合: 添加陀螺旋 ...
- xcap发包工具的简单使用2(发送报文)
上一篇文章介绍了如何构造报文,现在简单讲一下发送报文的步骤 1.获取接口列表 点击主界面工具栏中的“刷新列表”按钮(或对应菜单“interface->Reference interfaces”) ...
- Jmeter&Ant构建自动化测试平台
JMeter是一个软件,使负载测试或业绩为导向的业务(功能)测试不同的协议或技术. Apache软件基金会的Stefano Mazzocchi JMeter的最初的开发.他写道:它主要对 Apache ...
- JDBC--JAVA数据库连接相关
JDBC API提供了以下接口和类: DriverManager: 这个类管理数据库驱动程序的列表.确定内容是否符合从Java应用程序使用的通信子协议正确的数据库驱动程序的连接请求.识别JDBC在一定 ...
- HDU 3537 Mock Turtles型翻硬币游戏
题目大意: 每次可以翻1个或者2个或者3个硬币,但要保证最右边的那个硬币是正面的,直到不能操作为输,这题目还有说因为主人公感情混乱可能描述不清会有重复的硬币说出,所以要去重 这是一个Mock Turt ...
- [luoguP1019] 单词接龙(DFS)
传送门 不知为什么,判断全部包含反而A不了,不判断反而A了,╮(╯▽╰)╭ 代码 #include <cstdio> #include <iostream> #define m ...