由于OpenGl每次都会将物体都是变换为屏幕上的二维来显示,所以少不了坐标变换(将3D处理在2D上显示),然后并进行裁剪处理(显示范围之外的点都被裁剪掉(Clipped)),默认的可见坐标是-1.0~1.0,假如我们想自己显示投影的部分,那么就需要投影矩阵,通过投影矩阵可以创建一个观察箱(Viewing Box),又称为平截头体(Frustum),那么所有出现在观察箱里的顶点都会显示在屏幕上,创建一个投影矩阵有两种不同方法:

正射投影矩阵(Orthographic Projection Matrix)或一个透视投影矩阵(Perspective Projection Matrix)。.

1.正射投影(orthographic projection matrix)

正射投影对应的qt中函数是:

void QMatrix4x4::ortho(float left, float right, float bottom, float top, float nearPlane, float farPlane)// left right, bottom, top : 设置观察箱(平截头体)的上下左右坐标
// nearPlane: 设置近平面的距离
// farPlane: 设置远平面的距离

对应如下图所示:

初始化好投影矩阵后,会将处于这些x,y,z值范围内的坐标变换为标准化设备坐标,对应的源码如下所示:

如上图所示,可以看到将转换规则以一个系数存储在矩阵中,当乘上原本的标准坐标向量时,就会将标准坐标转为标准化设备坐标,而对于w分量部分(矩阵最后一行)依然是[0 0 0 1],所以会导致无论物体距离相机多远投影后的物体大小尺寸不变.如下图所示:

使用透视投影的话,远处的顶点看起来比较小,而在正射投影中每个顶点距离观察者的距离都是一样的。

2.透视投影

使用透视投影,会比正射投影更加真实(投影中心无变形,离中心越远变形越大)

透视投影通过w分量来实现,离观察者越则w分量越大,然后顶点坐标的每个分量都会去除以它的w分量(所以越远,则顶点坐标越小):

所以我们之前学习的坐标向量都是vec4,因为通过w分量才能帮我们进行透视投影.

透视投影对应的qt中函数是:

void QMatrix4x4::perspective(float verticalAngle, float aspectRatio, float nearPlane, float farPlane)// verticalAngle: 垂直角度(也就是裁剪窗口的高度),值越大,那么物体越小// aspectRatio: 横纵比(由视口的宽除以高所得),值越大则越宽值,比如宽高为100X50,那么就等于2// nearPlane: 设置近平面的距离(一般设置为0.1)// farPlane: 设置远平面的距离(一般设置为100)

源代码如下所示:

可以看到对于w分量部分(矩阵最后一行)是[0 0 -1 0],假如z向量有值的话会乘以(-1).得到的w分量将会有值的,通过透视除法后将会导致坐标越小,接下来我们便来测试一下.

3.正射投影和透视投影测试

测试代码如下所示:

    Vector4D vec(1,2,100,1);QMatrix4x4 projection1;projection1.ortho(10,20,0,10,10,100);qDebug()<<projection1<<projection1*vec;QMatrix4x4 projection2;projection2.perspective(10,20,0.1,100);qDebug()<<projection2<<projection2*vec;

运行打印:

可以看到对于z为100的物体,通过透视投影转换后得到的坐标的z值是-100。然后当顶点变换到裁剪空间时,会执行透视除法,从而导致顶点坐标很小.

而对于正射投影的话,转换出来的向量z值始终为1. 所以正射投影不支持透视除法.

未完待续,下章就在3D场景中使用投影矩阵.

本专栏opengl技术交流群:929155430

