OpenGL-ES (OpenGL for Embedded Systems)
作为OpenGL的子集,OpenGL-ES专为移动端的图像显示而生,其针对于手机等嵌入式设备所进行了定制与优化,使移动端的设备图像加载更高效,3D图像的渲染更快速,质量更高
渲染模块
同桌面端设备一样,移动端OpenGL-ES的渲染也是由CPU
和GPU
协同完成的,CPU
负责调动OpenGL模块,并将顶点数据
由内存中取出并传入GPU
中,GPU
负责将顶点数据进行处理,并执行渲染
操作。
渲染流程
OpenGL-ES渲染流程
顶点着色器
- 通过`attribute通道`负责接收`CPU`传递来的顶点信息(在iOS中,为了稳定性,默认将attribute通道关闭)
- 通过`uniform通道`统一变量,并进行后续处理
- 通过`采集器`来对`纹理`进行处理
- 通过GLSL内建变量,将顶点数据处理成需要的形式(`gl_Position`),并使用
- 通过特定语法,修改点的大小
- 通过矩阵变换,获取真正坐标
- 计算光照信息
- 生成纹理坐标并传递给片元着色器
图元装配
计算顶点信息,将`顶点数据`计算为多个`图元`
光栅化
将`图元`转换为`片段`,为后续`片元着色器`的工作做准备
片元着色器
- 通过uniform通道统一变量,以便于后续处理
- 接收顶点着色器传递来的`纹理坐标`,计算纹理坐标的填充颜色,并对纹理坐标的像素点进行颜色填充
逐片段操作
逐片段操作
逐片段操作是由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
中使用的变量。
网友评论