OpenGL ES是使用在手机端和嵌入式里的3D图形应用程序编程接口,是跨平台的API。OpenGL ES是OpenGL的简化版本。
OpenGL2.x 版本相比 1.x 版本有较大差异,1.x 版本为 fixed function pipeline,即固定管线硬件,而 2.x 版本为 programmable pipeline,可编程管线硬件。
固定管线中原本由系统做的一部分工作,在可编程管线中必须需要自己写程序实现,具体程序为 vertex shader(顶点着色器)和 fragment shader(片元着色器)。
tips:图元装配、光栅化、逐片元操作和帧缓冲区是不由开发者参与的,OpenGL会自动计算。
1,顶点着色器
顶点着色器输出属性:
顶点着色器实际就是获取到最终的结果给gl_Position赋值,使得计算变换之后的顶点生效,也可以对gl_PointSize赋值更改点的大小。
顶点着色器功能:
总结: 它可以用于执行自定义计算,实施新的变换,照明或者传统的固定功能所不允许的基于顶点的效果。
attribute vec4 position; //attribute属性变量修饰符,vec4是数据类型表示四维向量,顶点坐标
attribute vec2 texCoordinate; //vec2二维向量,纹理坐标是二维纹理
uniform mat4 rotateMatrix; //uniform统一通道修饰符,mat4四行四列的矩阵,旋转矩阵
varying lowp vec2 varyTexCoord; //纹理坐标传递到片元着色器,通过varying通道传递,lowp表示低精度
void main() {
varyTexCoord = texCoordinate; //赋值后传递给片元着色器
vec4 vPos = position;
vPos = vPos * rotateMatrix; //每一个顶点与旋转矩阵相乘得到新的顶点
gl_Position = vPos; //赋值最终计算好的新顶点,gl_Position是内建变量,不需要定义只需要赋值
}
GPU并行计算顶点,三角形的3个顶点并行计算,上面的代码并行执行3次
2,图元装配
顶点着色器之后,下一个阶段就是图元装配,确定图形的形状。
三种图元(Primitive):点,线,三角形.
图元装配:将顶点数据计算成⼀个个图元.在这个阶段会执⾏裁剪、透视分割和 Viewport变换操作,这个过程开发者无法干预。
图元类型和顶点确定将被渲染的单独图元。对于每个单独图元及其对应的顶点,图元装配阶段执行的操作包括:将顶点着色器的输出值执行裁剪、透视分割、视角变换后进入光栅化阶段。
3,光栅化
确定图形在屏幕上的像素点
在这个阶段绘制对应的图元(点/线/三⻆形),光栅化就是将图元转化成一组二维片段的过程。而这些转化的片段将由片元着色处理。这些二维片段就是屏幕上可绘制的像素.
4,片元着色器
片元着色器输出颜色:
片元着色器是输出颜色,通过计算颜色混合等最终输出一个像素点的颜色赋值给gl_FragColor,让对应的这一个像素点得到一种颜色。
片元着色器功能:
总结: 它可以用于图片/视频/图形中每个像素的颜色填充(比如给视频添加滤镜,实际上就是将视频中每个图片的像素点颜色填充进行修改.)
varying lowp vec2 varyTexCoord; //从顶点着色器传过来的纹理坐标,需要与顶点着色器的定义完全一致
uniform sampler2D colorMap; //由客户端通过uniform传递过来的纹理采样器,拿到对应的纹理颜色值,取得纹素
void main() {
//texture2D(纹理采样器, 纹理坐标);获取对应位置对应坐标上的颜色值,取得纹素
gl_FragColor = texture2D(colorMap, varyTexCoord); //gl_FragColor内建变量赋值,类型是vec4四维向量
}
片元着色器执行次数跟图片像素点的个数一样,并行执行每一个像素点获取颜色,让每一个像素点得到颜色值。
5,逐片段操作
片元着色器取出颜色后,进行逐片段操作
拿到片段数据之后执行像素归属测试
OpenGL 是一个仅仅关注图像渲染的图像接口库,在渲染过程中它需要将顶点信息、纹理信息、编译好的着色器等渲染状态信息存储起来,而存储这些信息的数据结构就可以看作 OpenGL 的上下文。
调用任何 OpenGL 函数前,必须已经创建了 OpenGL Context,GL Context 存储了OpenGL 的状态变量以及其他渲染有关的信息。OpenGL 是个状态机,有很多状态变量,是个标准的过程式操作过程,改变状态会影响后续所有操作,这和面向对象的解耦原则不符,毕竟渲染本身就是个复杂的过程。OpenGL 采用 Client-Server 模型来解释 OpenGL 程序,即 Server 存储 GL Context(可能不止一个),Client 提出渲染请求,Server 给予响应,一般 Server 和 Client 都在我们的 PC 上,但 Server 和 Client 也可以是通过网络连接。
之后的渲染工作就要依赖这些渲染状态信息来完成,当一个上下文被销毁时,它所对应的 OpenGL 渲染工作也将结束。
在 OpenGL 的设计中,OpenGL 是不负责管理窗口的,窗口的管理交由各个设备自己来完成,具体来讲,IOS 平台上使用 EAGL 提供本地平台对 OpenGL 的实现,在 Android 平台上使用 EGL 提供本地平台对 OpenGL 的实现。EGL 是 OpenGL ES 和 Android 底层平台视窗系统之间的接口,在 OpenGL 的输出与设备屏幕之间架接起一个桥梁,承担了为 OpenGL 提供上下文环境以及管理窗口的职责。
EGL 为双缓冲工作模式,即有一个 Back Frame Buffer 和一个 Front Frame Buffer,正常绘制的目标都是 Back Frame Buffer,绘制完成后再调用 eglSwapBuffer API,将绘制完毕的 FrameBuffer 交换到 Front Frame Buffer 并显示出来。
从代码层面来看,OpenGL ES 的 opengles 包下定义了平台无关的绘图指令,EGL(javax.microedition.khronos.egl)则定义了控制 displays,contexts 以及 surfaces 的统一的平台接口。