OpenGLES
在Android下进行视频渲染使用的是 OpenGLES。OpenGLES(OpenGL for Embedded Systems)就是用在嵌入式系统中的 OpenGL。
OpenGL是一个非常庞大而又专业的知识,如果想完全撑握它需要花不少时间。而视频渲染只用到了OpenGL的一小部分知识,所以我们就采取用多少学多少的办法,这样可以让我们更专注于音视频直播技术。
但即使这样,我们还是要先补习一些数据的基本知识。如果没有这些基础,我们是无法理解视频渲染过程的。
图像渲染过程
一般将一个3D图像显示在2D的平面上需要三个步骤的距阵变换,我们称之为MVP,即模型(Model), 观察(View)以及投影(Projection)。
- 模型:将要显示的3D物体从模型坐标系变成世界坐标系。
- 观察:将3D物体从世界坐标系变换成从人眼角度看到物体的坐标系。
- 投影:就是将3D坐标系换成2D坐标系。也就是3D物理如何在2D平面上展示。即我们通常说的降维。
下面我们介绍下实现 MVP 转换需要的数学知识。
距阵
在三维图形学用(x,y,z,w)代表一个顶点,它是一个齐次坐标。
- 其中的 x,y 我们都知道是横轴和纵轴。
- z 代表深度,比如按右手坐标来说,离我们眼睛越远的深度越深,z值也就越小。
- w 是为了距阵做乘法运算而增加的。
因此,我们在三维图形学中只用到4x4矩阵,它能对顶点(x,y,z,w)作变换。顶点变换使用距阵左乘的方法,其公式如下:
矩阵 x 顶点 = 变换后的顶点。
距阵左乘
左手指着a,右手指着x,得到ax。 左手移向右边一个数b,右手移向下一个数y,得到by。依次类推,就得到了右边的结果。
距阵的平移
有个 4x4 的距阵,如下:
平移距阵
其中,X、Y、Z是点的位移增量。例如,若想把向量(10, 10, 10, 1)沿X轴方向平移10个单位,可得:
平移运算
距阵的缩放
有个 4x4 的距阵,如下:
缩放距阵
如果想把一个向量沿各方向放大2倍,可得:
缩放运算
是不是很神奇?
距阵的旋转
旋转矩阵比较复杂,绕 X 轴旋转使用的距阵:
绕X轴旋转
绕 Y 轴旋转使用的距阵:
绕Y轴旋转
绕 Z 轴旋转使用的距阵:
绕Y轴旋转
累积距阵变换
前面已经学习了如何旋转、平移和缩放向量。把这些矩阵相乘就能将它们组合起来,例如:
TransformedVector = TranslationMatrix * RotationMatrix * ScaleMatrix * OriginalVector;
这行代码首先执行缩放,接着旋转,最后才是平移。这就是矩阵乘法的工作方式。
另外,变换的顺序不同,得出的结果也不同。所以,顺序不能乱。
距阵的正投影
正投影矩阵也比较复杂,我们这里直接给出,大家可以在网上查找相关资料,自己推导出这个距阵:
正投影距阵
小结
上面介绍了三维图型学中需要的一些数学基础知识。OpenGL也是按照上面的数学知识进行绘图的。当然,在编写OpenGL程序时,不需要直接写这些数学公式,OpenGL已经为我们提供了非常方便的函数,我们只需要调用就行了。但为了便于我们对图型的理解,这些基础知识还是非常必要的。
参考
- 齐次坐标。
- 搞懂 OpenGL 矩阵转换
- 距阵