在cocos中,最后设置视口大小,相机矩阵,裁剪矩阵是在setProjection方法中,源码如下:

void Director::setProjection(Projection projection)
{
//屏幕的可绘制区域,设计分辨率,fix模式下不和设计分辨率一样,其余和设计分辨率相等 Size size = _winSizeInPoints;
//设置适口,吧自己调整后的设计分辨率,换算成屏幕分辨率,设置绘制区域
setViewport(); switch (projection)
{
case Projection::_2D:
{
//单位化裁剪矩阵
loadIdentityMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_PROJECTION); #if CC_TARGET_PLATFORM == CC_PLATFORM_WP8
if(getOpenGLView() != nullptr)
{
multiplyMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_PROJECTION, getOpenGLView()->getOrientationMatrix());
}
#endif Mat4 orthoMatrix;
/*创建自定义投影矩阵*/
/*
left 视图体的最小 X 值。
right 视图体的最大 X 值。
bottom 视图体的最小 Y 值。
top 视图体的最大 Y 值。
zNearPlane 视图体的最小 Z 值。
zFarPlane 视图体的最大 Z 值。
返回值 正交投影矩阵。
*/
Mat4::createOrthographicOffCenter(, size.width, , size.height, -, , &orthoMatrix); multiplyMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_PROJECTION, orthoMatrix); loadIdentityMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW);
break;
} case Projection::_3D:
{
//得到观察者的Z,以设计分辨率为单位
/*
(_winSizeInPoints.height / 1.1566f);,为什么是1.1566,
根据相似三角形,通过这个值,得到的裁剪面正好就是 z为0的裁剪面,也就是2d中我们设置精灵的地方
原理可参考 http://blog.sina.com.cn/s/blog_6084f5880102v26q.html
*/
float zeye = this->getZEye();
//投影矩阵和View矩阵
Mat4 matrixPerspective, matrixLookup; //初始化一个单位矩阵,初始化投影矩阵为单位矩阵
loadIdentityMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_PROJECTION); #if CC_TARGET_PLATFORM == CC_PLATFORM_WP8
//if needed, we need to add a rotation for Landscape orientations on Windows Phone 8 since it is always in Portrait Mode
GLView* view = getOpenGLView();
if(getOpenGLView() != nullptr)
{
multiplyMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_PROJECTION, getOpenGLView()->getOrientationMatrix());
}
#endif
// issue #1334
//创建裁剪矩阵
/*
cocos直接使用设计分辨率winSizeInPoints来设置投影矩阵和观察点,并没有将其缩放到屏幕的实际分辨率,而只有视口设置为实际分辨率。
透视矩阵定义的视锥体的长宽比和视口的长宽比是相等的,这样才会保证不会变形
视口的大小为 设计分辨率*scale(scalex和scaley大部分情形一样),所以他们的比是一样的 我的理解:设计分辨率下的坐标相当于 世界坐标,然后乘以相机矩阵,得到相机下的坐标,然后乘以裁剪矩阵,得到裁剪后的规范化坐标,基本没用到实际分辨率 */
//参数一:垂直张角 参数二 宽高比,参数三:近端距离。距离eyez,也就是眼睛z坐标的距离 参数四:远端距离 参数五:生成的裁剪矩阵
/*
[x,y,z,1] 乘以 这个矩阵之后,变为[x'z,y'z,zz',wz],w=1,然后新的除以z,就是透视除法,把x',y',z' 变为(0,1)范围 // 经过投影变换后,物体坐标变换到了裁剪坐标系,经过OpenGL自动执行的透视除法后,变换到规范化设备坐标系中。透视除法就是将裁剪坐标系中坐标都除以齐次坐标的过程。
做过实验:把距离摄像机的近端距离由10变为100,发现 最后的图像没有变大,原因:
经过投影之后,x'=x/(z*aspect*tan(fov/2))这是投影之后的x坐标,范围为(-1,1),可以看到大小只受
aspect 和fov的影响,aspect不变,fov也不变,所以图像大小不变,受影响的只是z‘,不过投影到2d图像上,
这个用不到
*/
Mat4::createPerspective(, (GLfloat)size.width/size.height, , zeye+size.height/, &matrixPerspective);
//Mat4::createPerspective(60, (GLfloat)size.width/size.height, 100, zeye+size.height/2, &matrixPerspective); //单位矩阵先乘以投银矩阵,得到投影矩阵
multiplyMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_PROJECTION, matrixPerspective); Vec3 eye(size.width/, size.height/, zeye), center(size.width/, size.height/, 0.0f), up(0.0f, 1.0f, 0.0f); //生成相机坐标矩阵
/*
参数一:眼睛的位置,正中间 参数二:眼睛看向哪里,看向视口中点 参数三 头顶朝向,一班都是010
*/
Mat4::createLookAt(eye, center, up, &matrixLookup);
//通过测试得知 cameraPos.z=projectPos.w ,w就是z
Vec4 cameraPos=matrixLookup *Vec4(,,,);
Vec4 projectPos= matrixPerspective *cameraPos; //loopup矩阵右乘裁剪矩阵 也就是p*V
multiplyMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_PROJECTION, matrixLookup); //初始化模型视口矩阵??
loadIdentityMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW);
break;
} case Projection::CUSTOM:
// Projection Delegate is no longer needed
// since the event "PROJECTION CHANGED" is emitted
break; default:
CCLOG("cocos2d: Director: unrecognized projection");
break;
} _projection = projection;
//
GL::setProjectionMatrixDirty(); _eventDispatcher->dispatchEvent(_eventProjectionChanged);
}

