cocos设置 相机矩阵和投影矩阵 源码浅析
在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设置 相机矩阵和投影矩阵 源码浅析的更多相关文章
- 【深入浅出jQuery】源码浅析--整体架构
最近一直在研读 jQuery 源码,初看源码一头雾水毫无头绪,真正静下心来细看写的真是精妙,让你感叹代码之美. 其结构明晰,高内聚.低耦合,兼具优秀的性能与便利的扩展性,在浏览器的兼容性(功能缺陷.渐 ...
- 【深入浅出jQuery】源码浅析2--奇技淫巧
最近一直在研读 jQuery 源码,初看源码一头雾水毫无头绪,真正静下心来细看写的真是精妙,让你感叹代码之美. 其结构明晰,高内聚.低耦合,兼具优秀的性能与便利的扩展性,在浏览器的兼容性(功能缺陷.渐 ...
- Struts2源码浅析-ConfigurationProvider
ConfigurationProvider接口 主要完成struts配置文件 加载 注册过程 ConfigurationProvider接口定义 public interface Configurat ...
- Android 手势识别类 ( 三 ) GestureDetector 源码浅析
前言:上 篇介绍了提供手势绘制的视图平台GestureOverlayView,但是在视图平台上绘制出的手势,是需要存储以及在必要的利用时加载取出手势.所 以,用户绘制出的一个完整的手势是需要一定的代码 ...
- Android开发之Theme、Style探索及源码浅析
1 背景 前段时间群里有伙伴问到了关于Android开发中Theme与Style的问题,当然,这类东西在网上随便一搜一大把模板,所以关于怎么用的问题我想这里也就不做太多的说明了,我们这里把重点放在理解 ...
- 【深入浅出jQuery】源码浅析2--使用技巧
最近一直在研读 jQuery 源码,初看源码一头雾水毫无头绪,真正静下心来细看写的真是精妙,让你感叹代码之美. 其结构明晰,高内聚.低耦合,兼具优秀的性能与便利的扩展性,在浏览器的兼容性(功能缺陷.渐 ...
- spring源码浅析——IOC
=========================================== 原文链接: spring源码浅析--IOC 转载请注明出处! ======================= ...
- Android源码浅析(六)——SecureCRT远程连接Linux,配置端点和字节码
Android源码浅析(六)--SecureCRT远程连接Linux,配置端点和字节码 需要编译源码的同学,一般都是win+虚拟机吧,但是再虚拟机里体验并不是很好,所有市面上有很多的软件能够做到在wi ...
- Android源码浅析(五)——关于定制系统,如何给你的Android应用系统签名
Android源码浅析(五)--关于定制系统,如何给你的Android应用系统签名 今天来点简单的我相信很多定制系统的同学都会有一些特定功能的需求,比如 修改系统时间 静默安装 执行某shell命令 ...
- Android源码浅析(四)——我在Android开发中常用到的adb命令,Linux命令,源码编译命令
Android源码浅析(四)--我在Android开发中常用到的adb命令,Linux命令,源码编译命令 我自己平时开发的时候积累的一些命令,希望对你有所帮助 adb是什么?: adb的全称为Andr ...
随机推荐
- 20165308 《Java程序设计》第9周学习总结
20165308 <Java程序设计>第9周学习总结 教材学习内容总结 13章知识总结 获取地址 1.获取Internet上主机的地址 可以使用InetAddress类的静态方法getBy ...
- 关注 硬件 发展, 转载一篇介绍 VHDL 的文章
<VHDL学习笔记> https://www.eefocus.com/hrbeulvcaho/blog/12-11/289109_978e2.html VHDL 和 “可编程逻辑阵列” ...
- 我发起了一个 .Net 平台上的 产生式编程 开源项目 GP.Net
大家好 , 我发起了一个 .Net 平台上的 产生式编程 开源项目 GP.Net . 我们可以先看看一个网友的 代码生成器 项目 : <.Net 代码生成器 for PostgreSql> ...
- [转]kafka详解
一.入门 1.简介 Kafka is a distributed,partitioned,replicated commit logservice.它提供了类似于JMS的特性,但是在设 ...
- haproxy(单机)+mysql集群负载均衡
HAProxy是 七层代理 ,在使甠HAProxy后,在MySQL上 看不到Apps的源IP地址 ,看到的是HAProxy地址,而 MySQL的权限访问设置是和IP地址有关 ,这样就导致了MySQL无 ...
- 如何在linux服务器上使用hanlp
关于如何在linux服务器上使用hanlp也有分享过一篇,但分享的内容与湘笑的这篇还是不同的.此处分享一下湘笑的这篇hanlp在linux服务器上使用的文章,供新手朋友学习之用. 本文主要工作是在li ...
- 自然语言处理工具hanlp关键词提取图解TextRank算法
看一个博主(亚当-adam)的关于hanlp关键词提取算法TextRank的文章,还是非常好的一篇实操经验分享,分享一下给各位需要的朋友一起学习一下! TextRank是在Google的PageRan ...
- 基于结构化平均感知机的分词器Java实现
基于结构化平均感知机的分词器Java实现 作者:hankcs 最近高产似母猪,写了个基于AP的中文分词器,在Bakeoff-05的MSR语料上F值有96.11%.最重要的是,只训练了5个迭代:包含语料 ...
- 开源数据采集组件比较: scribe、chukwa、kafka、flume
针对每天TB级的数据采集,一般而言,这些系统需要具有以下特征: 构建应用系统和分析系统的桥梁,并将它们之间的关联解耦: 支持近实时的在线分析系统和类似于Hadoop之类的离线分析系统: 具有高可扩展性 ...
- hmaster 启动后自动关闭
hbase重装后,hmaster却起不来,多次启动也不行,后来发现原因是在zookeeper中之前注册的hmaster仍然存在,系统中只允许一个hmaster运行.解决方法如下: 进入zk客户端,将h ...