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 ...
随机推荐
- oracle-db安装
在LINUX平台上手动创建多个实例(oracle11g) http://blog.csdn.net/sunchenglu7/article/details/39676659 安装完桌面与数据库软件后, ...
- Zabbix-2.4-安装-3
zabbix自动注册简单介绍---创建自动注册的actions 怎么把1000台机器加zabbix里 zabbix提供了网络发现和自动注册2个功能,发现有机器连过来,给它加个模板 如果是win ...
- 从后端接口下载文件的2种方式:get方式、post方式
从后端接口下载文件的2种方式 一.get方式 直接使用: location.href='http://www.xxx.com/getFile?params1=xxx¶ms2=xxxx' ...
- 外观模式face
5.1 模式优点 外观模式的主要优点如下: (1) 它对客户端屏蔽了子系统组件,减少了客户端所需处理的对象数目,并使得子系统使用起来更加容易.通过引入外观模式,客户端代码将变得很简单,与之 ...
- instanceof isInstance isAssignableFrom 比较
instanceof : java 的关键字 判断一个 实例对象 是不是 可以赋值 给一个 class( 实例对象是不是 class 或者 subClass 的实现 ),表示的类和对象之间的关系 ...
- c#多线程与委托(转)
一:线程在.net中提供了两种启动线程的方式,一种是不带参数的启动方式,另一种是带参数的启动的方式.不带参数的启动方式 如果启动参数时无需其它额外的信息,可以使用ThreadStart来实例化Thre ...
- C# 控件
.ascx:Web窗体用户控件.用来存放独立的用户控件,可提供众多页面使用: <%@ Control Language="C#" AutoEventWireup=" ...
- asp.net:如何实现负载均衡方案讨论 (nginx+iis实现负载均衡)
5台阿里云服务器,ip地址分别为 ip地址 名字简称 操作系统 iis服务器 cpu 内存DDR3 机械硬盘 11 ...
- Spring学习之SpringMVC框架快速搭建实现用户登录功能
引用自:http://blog.csdn.net/qqhjqs/article/details/41683099?utm_source=tuicool&utm_medium=referral ...
- elasticsearch 聚合函数 max double精度损失bug
测试样例数据{ "size" : 0, "query" : { "bool" : { "must" : { " ...