OpenGL 01 - 基础概念

256 阅读5分钟

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. 顶点着色器

顶点着色器实现了顶点操作的通用可编程方法。每个顶点数据都会执行一次顶点着色器。

输入包括:

  1. 着色器程序
  2. attribute
  3. 统一变量(uniform)
  4. 采样器(纹理数据)

作用:

  1. 确定位置
  2. 缩放/平移/旋转位置换算
  3. 投影换算(手机显示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. 参考

  1. 逻辑教育
  2. 维基百科
  3. 《OpenGL ES 3.0 编程指南》