打造3D游戏中第一人称视觉效果 - 带可测试源代码下载
2013-11-02 15:07
330 查看
首先解决的一个问题:什么是镜头?
我们可以想象拍戏那种镜头,对着什么东西,就能拍出什么东西,然后我们就可以在电视屏幕或者电影屏幕上看到这些东西。3D世界里面也是这样定义一个镜头,在这个镜头范围之内的东西就可以显示在电脑屏幕中。
如下图在一个方各地上行走:
下面是把镜头抽象起来:
拍戏的时候,这个镜头是个实体,那么在我们的3D世界里面我们也是这样把镜头当做一个实体,在代码中体现出来就是一个类。
在游戏中控制镜头前进,后退,左移,右移,其实就是在代码中操作这个类。
所以问题就归结为如何构建这个类,和如何操作这个类了。
首先构建这个类的对象成员有如下数据:
镜头的坐标如下:
右上角的代表镜头,指向前的叫前向量,指向上的叫上向量,指向右的叫右向量。这样就构成了镜头坐标空间。就是构建了这样的空间,才可以让镜头前面的物体相对于镜头的位置得以确定!是在看不懂的朋友先熟记一下这个概念,然后建议补一补几何学。
mProj和mViewProj矩阵基本上在所有3D世界都要用到的。这是图形学的构造原理,有空再专门解析一下吧。简单解析一下就是说:利用这些矩阵才能把定位在世界坐标空间的物体投影到屏幕上。
跟本章相关的就是mView矩阵了,就是利用了这个矩阵才能操作镜头的。这个矩阵的计算方法如下:
定义在类中:
实现函数:
下面就是以鼠标和键盘为参数不断更新上面这些参数,得到不断移动镜头的感觉:
下面是调用函数,我写了个namespace包起来,方便修改:
玩这个程序只需要修改上面说明的地方就可以自己测试了。
可以修改的地方:
1 修改成为可以飞起来的
2 修改其速度
3 改成不受方格地限制
4 更难的就是修改限制其俯视的角度
这里是镜头类下载:
http://download.csdn.net/detail/kenden23/6491871
这里是框架下载:
http://download.csdn.net/detail/kenden23/6491875
都是源代码。
我们可以想象拍戏那种镜头,对着什么东西,就能拍出什么东西,然后我们就可以在电视屏幕或者电影屏幕上看到这些东西。3D世界里面也是这样定义一个镜头,在这个镜头范围之内的东西就可以显示在电脑屏幕中。
如下图在一个方各地上行走:
下面是把镜头抽象起来:
拍戏的时候,这个镜头是个实体,那么在我们的3D世界里面我们也是这样把镜头当做一个实体,在代码中体现出来就是一个类。
在游戏中控制镜头前进,后退,左移,右移,其实就是在代码中操作这个类。
所以问题就归结为如何构建这个类,和如何操作这个类了。
首先构建这个类的对象成员有如下数据:
class Camera { protected: D3DXMATRIX mView;//操作镜头的主要矩阵 D3DXMATRIX mProj;//投影到屏幕上的矩阵 D3DXMATRIX mViewProj;//从镜头空间到投影到屏幕上的矩阵 D3DXVECTOR3 mPosW;//镜头位置 D3DXVECTOR3 mRightW;//镜头的由向量 D3DXVECTOR3 mUpW;//镜头的上向量 D3DXVECTOR3 mLookW;//镜头的前向量 float mSpeed;//镜头的速度
镜头的坐标如下:
右上角的代表镜头,指向前的叫前向量,指向上的叫上向量,指向右的叫右向量。这样就构成了镜头坐标空间。就是构建了这样的空间,才可以让镜头前面的物体相对于镜头的位置得以确定!是在看不懂的朋友先熟记一下这个概念,然后建议补一补几何学。
mProj和mViewProj矩阵基本上在所有3D世界都要用到的。这是图形学的构造原理,有空再专门解析一下吧。简单解析一下就是说:利用这些矩阵才能把定位在世界坐标空间的物体投影到屏幕上。
跟本章相关的就是mView矩阵了,就是利用了这个矩阵才能操作镜头的。这个矩阵的计算方法如下:
定义在类中:
class Camera { public: Camera(); protected: void buildView();
实现函数:
void Camera::buildView() { // 这里是前向量单位化. D3DXVec3Normalize(&mLookW, &mLookW); D3DXVec3Cross(&mUpW, &mLookW, &mRightW);//作叉乘可以确保这2个向量是正交的,也就是都互相垂直。 D3DXVec3Normalize(&mUpW, &mUpW); D3DXVec3Cross(&mRightW, &mUpW, &mLookW);//再次叉乘保证正交 D3DXVec3Normalize(&mRightW, &mRightW); //这里是根据几何公式来填写这个需要的变换矩阵的,至于是什么公式,我也不记得了,因为公式很复杂,死背不是好办法,但是原理要知道,就是利用这样的矩阵来转换镜头。 float x = -D3DXVec3Dot(&mPosW, &mRightW); float y = -D3DXVec3Dot(&mPosW, &mUpW); float z = -D3DXVec3Dot(&mPosW, &mLookW); mView(0,0) = mRightW.x; mView(1,0) = mRightW.y; mView(2,0) = mRightW.z; mView(3,0) = x; mView(0,1) = mUpW.x; mView(1,1) = mUpW.y; mView(2,1) = mUpW.z; mView(3,1) = y; mView(0,2) = mLookW.x; mView(1,2) = mLookW.y; mView(2,2) = mLookW.z; mView(3,2) = z; mView(0,3) = 0.0f; mView(1,3) = 0.0f; mView(2,3) = 0.0f; mView(3,3) = 1.0f; }
下面就是以鼠标和键盘为参数不断更新上面这些参数,得到不断移动镜头的感觉:
void Camera::update(float dt) { // 这里是控制方法wsda为前后左右。 D3DXVECTOR3 dir(0.0f, 0.0f, 0.0f); if( gDInput->keyDown(DIK_W) ) dir += mLookW; if( gDInput->keyDown(DIK_S) ) dir -= mLookW; if( gDInput->keyDown(DIK_D) ) dir += mRightW; if( gDInput->keyDown(DIK_A) ) dir -= mRightW; // Move at mSpeed along net direction. D3DXVec3Normalize(&dir, &dir); mPosW += dir*mSpeed*dt;//这里是控制其速度,可以改变mSpeed的大小以改变其速度,记得mSpeed为类的私有成员。 mPosW.y = 2.0f;//这里是限制其高度,相当于人的高度。如果把这里去掉的话,就可以飞起来了。 if(mPosW.x >= 49.0f)//这下面的代码是控制不要超出了方格地的范围了。 mPosW.x = 49.0f; if(mPosW.x <=-49.0f) mPosW.x = -49.0f; if(mPosW.z >= 49.0f) mPosW.z = 49.0f; if(mPosW.z <= -49.0f) mPosW.z = -49.0f; // 下面是鼠标控制代码,控制其向左和向右,向上和向下看. float pitch = gDInput->mouseDY() / 150.0f; float yAngle = gDInput->mouseDX() / 150.0f; // 向上下方向看时的变换算法. D3DXMATRIX R; D3DXMatrixRotationAxis(&R, &mRightW, pitch); D3DXVec3TransformCoord(&mLookW, &mLookW, &R); D3DXVec3TransformCoord(&mUpW, &mUpW, &R); // 向左向右看时的算法. D3DXMatrixRotationY(&R, yAngle); D3DXVec3TransformCoord(&mRightW, &mRightW, &R); D3DXVec3TransformCoord(&mUpW, &mUpW, &R); D3DXVec3TransformCoord(&mLookW, &mLookW, &R); // 然后需要重新调用前面的函数根据上面的新参数更新计算,这样达到移动镜头的目的. buildView(); mViewProj = mView * mProj; }
下面是调用函数,我写了个namespace包起来,方便修改:
#include "CameraRun.h" #include "Camera.h" namespace CameraRun { Camera camera; void initData() { gCamera = &camera; gCamera->pos() = D3DXVECTOR3(-20.0f, 2.0f, 0.0f); } void updateAll(float dt) { gCamera->update(dt); } }
玩这个程序只需要修改上面说明的地方就可以自己测试了。
可以修改的地方:
1 修改成为可以飞起来的
2 修改其速度
3 改成不受方格地限制
4 更难的就是修改限制其俯视的角度
这里是镜头类下载:
http://download.csdn.net/detail/kenden23/6491871
这里是框架下载:
http://download.csdn.net/detail/kenden23/6491875
都是源代码。
相关文章推荐
- ASP.NET MVC4应用程序无法建立控制器的解决方案/获取自己需要的EF版本
- SSH整合包详解.Struts2.2.3+Spring3.1.0.M2+Hibernate3.6.6
- C语言编程——控制台程序光标控制
- 使用git配合idea使用oschina代码仓库初级教程
- java之事件监听(三)鼠标监听
- java常用日期问题集锦
- 主题:Java 枚举7常见种用法
- C++: Socket工作流程图(WinSock)
- JAVA学习日记
- MyEclipse中使用SVN插件方法
- pureftp服务器搭建
- Google地图 经度 纬度 到 像素索引值 的转换公式
- C#指定编码写文件的那些事
- ASP.NET 如何使用 SqlTransaction
- C#:在catch中return,会执行finally吗?
- android开发环境的搭建,基于eclipse.最后会附上一些参考网址算是一个合集给大家
- c++练习中遇到的问题和解决
- 事件CEvent的使用 . 分类: VC++ 2013-11-02 14:31 499人阅读 评论(0) 收藏
- ASP.NET执行cmd命令
- java流类,快速统计出字符次数+++