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

原创 2016年06月11日 11:30:19

       本篇文章介绍一个在游戏中的重要概念,在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], 0, _zoom[1], _nearPlane, _farPlane, &_projection);
    _viewProjectionDirty = true;
    _frustumDirty = true;
    
    return true;
}
      正交投影就是没有近大远小概念的投影,它的视锥体就是矩形,所以定义它的时候只要定义视口宽高和近平面以及远平面就可以了。调用Mat4的

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

bool Camera::initPerspective(float fieldOfView, float aspectRatio, float nearPlane, float farPlane)
{
    _fieldOfView = fieldOfView;
    _aspectRatio = aspectRatio;
    _nearPlane = nearPlane;
    _farPlane = farPlane;
    Mat4::createPerspective(_fieldOfView, _aspectRatio, _nearPlane, _farPlane, &_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 3.x 头像选择器,本地相册与拍照+头像编辑功能(Android、IOS双平台实现)

在应用甚至游戏当中会常常有用户上传头像的功能,在网上找了N多资料发现没有人具体介绍过该用cocos2d-x实现。这篇文章就来介绍一下如何在Android和IOS平台上实现该功能。 先传一张完成后的图片...

《游戏引擎架构》读书笔记-游戏引擎中的C++

《游戏引擎架构》在两年前就买了,而且自己也大体的看过一遍,因为自己想学习引擎的底层知识,所以重新又找出了这本书再读一遍,并把根据自己的理解写一些读书笔记在这里与大家交流。       闲话少续,开始本...

Cocos2d-x学习笔记(17)(TestCpp源码分析-1)

TestCpp源码基于Cocos2d-x2

Cocos2d-x学习笔记(19)(TestCpp源码分析-3)

本章主要介绍

cocos2d-x 捕鱼大人源码

  • 2013年11月24日 22:50
  • 5.37MB
  • 下载

【Cocos2d-X开发学习笔记】第07期:渲染框架之摄像机类(CCCamera)的使用

一、摄像机类      所有节点都拥有一个摄像机类CCCamera。只有通过摄像机类,节点才会被渲染出来。当节点发生缩放旋转和位置 变化的时候,都需要覆盖CCCamera类,让这个节点通过CCCa...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:cocos2D-X源码分析之从cocos2D-X学习OpenGL(11)----摄像机
举报原因:
原因补充:

(最多只允许输入30个字)