DirectX11 学习笔记7 - 支持自由移动的摄像机
2014-10-09 00:25
423 查看
现在将重新制定一个camera摄像机。可以自由移动。
比如前进 后退,上游 下潜。 各个方向渲染之类的。
首先设置按键。
这个时候需要在
XWindow.h 里面
然后很简单吧
然后就是修改摄像机了
先上代码再讲解吧
注释掉的地方是一个坑。为什么呢。
下面就要讲XMVECTOR 和XMFloat3的区别
前者是向量。后者就是一个点结构
前者支持各种运算。差 点 乘 加减
后者 只能赋值啊什么的。是不是特别奇怪。因为XMVECTOR
看源码
128位懂了吧。不能随便玩, 不然会报错 涉及到对齐问题
上节说了,全局变量和局部变量可以用XMVECTOR 但是类变量不建议用
偏偏这个摄像机是类变量。作死啊。只有设成XMFloat3了
看源码
32位的 只能赋值 怎么玩 怎么玩
上面摄像机类加注释了的函数是之前悲剧了的,我以为Float可以做运算。结果悲剧了。
后来查了一下。 可以用一个转换
看懂了吗 看懂了吗。 先load 把float装到vector局部变量 然后进行运算
运算完成后 再store
是不是很烦
是不是
没办法。目前我只会这样弄。你嫌烦 直接全局变量吧。或者回归dx10math.h
废话不说 效果图。
只改了walk函数。 其他自己改改吧,锻炼下自己
对了还有上面这个。原教程是直接这样算的一个矩阵,麻烦吧。麻烦吧。 懂不起含义了吧 快看龙书就懂了。懂了之后怎么办。还敲这么多??
一句话搞定,就不要造轮子了
比如前进 后退,上游 下潜。 各个方向渲染之类的。
首先设置按键。
这个时候需要在
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;
然后很简单吧
然后就是修改摄像机了
先上代码再讲解吧
#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);
一句话搞定,就不要造轮子了
相关文章推荐
- DirectX11 学习笔记7 - 支持自由移动的摄像机
- 【Unity3D游戏开发学习笔记】(七)上帝之眼—第三人称摄像机的简单实现(跟随视角,自由视角)
- 用JS实现移动的窗口 - 流星絮语 JAVA学习笔记 - CSDNBlog
- Struts 1 学习笔记-5-2(编写一个简单的支持I18N的登录系统)
- 将中心点移动至指定位置,并显示其信息【GMap 学习笔记】
- 31 天重构学习笔记2. 移动方法
- 31天重构学习笔记2. 移动方法
- [SQL学习笔记之一]SQLServer的内置XML支持
- 移动定位业务学习笔记
- ASP.NET AJAX的国际化与本地化支持(学习笔记)
- ArcGIS Mobile 9.4学习笔记八之如何设计和创建移动地图
- 学习笔记 Flex国际化如何支持其他语言
- XSLT学习笔记--NET Framework对XSLT的支持(1)
- MonoRail学习笔记二十:资源文件的使用和多语言支持
- [原]spring学习笔记9.1-Spring对Aop的支持-AOP基础篇
- 微软企业库4.1学习笔记(十二)中间人Providers,设计时支持Design-Time Configuration和仪表盘Instrumentation
- MonoRail学习笔记二十:资源文件的使用和多语言支持
- XSLT学习笔记--NET Framework对XSLT的支持(2)
- [原]spring学习笔记9.2-Spring对Aop的支持-annotation的方式
- ArcGIS Mobile 9.4学习笔记八之如何设计和创建移动地图