1. OpenGL vs OpenGL ES vs OpenCV vs Metal
-
OpenGL(Open Graphics Library) 是一个跨平台的编程图形程序接口,它将计算机的资源抽象称为一个个
OpenGL
的对象,对这些资源的操作,抽象成一个个的OpenGl
指令。OpenGL
常用于CAD、虚拟现实、科学可视化程序和电子游戏开发。 -
OpenGL ES(OpenGL for Embedded Systems) 是以手持和嵌入式设备为目标的高级3D图形应用程序编程接口,是OpenGL三维图形API的子集,但去除了许多不必要和性能较低的API接口。
它是当今智能手机中占据统治地位的图形API。Android 4.3以上版本的设备和使用iOS7的iphone5s已经支持OpenGL ES 3.0.
-
OpenCV(Open Source Computer Vision Library),是一个跨平台的计算机视觉库。
OpenCV
是由英特尔公司发起并参与开发,以BSD许可证授权发行,可以在商业和研究领域中免费使用。OpenCV
可用于开发实时的图像处理、计算机视觉以及模式识别程序。(来自维基百科)和
OpenGL
相比,OpenCV
主要是图像识别,而OpenGL
主要处理的是图形渲染 -
Metal是苹果为了解决3D渲染而推出的框架。相比
OpenGL ES
,它拥有更高效的GPU交互,更低的CPU负,且支持多线程操作,以及线程之间资源共享能力。支持资源和同步的控制。iOS12开始,苹果已经弃用OpenGL ES。
2. OpenGL 上下文(context)
-
概念
在应用程序调用任何
OpenGL
的指令之前,需要首先创建一个OpenGL
的上下问,这个上下文是一个非常庞大的状态机,保存了OpenGL
中的各种状态,这也是OpenGl
指令执行的基础。 它就相当于一个配置文件或者状态机。主要的功能就是记录某些功能是否开启。 -
使用注意
切换上下文往往会产生较大的开销,但是不同的绘制模块,可能需要使用完全独立的状态管理。因此,可以在应用程序中分别创建多个不同的上下文,在不同线程中使用不同的上下文,上下文之间共享纹理、缓冲区等资源。这样的方案会比反复切换上下文,或者大量修改渲染状态更加合理高效的。
3. 渲染
把图片,按钮等显示在屏幕上的过程
4. 位图
png/jpg经过解压,就能生成位图。在iOS中,解压生成位图主要通过CoreGraphics
实现。120 x 120 分辨率的图片,经过解压缩的大小为: 120 * 120 * 4字节(RGBA)
5. 管线
管线可以理解为一个流水线。在OpenGL
中可分为固定管线和可编程管线。固定管线类似调用系统的API,我们只能修改传入的参数。而可编程管线,我们可以添加自定义逻辑。
OpenGL ES3.0
的可编程管线如下图所示:
大致流程可描述为:顶点数组->顶点着色器->图元装配->光栅化->片段着色器->逐片段操作->帧缓冲区
其中,顶点着色器和片段着色器是我们可以进行自定义编程的阶段。
6. 顶点着色器
顶点着色器实现了顶点操作的通用可编程方法。每个顶点数据都会执行一次顶点着色器。
输入包括:
- 着色器程序
- attribute
- 统一变量(uniform)
- 采样器(纹理数据)
作用:
- 确定位置
- 缩放/平移/旋转位置换算
- 投影换算(手机显示3D数据时候使用到的透视投影)
7. 图元装配
图元是三角形、直线或者点等几何对象。图元装配可以理解为把顶点数据组合生成这些图元的过程。
8. 光栅化
光栅化是将上一阶段生成的图元转化为一组二维片段(像素)的过程,然后,这些片段由片段(像素)着色器进行处理
9. 片段着色器(像素着色器)
片段着色器为片段上的操作实现了通用的可编程方法。我们可以在片段着色器中自定义每一个像素的显示。
和顶点着色器相比,片段着色器不接受attribute的输入。
10.逐片段操作
在逐片段操作阶段,在每个片段上执行如下图所示功能:
在逐片段操作的最后,片段或者被拒绝,或者在帧缓冲区相应位置写入片段的颜色、深度或者模版值
11. GLSL语言
GLSL(OpenGL Shading Language),是用来在OpenGL中着色编程的语言,也即开发人员写的短小的自定义程序。代码类似:
NSString *const kGPUImageBeautifyFragmentShaderString = SHADER_STRING
(
varying highp vec2 textureCoordinate;
....
uniform lowp vec4 mask;
void main()
{
highp vec4 bilateral = texture2D(inputImageTexture, textureCoordinate);
highp vec4 canny = texture2D(inputImageTexture2, textureCoordinate2);
highp vec4 origin = texture2D(inputImageTexture3,textureCoordinate3);
....
if(gl_FragCoord.x < (mask.x + mask.z) && gl_FragCoord.y < (mask.y + mask.w) && gl_FragCoord.x > mask.x && gl_FragCoord.y > mask.y) {
gl_FragColor = smooth;
}else {
gl_FragColor = origin;
}
}
);
12. 投影方式
OpenGL中,投影方式可以分为两种,一种为正投影,一种为透视投影。如下图所示
- 正投影下,图片不管远近都是1:1进行绘制,主要用于显示2D图形
- 透视投影,实现远小近大的效果,主要用于3D效果
13. 未完待续
14. 参考
- 逻辑教育
- 维基百科
- 《OpenGL ES 3.0 编程指南》