下面再看看生成投影矩阵的代码:

void Mat4::createPerspective(float fieldOfView, float aspectRatio,
float zNearPlane, float zFarPlane, Mat4* dst)
{
GP_ASSERT(dst);
GP_ASSERT(zFarPlane != zNearPlane); float f_n = 1.0f / (zFarPlane - zNearPlane);
float theta = MATH_DEG_TO_RAD(fieldOfView) * 0.5f;
if (fabs(fmod(theta, MATH_PIOVER2)) < MATH_EPSILON)
{
CCLOGERROR("Invalid field of view value (%f) causes attempted calculation tan(%f), which is undefined.", fieldOfView, theta);
return;
}
float divisor = tan(theta);
GP_ASSERT(divisor);
float factor = 1.0f / divisor; memset(dst, , MATRIX_SIZE); GP_ASSERT(aspectRatio);
dst->m[] = (1.0f / aspectRatio) * factor;
dst->m[] = factor;
dst->m[] = (-(zFarPlane + zNearPlane)) * f_n;
//测试的值m[11]控制着裁剪矩阵(x'z,x'y,z'z,z)的z,左手坐标系m[11]为1,右手坐标系m[11]为-1,控制着
//最后x,y,z 的正负,不管是左手坐标系还是右手坐标系,得出的裁剪矩阵x',y',z'的坐标应该是一样的
//而在世界坐标转换为 相机坐标的时候,z坐标正好相反,所以通过m[11]使2者的裁剪坐标一致
dst->m[] = -1.0f;
dst->m[] = -2.0f * zFarPlane * zNearPlane * f_n;
}

