OpenGL学习——概述

OpenGL是什么?用来干嘛的?想来一开始接触OpenGL的时候也是一脸懵逼。

OpenGL是什么?

我们从iOS的APP图形图像渲染基本流程来看一看它是什么。

OpenGL位于硬件驱动层和应用处理层之间,是一套相对底层的图形图像开发规范,由各个厂商在GPU驱动层以上实现一套相关操作的API。

OpenGL用来干嘛?

emmmmm…它是用来干嘛的呢?我们从它的操作粒度来理解它,它是基于GPU硬件驱动层的API,它直接操作的对象是显示屏幕上的每个像素点(Pixel)。我们可以利用这套API来操作屏幕上的每一个像素点的排列组合,颜色,深度等等来实现各种各样的图形图像。

总而言之,它是用来操作GPU显示图形图像的API。

OpenGL的基本概念

状态机

OpenGL自身是一个巨大的状态机(State Machine):一系列的变量描述OpenGL此刻应当如何运行。OpenGL的状态通常被称为OpenGL上下文(Context)。我们通常使用如下途径去更改OpenGL状态:设置选项,操作缓冲。最后,我们使用当前OpenGL上下文(Contex)来渲染。

OpenGL会保持状态,除非我们调用OpenGL函数来改变它。就像一个时间点的快照一样,除非对这个OpenGL的上下文进行修改,否则它呈现的内容是不会改变的。

每个OpenGL的上下文都是独立,我们在不同上下文做的工作是互不影响的,在实际操作过程中要注意是否在同一个上下文中。

渲染管线

Contex为我们提供OpenGL的运行环境,而具体的操作则是在OpenGL的渲染管线中进行的。这里的渲染管线是一次完整的图形图像渲染过程,OpenGL1.0对应的渲染管线是固定渲染管线。意味着开发者只能做一些简单操作,后面OpenGL2.0之后渲染管线升级为可编程渲染管线。其中可编程的部分是顶点着色器(Vertex Shader)和片段着色器(Fragament Shader)。
渲染管线的基本流程如下:

我们从头一个一个理解:

  1. 我们调用OpenGL的API给渲染管线填充顶点数组(所要绘制图形的坐标信息)然后OpenGL传递到该渲染管线的顶点着色器中,将坐标信息转换为OpenGL的内部坐标信息。
  2. OpenGL有了图形的坐标信息后就通过图元组装描绘出基本的图形。
  3. 通过光栅化将线性的图形映射到屏幕一个个像素(Pixel)上。
  4. 通过片段着色器给每个像素(Pixel)赋予颜色值。
  5. 最后将图像传递到帧缓冲(Framebuffer)中提供给屏幕进行刷新操作。

上面描述的就是OpenGL在渲染一个画面的大体流程。

A.顶点着色器(Vetex Shader)

负责坐标和图形的描述。在OpenGL中有三种基本的图形点、线、三角形,只能通过这三种基本图形去描述一个图形。其中在OpenGL中我们的显示区域位于x,y均为[-1,1]之内的空间。

  • :点存在于三维空间,坐标用(x,y,z)表示。
  • 线:由两个三维空间中的点组成。
  • 三角形:由三个三维空间的点组成。
B.图元装配

负责将顶点着色器输出的坐标信息进行组装和裁剪,将所有3D的图元转化为屏幕上2D的图元。

C.光栅化

到这一步我们已经为OpenGL描述了一个图形的样子,但是要转换为图像还需要颜色信息。在使用光栅化后基本图元被转换为供片段着色器使用的片段(Fragment),即实现通过插值运算将连续的值用一个个像素片段表示出来。

D.片段着色器(Fragament Shader)

到了这一步我们已经有了一个个的像素片段(Fragament),我们在这个阶段给它涂上颜色值就可以变成一个完整的像素点。包括位置,颜色,纹理坐标等信息。同时我们可以编写Fragament Shader的脚本来实现对每个像素颜色的变换来达到一些效果,如纹理贴图,光照,环境光,阴影。

E.片段测试

这个阶段是对每个像素点进行测试保证这些像素点是正确可用的。最后在输入到帧缓冲(Frambuffer)中。

F.帧缓存 (Framebuffer)

经过上述处理流程,我们想要看到的图形图像数据最后都会存储到帧缓存区(Framebuffer)中。我们可以同时存在很多帧缓存(Framebuffer),并且可以通过OpenGL让GPU把渲染结果存储到任意数量的帧缓存中(这里引申出一个离屏渲染的工作概念)。
但是,只有将内容绘制到视窗体提供的帧缓存(Renderbuffer)中,才能将内容输出到显示设备。在实现上渲染缓存(Renderbuffer)是直接跟屏幕映射的,可以绕开CPU进行工作。

G.渲染帧缓存(Renderbuffer)

基本工作原理是存在两个缓存(前缓存和后缓存),当屏幕的刷新同步信号到达时让系统将后缓存交换到前缓存区上。
这个刷新的时间是由系统决定的,比如在iOS中屏幕刷新率是60fps即每16.75ms会发生一次前后缓存的交换。我们只需要准备好后缓存的数据提供给系统就能进行屏幕刷新渲染了。

总结

这篇文章主要是总结一下我对OpenGL整体工作流程的理解,首先OpenGL是用来操作GPU进行图形图像渲染工作的,它的操作粒度可以到每个像素点,同时它是直接操作GPU硬件工作的。而之后的工作核心(2D图形图像渲染)基本是集中在对顶点着色器和片段着色器的脚本实现上(酷炫的滤镜效果和动画效果)。