今天开始正式的 Android 音视频技术的学习,根据前面的分析,先来学习图片相关的处理 - OpenGL ES 2.0。
OpenGL ES 简介
OpenGL (全写 Open Graphics Library) 是指定义了一个跨编程语言、跨平台的编程接口规格的专业的图形程序接口。它用于三维图像 (二维的亦可),是一个功能强大,调用方便的底层图形库。
OpenGL 在不同的平台上有不同的实现,但是它定义好了专业的程序接口,不同的平台都是遵照该接口来进行实现的,思想完全相同,方法名也是一致的,所以使用时也基本一致,只需要根据不同的语言环境稍有不同而已。OpenGL 这套 3D 图形 API 从1992 年发布的 1.0 版本到目前最新 2014 年发布的 4.5 版本,在众多平台上多有着广泛的使用。
OpenGL ES (OpenGL for Embedded Systems) 是 OpenGL 三维图形 API 的子集,针对手机、PDA 和游戏主机等嵌入式设备而设计。OpenGL ES 相对于 OpenGL 来说,减少了许多不是必须的方法和数据类型,去掉了不必须的功能,对代价大的功能做了限制,比 OpenGL 更为轻量。在 OpenGL ES 的世界里,没有四边形、多边形,无论多复杂的图形都是由点、线和三角形组成的,也去除了 glBegin/glEnd 等方法。
OpenGL ES 可以做什么?
OpenGL ES 强大的渲染能力使其成为我们在嵌入式设备上进行图形处理的优良选择,我们经常使用的场景有:
- 图片处理。比如图片色调转换、美颜等。
- 摄像头预览效果处理。比如美颜相机、恶搞相机等。
- 视频处理。摄像头预览效果处理可以,这个自然也不在话下了。
- 3D游戏。比如神庙逃亡、都市赛车等。
OpenGL ES 版本及 Android 支持情况
OpenGL ES 当前主要版本有 1.0/1.1/2.0/3.0/3.1。这些版本的主要情况如下:
- OpenGL ES 1.0 是基于 OpenGL 1.3 的,OpenGL ES 1.1 是基于 OpenGL 1.5 的。Android 1.0 和更高的版本支持这个 API 规范,OpenGL ES 1.x 是针对固定硬件管线的。
- OpenGL ES 2.0 是基于 OpenGL 2.0 的,不兼容 OpenGL ES 1.x。Android 2.2 (API 8) 和更高的版本支持这个 API 规范,OpenGL ES 2.x 是针对可编程硬件管线的。
- OpenGL ES 3.0 的技术特性几乎完全来自 OpenGL 3.x 的,向下兼容 OpenGL ES 2.x。Android 4.3 (API 18) 及更高的版本支持这个 API 规范。
- OpenGL ES 3.1 基本上可以属于 OpenGL 4.x 的子集,向下兼容 OpenGL ES 3.0/2.0。Android 5.0 (API 21) 和更高的版本支持这个 API 规范。
OpenGL ES 2.0 中几个概念
学习 OpenGL ES 2.0 需要知道 OpenGL ES 2.0 相关的一些概念及知识。 在上段中提到了 OpenGL ES 2.0 相对 1.x 全新的两个重要东西:顶点着色器和片元着色器。
顶点着色器
着色器 (Shader) 是在 GPU 上运行的小程序。从名称可以看出,可通过处理它们来处理顶点。此程序使用 OpenGL ES SL 语言来编写,它是一个描述顶点或像素特性的简单程序。
对于发送给 GPU 的每一个顶点,都要执行一次顶点着色器。其功能是把每个顶点在虚拟空间中的三维坐标变换为可以在屏幕上显示的二维坐标,并带有用于 z-buffer 的深度信息。顶点着色器可以操作的属性有:位置、颜色、纹理坐标,但是不能创建新的顶点。 顶点着色器的输入输出模型如下:
片元着色器
片元着色器计算每个像素的颜色和其它属性。它通过应用光照值、凹凸贴图,阴影,镜面高光,半透明等处理来计算像素的颜色并输出。它也可改变像素的深度 (z-buffering) 或在多个渲染目标被激活的状态下输出多种颜色。一个片元着色器不能产生复杂的效果,因为它只在一个像素上进行操作,而不知道场景的几何形状。 片元着色器的输入输出模型如下:
着色器语言
着色器语言 (Shading Language) 是一种高级的图形编程语言,仅适合于 GPU 编程,其源自应用广泛的 C 语言。对于顶点着色器和片元着色器的开发都需要用到着色器语言进行开发,它是面向过程的而非面向对象。
坐标系
OpenGL ES 采用的是右手坐标,选取屏幕中心为原点,从原点到屏幕边缘默认长度为 1,也就是说默认情况下,从原点到 (1,0,0) 的距离和到 (0,1,0) 的距离在屏幕上展示的并不相同。即向右为 X 正轴方向,向左为 X 负轴方向,向上为 Y 轴正轴方向,向下为 Y 轴负轴方向,屏幕面垂直向上为 Z 轴正轴方向,垂直向下为 Z 轴负轴方向。
图形的绘制
前面提到 OpenGL ES 2.0 的世界里面只有点、线、三角形,其它更为复杂的几何形状都是由三角形构成的。包括正方形、圆形、正方体、球体等。但是其他更为复杂的物体,我们不可能都自己去用三角形构建,这个时候就需要通过加载利用其他软件 (比如3DMax) 构建的 3D 模型。
投影
OpenGL ES 的世界是 3D 的,但是手机屏幕能够给我展示的终究是一个平面,只不过是在绘制的过程中利用色彩和线条让画面呈现出 3D 的效果。OpenGL ES 将这种从 3D 到 2D 的转换过程利用投影的方式使计算相对使用者来说变得简单可设置。
OpenGL ES 中有两种投影方式:正交投影和透视投影。正交投影,物体不会随距离观测点的位置而大小发生变化。而透视投影,距离观测点越远,物体越小,距离观测点越近,物体越大。
光照
如果利用直接给出颜色的方式来对 3D 场景中的物体进行着色渲染,很难使 3D 场景拥有较强的真实感。一般来说,曲面物体比平面物体更能体现出光照效果。想用数学模型完全模拟真实世界的光照情况是很难的,而 OpenGL ES 2.0 采用的光照模型相对真实世界的光照是进行了很大的简化。在 OpenGL ES 2.0 中,光照由三种元素组成 (也可以说是三种通道组成),分别为环境光、镜面光及散射光。
纹理映射
现实世界中的物体往往是绚丽多彩的,要模拟现实世界的绚丽多彩,绘制出更加真实、酷炫的 3D 物体,就需要用到纹理映射了。纹理映射是将 2D 的纹理映射到 3D 场景中的立体物体上。
网友评论