cocos2D-X源码分析之从cocos2D-X学习OpenGL(11)----摄像机

cocos2D-X源码分析之从cocos2D-X学习OpenGL(11)----摄像机,第1张

概述       本篇文章介绍一个在游戏中的重要概念,在MVP矩阵中,视图矩阵和投影矩阵都和摄像机有关,说句白话,摄像机其实就是生成投影矩阵和视图矩阵的方式和原因,cocos2d-x中使用GamePlay3D类的Mat4类生成各种矩阵,一下就通过分析摄像机Camera类的代码来看这些矩阵是如何生成的。        首先来看正交矩阵的初始化代码: bool Camera::initOrthograph

本篇文章介绍一个在游戏中的重要概念,在MVP矩阵中,视图矩阵和投影矩阵都和摄像机有关,说句白话,摄像机其实就是生成投影矩阵和视图矩阵的方式和原因,cocos2d-x中使用GamePlay3D类的Mat4类生成各种矩阵,一下就通过分析摄像机Camera类的代码来看这些矩阵是如何生成的。

首先来看正交矩阵的初始化代码:

bool Camera::initOrthographic(float zoomX,float zoomY,float nearPlane,float farPlane){    _zoom[0] = zoomX;    _zoom[1] = zoomY;    _nearPlane = nearPlane;    _farPlane = farPlane;    Mat4::createOrthographicOffCenter(0,_zoom[0],_zoom[1],_nearPlane,_farPlane,&_projection);    _vIEwProjectionDirty = true;    _frustumDirty = true;        return true;}
正交投影就是没有近大远小概念的投影,它的视锥体就是矩形,所以定义它的时候只要定义视口宽高和近平面以及远平面就可以了。调用Mat4的

createOrthographicOffCenter生成投影矩阵把它传给_projection。

bool Camera::initPerspective(float fIEldOfVIEw,float aspectRatio,float farPlane){    _fIEldOfVIEw = fIEldOfVIEw;    _aspectRatio = aspectRatio;    _nearPlane = nearPlane;    _farPlane = farPlane;    Mat4::createPerspective(_fIEldOfVIEw,_aspectRatio,&_projection);    _vIEwProjectionDirty = true;    _frustumDirty = true;        return true;}
而透视投影的初始化方式类似,参数分别为:视角角度,宽高比,近平面,远平面,最后函数会把投影矩阵传递给_projection。
定义一个摄像机,需要摄像机位置,观察方向,还有一个指向它右侧的向量,以及一个它上方的向量,这实际上是一个以摄像机位置为原点的坐标系,如图所示:

所以说在创建摄像机以后,就要定义它的位置和lookAt

_camera->setposition3D(Vec3(0,130,130) + _sprite3D->getposition3D());_camera->lookAt(_sprite3D->getposition3D());
lookAt定义了观察目标位置和摄像机向上位置,如果不传参数第二个参数就默认为y轴方向

在lookAt中,我们定义了lookAt矩阵,也就是视图矩阵,至于视图矩阵的推导,可以参考这篇文章:http://www.cnblogs.com/mincomp/archive/2012/09/06/2672888.HTML,这里我们只需要知道这个结果就可以:

R为右向量,U为上向量,D为方向向量,它们的计算过程就在lookAt函数中:

    //向上向量    Vec3 upv = up;    upv.normalize();    //摄像机方向    Vec3 zaxis;    Vec3::subtract(this->getposition3D(),lookAtPos,&zaxis);    zaxis.normalize();    //右轴    Vec3 xaxis;    Vec3::cross(upv,zaxis,&xaxis);    xaxis.normalize();    //上轴    Vec3 yaxis;    Vec3::cross(zaxis,xaxis,&yaxis);    yaxis.normalize();    //lookAt矩阵    Mat4  rotation;    rotation.m[0] = xaxis.x;    rotation.m[1] = xaxis.y;    rotation.m[2] = xaxis.z;    rotation.m[3] = 0;        rotation.m[4] = yaxis.x;    rotation.m[5] = yaxis.y;    rotation.m[6] = yaxis.z;    rotation.m[7] = 0;    rotation.m[8] = zaxis.x;    rotation.m[9] = zaxis.y;    rotation.m[10] = zaxis.z;    rotation.m[11] = 0;
注意,这里的摄像机方向实际上是摄像机位置向量指向它看着的方向的相反方向,然后下面用向量的叉乘获得右轴和上轴,从而获得lookAt矩阵所需要的值,这些计算的原理可以参考:https://en.wikipedia.org/wiki/Gram%E2%80%93SchmIDt_process

下一篇将介绍天空盒的原理


能力不足,水平有限,如有问题,欢迎指出。

总结

以上是内存溢出为你收集整理的cocos2D-X源码分析之从cocos2D-X学习OpenGL(11)----摄像机全部内容,希望文章能够帮你解决cocos2D-X源码分析之从cocos2D-X学习OpenGL(11)----摄像机所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/web/1080187.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-05-27
下一篇2022-05-27

发表评论

登录后才能评论

评论列表(0条)

    保存