OpenGL ES之九——相机和投影
概述
这是一个系列的Android平台下OpenGl ES介绍,从最基本的使用最终到VR图的展示的实现,属于基础篇。(后面针对VR视频会再有几篇文章,属于进阶篇)
OpenGL ES之一——概念扫盲
OpenGL ES之二——Android中的OpenGL ES概述
OpenGL ES之三——绘制纯色背景
OpenGL ES之四——绘制点,线,三角形
OpenGL ES之五——相机和投影,绘制等腰三角形
OpenGL ES之六——绘制矩形和圆形
OpenGL ES之七——着色器语言GLSL
OpenGL ES之八——GLES20类和Matrix类
OpenGL ES之九——相机和投影
OpenGL ES之十——纹理贴图(展示一张图片)
OpenGL ES之十一——绘制3D图形
OpenGL ES之十二——地球仪和VR图
本篇概述
前面一直在使用相机矩阵和投影矩阵来解决平面图形变形的问题,但是其中的原理一直没有阐述,其实是怕不结合实例很难解释的清楚。现在水到渠成了,接触了很多使用OpenGLES绘制2D图形,想必都有了一些感觉,接下来可以好好解释一下了。
一.OpenGL的世界
这里不会将官网上概念搬过来,而是将各种概念以容易理解的方式阐述
。
1. 相机就相当于我们的眼睛;
2. 人类的视野范围是有限的,所以就有了“视景体”或者叫“裁剪体”;
3. 物体反射光或者发光投射到“指定的屏幕上”,这就是投影;
变换矩阵
我们在之前绘制点,线,三角形的时候发现即使我们给的坐标是构成等腰三角形的坐标,最终绘制的结果也不是。后来我们使用了变换矩阵将我们本想绘制的等腰直角三角形绘制了出来,而它的出处如下(之前阐述过OpenGl的2D坐标系和屏幕坐标系的关系所以这里不做赘述):
先给出顶点位置变换公式
其中从左往右各个参数解释如下:
第一个:变换结果;
第二个:投影矩阵;
第三个:相机矩阵;
第四个:模型矩阵;
第五个:顶点位置参数所在的向量。
我们之前使用的时候将投影矩阵和相机矩阵相乘为变换矩阵使用。而这里的模型矩阵我们可以理解为一个单位矩阵(我们习惯将2D平面设置为x和y轴组成的平面,而z轴作为垂直于该平面的方向)
。
二 投影
2.1 视景体
先看下图
上图中六个平面围成的空间就是“视景体”或者称为“裁剪空间”
,只有被观察的物体在其中我们才能看得见
。同时注意这里的远,近平面是以相机为基准的
。同时图像是呈现在近平面上的
。
2.2 透视投影和正交投影
先看图:
从图中我们可以很容易看出区别:
透视投影:相机看作一个点,由相机发出的视线与视景体远平面构成椎体。
正交投影:相机看作和近,远平面大小相同并平行的矩形,由相机发出的视线与视景体远平面构成长方体。
最终图像都投影到近平面上。
然后看我们获取投影矩阵的方法
透视投影
public static void frustumM(float[] m, int offset,float left, float right,float bottom, float top,float near, float far)
正交投影
public static void orthoM(float[] m, int mOffset,float left, float right, float bottom, float top,float near, float far)
两个方法的参数:m指的是装载结果矩阵的数组;offset指矩阵偏移量;其他在图中标记的很明显了,这里不做赘述。
2.3 参数的传递规则
之前解决三角形的拉伸问题我们使用如下:
//相机和透视投影方式//计算宽高比float ratio=(float)width/height;//设置透视投影Matrix.frustumM(mProjectMatrix, 0, -ratio, ratio, -1, 1, 3, 7);//设置相机位置Matrix.setLookAtM(mViewMatrix, 0, 0, 0, 7.0f, 0f, 0f, 0f, 0f, 1.0f, 0.0f);//计算变换矩阵Matrix.multiplyMM(mMVPMatrix,0,mProjectMatrix,0,mViewMatrix,0);/*//正交投影方式final float aspectRatio = width > height ?(float) width / (float) height :(float) height / (float) width;if (width > height) {//横屏Matrix.orthoM(mMVPMatrix, 0, -aspectRatio, aspectRatio, -1f, 1f, -1f, 1f);} else {//竖屏Matrix.orthoM(mMVPMatrix, 0, -1f, 1f, -aspectRatio, aspectRatio, -1f, 1f);}*/
不管是正交投影还是透视投影,最终都是将视景体内的物体投影在近平面上
,这也是 3D 坐标转换到 2D 坐标的关键一步。
而近平面上的坐标接着也会转换成归一化设备坐标,再映射到屏幕视口上。
为了解决之前的图像拉伸问题,就是要保证近平面的宽高比和视口的宽高比一致,而且是以较短的那一边作为 1 的标准,让图像保持居中
。
2.4 另一种获取透视投影的方法perspectiveM
如下:
public static void perspectiveM(float[] m, int offset,float fovy, float aspect, float zNear, float zFar)
看下图,帮助理解
perspectiveM
函数来创建投影矩阵,它的视景体和 frustumM 函数相同,但是构造的参数有所不同。
视景体不再需要确定近平面左、上、右、下距离了。
通过视角来决定我们能看到的视野大小。视角就是图中所示的那个夹角。另外的参数是视口的宽高比,还有近平面和远平面的距离,参数个数减少了。
如下图:
上述图片左边是 90 视角,右边是 45 度视角。显然,视野角度越大,则看到的内容更多,但是物体显得更小,而视野角度越小,则看的内容更少,但物体显得更大。
和 frustumM不同的是,一旦确定了视角和宽高比,那么整个摄像机视野也就确定了,此时完整的锥形视野已经形成了,也就是说物体的近大远小效果已经完成了。这时,近平面距离和远平面距离只是确定想要截取锥形视野中的哪一部分了。不像在frustumM函数中,近、远平面的距离还能够调整近大远小的效果。
三 相机
先看图
这里的相机模拟了真实环境中相机。OpenGL 本身是没有相机的概念的,不过为了营造出运动的效果,我们可以移动相机产生相对运动(例如平移,转动等)。
我们通过下面的方法来设置相机的各个参数:
Matrix.setLookAtM(float[] rm, int rmOffset,float eyeX, float eyeY, float eyeZ,float centerX, float centerY, float centerZ,float upX, float upY, float upZ)
上面参数的解释:
第一行中:rm:装有结果的投影矩阵;rmOffset:投影矩阵偏移量
第二行:指定相机的位置;
第三行:指定被观察物的位置:(相机位置点指向被观察物位置点,组成一个向量,这个就是相机的拍摄方向)
第四行:相机上方向。(我们可以想象成原始相机上面那个闪光灯的朝向)
OpenGL ES之九——相机和投影相关推荐
- Android OpenGL ES 学习(九) – 坐标系统和实现3D效果
OpenGL 学习教程 Android OpenGL ES 学习(一) – 基本概念 Android OpenGL ES 学习(二) – 图形渲染管线和GLSL Android OpenGL ES 学 ...
- OpenGL ES之三——绘制纯色背景
概述 这是一个系列的Android平台下OpenGl ES介绍,从最基本的使用最终到VR图的展示的实现,属于基础篇.(后面针对VR视频会再有几篇文章,属于进阶篇) OpenGL ES之一--概念扫盲 ...
- OpenGL ES之十——纹理贴图(展示一张图片)
概述 这是一个系列的Android平台下OpenGl ES介绍,从最基本的使用最终到VR图的展示的实现,属于基础篇.(后面针对VR视频会再有几篇文章,属于进阶篇) OpenGL ES之一--概念扫盲 ...
- OpenGL ES总结(一)OpenGL 初识
转载请把头部出处链接和尾部二维码一起转载,本文出自逆流的鱼yuiop:http://blog.csdn.net/hejjunlin/article/details/61615215 OpenGL是在图 ...
- 图片和图形之OpenGL ES(8)
原文 概要 Android包含对开放图形库(OpenGL®),特别是OpenGL ES API的高性能2D和3D图形的支持.OpenGL是一个跨平台的图形API,它为3D图形处理硬件指定了一个标准的软 ...
- Android OpenGL ES 学习(十二) - MediaCodec + OpenGL 解析H264视频+滤镜
OpenGL 学习教程 Android OpenGL ES 学习(一) – 基本概念 Android OpenGL ES 学习(二) – 图形渲染管线和GLSL Android OpenGL ES 学 ...
- Android OpenGL ES 学习(十一) –渲染YUV视频以及视频抖音特效
OpenGL 学习教程 Android OpenGL ES 学习(一) – 基本概念 Android OpenGL ES 学习(二) – 图形渲染管线和GLSL Android OpenGL ES 学 ...
- Android OpenGL ES 学习(十) – GLSurfaceView 源码解析GL线程以及自定义 EGL
OpenGL 学习教程 Android OpenGL ES 学习(一) – 基本概念 Android OpenGL ES 学习(二) – 图形渲染管线和GLSL Android OpenGL ES 学 ...
- 使用Android OpenGL ES 2.0绘图之四:应用投影和相机视图
传送门☞Android兵器谱☞转载请注明☞http://blog.csdn.net/leverage_1229 传送门☞系统架构设计☞转载请注明☞http://blog.csdn.net/levera ...
最新文章
- adobexd怎么录屏_请问如何使用Adobe XD制作应用动效?
- JavaScript——判断undefined解决方案
- DataGrid单击行时改变颜色
- JAVA数据类型及字符编码
- Server操作Mxd文件详细讲解
- PHP开发框架[国内框架]
- pexpect与fabric
- 2018 最强“弱密码”排行榜新鲜出炉,123456 再登首
- Python模块安装:Python3安装pdfminer3k
- 几款电子教室软件推荐
- 东南亚电商lazadashopee平台怎么开店,需要什么条件?
- 电脑可以上QQ但是打不开网页
- 使用u盘如何装linux系统教程视频教程,如何使用u盘安装linux系统
- 从战略到执行:业务领先模型 BLM 战略篇「市场洞察」
- Thinkphp3.2(tp3.2) sql语句表达式查询字符列表【eq,neq,gt,egt,lt,elt,in,between,like,exp】
- BERTILO发“富”啦,来元代艺数get你的专属「招财兔」!
- 为何电动汽车没未来感?设计和生产线无根本性改变 | 行业
- Hibernate的事务级别控制与查询对象的API(Query查询与Criterial查询+离线查询)
- 技侦十所 技侦科技局
- 2022年6月大学英语六级翻译