OpenGL-ES (OpenGL for Embedded Systems)
作为OpenGL的子集,OpenGL-ES专为移动端的图像显示而生,其针对于手机等嵌入式设备所进行了定制与优化,使移动端的设备图像加载更高效,3D图像的渲染更快速,质量更高
渲染模块
同桌面端设备一样,移动端OpenGL-ES的渲染也是由CPU和GPU协同完成的,CPU负责调动OpenGL模块,并将顶点数据由内存中取出并传入GPU中,GPU负责将顶点数据进行处理,并执行渲染操作。
渲染流程
![[9].专属Mobile的OpenGL-OpenGLES - 图1](/uploads/projects/nanziyaonulibenpao@uyzg7e/3cd4ccd4d6337958e2b3c7683e03d281.png)
顶点着色器
- 通过`attribute通道`负责接收`CPU`传递来的顶点信息(在iOS中,为了稳定性,默认将attribute通道关闭)- 通过`uniform通道`统一变量,并进行后续处理- 通过`采集器`来对`纹理`进行处理- 通过GLSL内建变量,将顶点数据处理成需要的形式(`gl_Position`),并使用- 通过特定语法,修改点的大小- 通过矩阵变换,获取真正坐标- 计算光照信息- 生成纹理坐标并传递给片元着色器
图元装配
计算顶点信息,将`顶点数据`计算为多个`图元`
光栅化
将`图元`转换为`片段`,为后续`片元着色器`的工作做准备
片元着色器
- 通过uniform通道统一变量,以便于后续处理- 接收顶点着色器传递来的`纹理坐标`,计算纹理坐标的填充颜色,并对纹理坐标的像素点进行颜色填充
逐片段操作
![[9].专属Mobile的OpenGL-OpenGLES - 图2](/uploads/projects/nanziyaonulibenpao@uyzg7e/40bcbdfa05855be54b88819895dd98f8.png)
逐片段操作是由OpenGL-ES内部所完成的,其最终将图像数据放到帧缓冲区,显示于屏幕上
EGL(Embedded Graphics Library)
EGL
针对于移动端,OpenGL-ES需要设定新的命令来链接窗口,因此需要一个新的库来执行这个操作,这个库就是EGL, EGL 是OpenGL-ES 和原⽣窗⼝系统之间的接口
EAGL
出于Apple一贯精益求精的精神,apple当然不满足EGL的效率,因此apple自己研发了一个库用于替代`EGL`,这个库就是`EAGL`
GLSL(OpenGL着色器语言)
着色器
着色器是使用一种叫GLSL的类C语言写成的。GLSL是为图形计算量身定制的,它包含一些针对向量和矩阵操作的有用特性。
着色器的开头总是要声明版本,接着是输入和输出变量、uniform和main函数。每个着色器的入口点都是main函数,在这个函数中我们处理所有的输入变量,并将结果输出到输出变量中。
向量
GLSL中的向量是一个可以包含有1、2、3或者4个分量的容器,分量的类型可以是前面默认基础类型的任意一个。它们可以是下面的形式(n代表分量的数量):
| 类型 | 含义 |
|---|---|
vec n |
包含n个float分量的默认向量 |
bvec n |
包含n个bool分量的向量 |
ivec n |
包含n个int分量的向量 |
uvec n |
包含n个unsigned int分量的向量 |
dvec n |
包含n个double分量的向量 |
向量重组
一个向量的分量可以通过vec.x这种方式获取,这里x是指这个向量的第一个分量。你可以分别使用.x、.y、.z和.w来获取它们的第1、2、3、4个分量。GLSL也允许你对颜色使用rgba,或是对纹理坐标使用stpq访问相同的分量。
vec2 someVec;vec4 differentVec = someVec.xyxx;vec3 anotherVec = differentVec.zyw;vec4 otherVec = someVec.xxxx + anotherVec.yxzy;
输入输出 in out
着色器是各自独立的小程序, 它们都是一个整体的一部分,每个着色器都有特定的输入和输出,这样使它们可以进行数据交流及传递。GLSL定义了in和out关键字专门来实现这个目的。每个着色器使用这两个关键字设定输入和输出,只要一个输出变量与下一个着色器阶段的输入匹配,它就会传递下去。
如果我们需要从一个着色器向另一个着色器发送数据,我们必须在发送方着色器中声明一个输出,在接收方着色器中声明一个类似的输入。当类型和名字都一样的时候,OpenGL就会把两个变量链接到一起,它们之间就能发送数据了(这是在链接程序对象时完成的)。
varying uniform attribute
varying变量是 vertex shader 和 fragment shader 之间做数据传递用的。一般 vertex shader 修改 varying 变量的值,然后 fragment shader 使用该 varying 变量的值。因此 varying 变量在 vertex shader 和 fragment shader 二者之间的声明必须是一致的。
uniform 变量是外部程序传递给 vertex shader fragment shader 的变量。
attribute变量是只能在 vertex shader中使用的变量。