11.opengl-正射投影和透视投影源码分析相关推荐

  1. YYCache 源码分析(一)

    iOS 开发中总会用到各种缓存,YYCache或许是你最好的选择.性能上有优势,用法也很简单.作者ibireme曾经对比过同类轮子:http://blog.ibireme.com/2015/10/26 ...

  2. apache dubbo 源码分析系列汇总

    Dubbo(读音[ˈdʌbəʊ])是阿里巴巴公司开源的一个高性能优秀的服务框架,使得应用可通过高性能的 RPC 实现服务的输出和输入功能,可以和 Spring框架无缝集成.后面捐献给了知名的开源社区 ...

  3. SDL2源码分析之OpenGL ES在windows上的渲染过程

    SDL2源码分析之OpenGL ES在windows上的渲染过程 更新于2018年11月4日. 更新于2018年11月21日. ffmpeg + SDL2实现的简易播放器 ffmpeg和SDL非常强大 ...

  4. Java源码详解六:ConcurrentHashMap源码分析--openjdk java 11源码

    文章目录 注释 类的继承与实现 数据的存储 构造函数 哈希 put get 扩容 本系列是Java详解,专栏地址:Java源码分析 ConcurrentHashMap 官方文档:ConcurrentH ...

  5. Java源码详解四:String源码分析--openjdk java 11源码

    文章目录 注释 类的继承 数据的存储 构造函数 charAt函数 equals函数 hashCode函数 indexOf函数 intern函数 本系列是Java详解,专栏地址:Java源码分析 Str ...

  6. Java源码详解五:ArrayList源码分析--openjdk java 11源码

    文章目录 注释 类的继承与实现 构造函数 add操作 扩容函数 remove函数 subList函数 总结 本系列是Java详解,专栏地址:Java源码分析 ArrayList 官方文档:ArrayL ...

  7. Java源码详解三:Hashtable源码分析--openjdk java 11源码

    文章目录 注释 哈希算法与映射 线程安全的实现方法 put 操作 get操作 本系列是Java详解,专栏地址:Java源码分析 Hashtable官方文档:Hashtable (Java Platfo ...

  8. Java源码详解二:HashMap源码分析--openjdk java 11源码

    文章目录 HashMap.java介绍 1.HashMap的get和put操作平均时间复杂度和最坏时间复杂度 2.为什么链表长度超过8才转换为红黑树 3.红黑树中的节点如何排序 本系列是Java详解, ...

  9. Android 11.0 Settings源码分析 - 主界面加载

    Android 11.0 Settings源码分析 - 主界面加载 本篇主要记录AndroidR Settings源码主界面加载流程,方便后续工作调试其流程. Settings代码路径: packag ...

最新文章

  1. ​炸了!程序员现在没有这点技能都还不能就业了?
  2. html 页面中的 base href 和 target
  3. jquery ajax 序列化表单传参提交实体对象到后台action
  4. 数智化时代合格数据架构师如何养成?
  5. HTTP和RPC的优缺点 1
  6. php获取手机目录,php如何获取手机型号
  7. php jquery mysql,使用PHP / MySQL搜索并使用jQuery动态更新
  8. 芦溪中学2021高考成绩查询,2021萍乡市地区高考成绩排名查询,萍乡市高考各高中成绩喜报榜单...
  9. 开源任务式问答机器人框架系列之Dialogflow
  10. 《量子信息与量子计算简明教程》绪论
  11. python+FTP 批量上传文件
  12. 基于MATLAB视频的人体姿态检测
  13. C++基础中的基础——平行四边形
  14. 微软中国艰难前行:业绩遭遇连续跳票
  15. 软件架构设计---软件架构风格
  16. 常用字写法(粤语)--(1)
  17. 您目前无法访问XXXX,因为此网站使用了HSTS
  18. jdk11新特性——ZGC
  19. 【R语言】使用nnet过程中报错Error in eval(predvars, data, env) : object ‘naulong‘ not found
  20. 1491_福特8D分析案例学习

热门文章

  1. 基于天鹰算法改进的DELM预测-附代码
  2. java爬取网上公开的文章
  3. pug的安装以及pug-plain-loader处理模板
  4. /var/run目录详解
  5. HP1280打印机A4能打印,A3不能打印故障解决
  6. 一文读懂什么是分布式文件系统
  7. linux中的压缩解压命令:gzip,tar,zip,bzip2
  8. python 发音-python 发音
  9. H5游戏开发:消灭星星
  10. 软件工程--四则运算表达式(4)