cocos设置 相机矩阵和投影矩阵 源码浅析的更多相关文章

  1. 【深入浅出jQuery】源码浅析--整体架构

    最近一直在研读 jQuery 源码,初看源码一头雾水毫无头绪,真正静下心来细看写的真是精妙,让你感叹代码之美. 其结构明晰,高内聚.低耦合,兼具优秀的性能与便利的扩展性,在浏览器的兼容性(功能缺陷.渐 ...

  2. 【深入浅出jQuery】源码浅析2--奇技淫巧

    最近一直在研读 jQuery 源码,初看源码一头雾水毫无头绪,真正静下心来细看写的真是精妙,让你感叹代码之美. 其结构明晰,高内聚.低耦合,兼具优秀的性能与便利的扩展性,在浏览器的兼容性(功能缺陷.渐 ...

  3. Struts2源码浅析-ConfigurationProvider

    ConfigurationProvider接口 主要完成struts配置文件 加载 注册过程 ConfigurationProvider接口定义 public interface Configurat ...

  4. Android 手势识别类 ( 三 ) GestureDetector 源码浅析

    前言:上 篇介绍了提供手势绘制的视图平台GestureOverlayView,但是在视图平台上绘制出的手势,是需要存储以及在必要的利用时加载取出手势.所 以,用户绘制出的一个完整的手势是需要一定的代码 ...

  5. Android开发之Theme、Style探索及源码浅析

    1 背景 前段时间群里有伙伴问到了关于Android开发中Theme与Style的问题,当然,这类东西在网上随便一搜一大把模板,所以关于怎么用的问题我想这里也就不做太多的说明了,我们这里把重点放在理解 ...

  6. 【深入浅出jQuery】源码浅析2--使用技巧

    最近一直在研读 jQuery 源码,初看源码一头雾水毫无头绪,真正静下心来细看写的真是精妙,让你感叹代码之美. 其结构明晰,高内聚.低耦合,兼具优秀的性能与便利的扩展性,在浏览器的兼容性(功能缺陷.渐 ...

  7. spring源码浅析——IOC

    =========================================== 原文链接: spring源码浅析--IOC   转载请注明出处! ======================= ...

  8. Android源码浅析(六)——SecureCRT远程连接Linux,配置端点和字节码

    Android源码浅析(六)--SecureCRT远程连接Linux,配置端点和字节码 需要编译源码的同学,一般都是win+虚拟机吧,但是再虚拟机里体验并不是很好,所有市面上有很多的软件能够做到在wi ...

  9. Android源码浅析(五)——关于定制系统,如何给你的Android应用系统签名

    Android源码浅析(五)--关于定制系统,如何给你的Android应用系统签名 今天来点简单的我相信很多定制系统的同学都会有一些特定功能的需求,比如 修改系统时间 静默安装 执行某shell命令 ...

  10. Android源码浅析(四)——我在Android开发中常用到的adb命令,Linux命令,源码编译命令

    Android源码浅析(四)--我在Android开发中常用到的adb命令,Linux命令,源码编译命令 我自己平时开发的时候积累的一些命令,希望对你有所帮助 adb是什么?: adb的全称为Andr ...

随机推荐

  1. :first :first-child .first()和.get() .eq()

    :first .first()只匹配一个元素,而 :first-child 将为每个父元素匹配一个子元素 .get()得到的是dom 元素  $('li').get()没有参数返回一个数组 .eq() ...

  2. cachecloud安装部署

    项目地址:https://github.com/sohutv/cachecloud # 初始化数据库 默认插入admin超级管理员,用户名admin, 密码:admin 安装mysql yum -y ...

  3. mqtt-jmeter

    mqtt-jmeter https://github.com/emqtt/mqtt-jmeter mqtt-jmeter MQTT JMeter Plugin, it's used for testi ...

  4. 集群RedHat6.5+JDK1.8+Hadoop2.7.3+Spark2.1.1+zookeeper3.4.6+kafka2.11+flume1.6环境搭建步骤

    1.RHEL 6.5系统安装配置图解教程(rhel-server-6.5) 2.在Linux下安装JDK图文解析 3.RedHat6.5上安装Hadoop集群 4.RedHat6.5安装Spark集群 ...

  5. openwrt 无线中继

    参考: https://wiki.openwrt.org/doc/recipes/relayclient 该方法可以实现中继AP,而不需要AP(WDS)模式.中继后,相当于该路由所有的LAN口以及AP ...

  6. 《LOST》 电视

    还没看正剧,所以转来帮助看电视 从起源到终点:<LOST>剧情全解析(一)   此文是LOST完结之后的剧情解析,剧透,慎入   从起源到终点:<LOST>剧情全解析(一) 转 ...

  7. xe5 android sample 中的 SimpleList 是怎样绑定的 [转]

    C:\Users\Public\Documents\RAD Studio\12.0\Samples\FireMonkeyMobile 例子中的绑定方式如下图: 1.拖拽一个listview到界面上,然 ...

  8. NetBeans IDE 多行标签设置方法

  9. JavaScript压缩代码解压缩还原具体办法

    我们知道许多网站都对Javascript代码进行了压缩,但这对开发者和学习者来说,读起来很费劲,本文分享给大家在Chrome浏览器中,如何使用Pretty Print功能反压缩JS代码,让代码更加直观 ...

  10. Java 中统计文件中出现单词的次数练习

    统计英文article.txt文件中出现hello这个单词的次数 这个是article.txt文件内容 { hello The Royal Navy is trying hello to play h ...