初始OpenGL ES
OpenGL ES (OpenGL For Embedded Systems) 是OpenGL 三维图形API 的子集。是以手持和嵌入式为目标的高级3D图形应用程序编程接口。
OpenGL ES是目前智能手机占据统治地位的图形API,用于可视化的二维和三维数据。可以使用OpenGL 配置3D图形管道并向其提交数据。顶点被变换和点亮,组合成图元,并光栅化以创建2D图像。
iOS下的OpenGL ES
OpenGL ES允许应用程序利用底层图形处理器的强大功能。iOS设备上的GPU可以执行复制的2D和3D绘图,以及最终图像中每个像素的复杂着色计算。
cpugpu2xpngOpenGL ES3.0 图形管线
OpenGL ES30图形管线jpgApple官方文档图示如下
applicationpipeline2xpngOpenGL ES下的顶点着色器
- 着色器程序 描述顶点上执行操作的顶点着色器程序源代码/可执行文件
- 顶点着色器输入【属性】 用顶点数组提供每个顶点的数据
- 统一变量【uniform】 顶点/片元着色器使用的不变数据。
- 采样器 代表顶点着色器使用纹理的特殊统一变量类型
顶点着色器业务
- 矩阵变换位置
- 计算光照公式生成逐顶点颜色
- 生成/变换纹理坐标
总结:它可以用于执行自定义计算,实施新的变换,照明或者传统的固定功能所不允许的基于顶点的效果。
顶点着色器代码案例
attribute vec4 position;
attribute vec2 textCoordinate;
uniform mat4 rotateMatrix;
varying lowp vec2 varyTextCoord;
void main()
{
varyTextCoord = textCoordinate;
vec4 vPos = position;
vPos = vPos * rotateMatrix;
gl_Position = vPos;
}
将顶点坐标赋值给内建变量gl_positon
图元装配、光栅化
图元装配
将顶点数据计算成⼀个个图元.在这个阶段会执⾏裁剪、透视分割和Viewport变换操作。图元类型和顶点索确定将被渲染的单独图元。对于每个单独图元及其对应的顶点,图元装配阶段执⾏的操作包括:将顶点着⾊器的输出值执⾏裁剪、透视分割、视⼝变换后进⼊光栅化阶段。
光栅化
在这个阶段绘制对应的图元(点/线/三⻆形). 光栅化就是将图元转化成⼀组⼆维⽚段
的过程.⽽这些转化的⽚段将由⽚元着⾊器处理.这些⼆维⽚段就是屏幕上可绘制的像素。
片元着色器
- 着色器程序 描述顶点上执行操作的顶点着色器程序源代码/可执行文件
- 顶点着色器输入【属性】 用顶点数组提供每个顶点的数据
- 统一变量【uniform】 顶点/片元着色器使用的不变数据。
- 采样器 代表顶点着色器使用纹理的特殊统一变量类型
片元着色器业务
- 计算颜⾊
- 获取纹理值
- 往像素点中填充颜⾊值(纹理值/颜⾊值);
总结: 它可以⽤于图⽚/视频/图形中每个像素的颜⾊填充(⽐如给视频添加滤镜,实际上就是将视频中每个图⽚的像素点颜⾊填充进⾏修改。
片元着色器代码案例
varying lowp vec2 varyTextCoord;
uniform sampler2D colorMap;
void main()
{
gl_FragColor = texture2D(colorMap, varyTextCoord);
}
片元着色器中将最终返回的颜色值赋值给内建变量gl_FragColor
顶点缓冲区(VBO)
关于顶点缓冲区
在矩形绘制过程中,使用到了VBO
,即Vertex Buffer Object
,可视为GPU中的一块缓冲区buffer,用于存储顶点的所有信息。OpenGL在GPU中记录着这个VBO的id和对应的显存地址(或地址偏移)。 绘制图形的过程,实际上就是将内存中的信息拷贝到GPU中。而频繁地在CPU/GPU之间传递数据的效率很低,因此可使用VBO缓存顶点数据,只在初始化缓冲区及在顶点数据有变化时才需要对该缓冲区进行操作,能大大减少CPU/GPU之间的数据拷贝开销。
创建顶点缓冲区
GLuint bufferID;
glGenBuffers(1,&bufferID);
绑定顶点缓冲区
glBindBuffer (GLenum target, GLuint buffer)
拷贝顶点数据至缓冲区
GLenum usage
参数
STREAM | STATIC | DYNAMIC |
---|---|---|
GL_STREAM_DRAW |
GL_STATIC_DRAW |
GL_DYNAMIC_DRAW |
GL_STREAM_READ |
GL_STATIC_READ |
GL_DYNAMIC_READ |
GL_STREAM_COPY |
GL_STATIC_COPY |
GL_DYNAMIC_COPY |
”static“表示VBO中的数据将不会被改动(一次指定多次使用),
”dynamic“表示数据将会被频繁改动(反复指定与使用),
”stream“表示每帧数据都要改变(一次指定一次使用)。
”draw“表示数据将被发送到GPU以待绘制(应用程序到GL),
”read“表示数据将被客户端程序读取(GL到应用程序),”
glBufferData (GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage)
OpenGL ES的应用
图片滤镜
- 获取图片中的每一个像素点
- 像素点做饱和度处理
- 得到新的颜色
- 将新的颜色翻入帧缓存区
- 最后进行显示
视频滤镜
原理以及处理方式是一样的(GLSL代码),视频也是一帧一帧处理的,而一帧就是一张图片
- 获得视频MP4文件
- 拿到h264(视频压缩文件)
- 将视频解码(解压),还原成一帧一帧的图片
- 针对一帧一帧的图片进行处理
逐片段操作
像素归属测试
确定帧缓存区中位置(Xw,Yw)的像素⽬前是不是归属于OpenGL ES所有. 例如,如果⼀个显示OpenGL ES帧缓存区View被另外⼀个View 所遮蔽.则窗⼝系统可以确定被遮蔽的像素不属于OpenGL ES 上下⽂.从⽽不全显示这些像素. ⽽像素归属测试是OpenGL ES 的⼀部分,它不由开发者开⼈为控制,⽽是由OpenGL ES 内部进⾏。
裁剪测试
裁剪测试确定(Xw,Yw)是否位于作为OpenGL ES状态的⼀部分裁剪矩形范围内,如果该⽚段位于裁剪区域之外,则被抛弃。
深度测试
输⼊⽚段的深度值进步⽐较,确定⽚段是否拒绝测试
混合
混合将新⽣成的⽚段颜⾊与保存在帧缓存的位置的颜⾊值组合起来.
抖动
抖动可⽤于最⼩化因为使⽤有限精度在帧缓存区中保存颜⾊值⽽产⽣的伪像.
EGL(Embedded Graphics Library)
- OpenGL ES 命令需要
渲染上下⽂
和绘制表面
才能完成图形图像的绘制 - 渲染上下⽂: 存储相关OpenGL ES状态,是一个状态机
- 绘制表面:⽤于绘制图元的表面,需要指定渲染的缓存区,例如颜⾊缓、深度和模板
- OpenGL ES API 并没有提供如何创建渲染上下文或者上下文如何连接到原生窗口系 统. EGL 是Khronos 渲染API(如OpenGL ES) 和原⽣窗⼝系统之间的接⼝.
唯⼀支持 OpenGL ES 却不支持EGL的平台是iOS. Apple 提供⾃己的EGL API的iOS实现,称为EAGL
- 因为每个窗⼝系统都有不同的定义,所以EGL提供基本的不透明类型—EGLDisplay, 这 个类型封装了所有系统相关性,用于和原生窗⼝系统接⼝