OpenGL(Open Graphics Library)开放图形库
OpenGL是用于渲染2D、3D矢量图形的跨语言、跨平台的应用程序编程接口(API)。接口由350多个不同的函数调用组成,用来绘制从简单的图形比特到复杂的三维景象。
OpenGL ES(OpenGL for Embedded Systems)
OpenGL ES是OpenGL的子集,针对手机、PAD和游戏主机等嵌入式设备,祛除了许多不必要和性能较低的API接口。
Metal
Metal是2014年Apple为游戏开发者推出的新的平台技术,它能够为3D图像提高10倍的渲染性能。Metal是苹果专门为解决3D渲染而推出的框架。
图像API可以解决的问题
利用GPU芯片来高效渲染图形图像
- 游戏开发中,对于游戏场景/任务的渲染
- 音视频开发中,对于视频解码后的数据渲染
- 地图引擎对于地图上的数据渲染
- 动画的绘制
- 视频处理中,对于视频增加滤镜
OpenGL上下文(Context)
- 在应用程序调用
OpenGL指令之前,需要创建一个OpenGL的上下文。这个上下文是一个庞大的状态机,里面保存了一系列的变量来描述OpenGL此刻需要如何运行,保存了OpenGL的各种状态,这是OpenGL指令执行的基础。 OpenGL的函数是类似C语言一样面向过程的函数,本质上是对OpenGL上下文这个庞大的状态机中的某个状态或者对象进行操作。OpenGL切换上下文会产生比较大的开销,不同的绘制模块有可能需要完全独立的状态管理。因此可以在应用程序中创建多个不同的上下文,在不同的线程中使用不同的上下文,上下文之间共享纹理、缓冲区等资源。这样的方案可以避免反复切换上下文或者大量修改渲染状态,更加合理高效。
OpenGL状态机
- 状态机描述了一个对象在其生命周期内所经历的各种状态以及状态间的转变、发生转变的动因,条件以及转变中所执行的活动。
- 状态机可以根据输入的内容和自己的状态,修改自己的状态,并且可以得到输出。
- 可以进入某个特殊的状态如停机状态的时候,不再接收输入,停止工作。
glClearColor(1.0,1.0,1.0.1.0);
glEnable(GL_DEPTH_TEST);//开启深度测试
glDisable(GL_DEPTH_TEST);//关闭深度测试
glEnable(GL_BLEND);//开启混合
glDisable(GL_BLEND)//关闭混合
OpenGL可以保持自身的状态,除非用户输入一条命令让它改变状态。
渲染
将图形/图像数据转换成2D空间图像的操作叫做渲染(Rendering)
顶点数组和顶点缓冲区
OpenGL的图像都是由图元组成的,在OpenGL ES中,存在3中类型的图元:点、线段和三角形。顶点指的是当我们绘制一个图形时,它的顶点位置数据。这个数据可以存储在内存中,当调用绘制方法时,从内存传入顶点数据,被称为顶点数组。也可以提前分配一块显存,将顶点数据预先传入到显存当中,这部分显存,成为顶点缓冲区。
位图
A bitmap image (or sampled image) is an array of pixels (or samples). Each pixel represents a single point in the image. JPEG, TIFF, and PNG graphics files are examples of bitmap images.
位图就是一个像素数组,数组中的每个像素代表着图片中的一个点。我们在应用中经常用到的JPEG、PNG图片就是压缩后的位图。
管线(pipeline)
在OpenGL下渲染图形,会经历一个一个节点,这样的操作可以理解为管线。
- 固定管线/存储着色器:早期的
OpenGL版本封装了很多着色器程序块内置的一段包含了光照、坐标变换、裁剪等等诸多功能的固定Shader程序来帮助开发者完成程序的渲染,类似于封装好的API,开发者只需要传入相应的参数就能快速完成图形的渲染。 - 但是由于
OpenGL的使用场景非常丰富,固定管线或者存储着色器无法完成每一个业务,因此需要将相关部分开放成可编程。
着色器程序Shader
- 固定着色器/存储着色器:
OpenGL提供的固定的Shader - 自定义着色器:基于
GLSL语法生成的着色器程序
OpenGL在处理Shader时,和其他编译器一样,通过编译、链接等步骤,生成了着色器程序,着色器程序包含了顶点着色器和片元着色器的运算逻辑。
顶点着色器 (VertexShader)
- ⼀般⽤来处理图形每个顶点变换(旋转/平移/投影等)
- 是用于计算顶点属性的程序。顶点着⾊器是逐顶点运 算的程序,也就是说每个顶点数据都会执⾏⼀次顶点着⾊器,当然这是并 ⾏的,并且顶点着⾊器运算过程中⽆法访问其他顶点的数据
- ⼀般来说典型的需要计算的顶点属性主要包括顶点坐标变换、逐顶点光照 运算等等。顶点坐标由⾃身坐标系转换到归⼀化坐标系的运算,就是在这 ⾥发⽣的。
片元着色器(FragmentShader)
- 一般用来处理图形中每个像素点颜色计算和填充
- 片元着色器是
OpenGL中用于计算像素颜色的程序,每个像素都会进行一次计算,也是并行的
GLSL(OpenGL Shading Language)
OpenGL着色语言,是用来在OpenGL中着色变成的语言,在显卡的GPU(Graphic Processor Unit图形处理单元)上执行的,代替了固定的渲染管线的一部分,是渲染管线不同层次具有可编程性。比如:视图转换、投影转换等。 GLSL的着色器代码分为2个部分:顶点着色器和片元着色器
光栅化
- 是把顶点数据转换为⽚元的过程,具有将图转化为⼀个个栅格组成的图象 的作⽤,特点是每个元素对应帧缓冲区中的⼀像素。
- 光栅化就是把顶点数据转换为⽚元的过程。⽚元中的每⼀个元素对应于帧 缓冲区中的⼀个像素。
- 光栅化其实是⼀种将⼏何图元变为⼆维图像的过程。该过程包含了两部分 的⼯作。第⼀部分⼯作:决定窗⼝坐标中的哪些整型栅格区域被基本图元 占⽤;第⼆部分⼯作:分配⼀个颜⾊值和⼀个深度值到各个区域。光栅化 过程产⽣的是⽚元
- 把物体的数学描述以及与物体相关的颜⾊信息转换为屏幕上⽤于对应位置 的像素及⽤于填充像素的颜⾊,这个过程称为光栅化,这是⼀个将模拟信 号转化为离散信号的过程
纹理
纹理可以理解为图片,解压缩之后得到的位图。
混合
在测试阶段之后,如果像素依然没有被剔除,那么像素的颜⾊将会和帧缓 冲区中颜⾊附着上的颜⾊进⾏混合,混合的算法可以通过OpenGL的函数进 ⾏指定。但是OpenGL提供的混合算法是有限的,如果需要更加复杂的混合 算法,⼀般可以通过像素着⾊器进⾏实现,当然性能会⽐原⽣的混合算法 差⼀些。
变换矩阵
图形进行平移、缩放、旋转变换需要使用变换矩阵
投影矩阵
用于将3D坐标转换为2D屏幕坐标,实际线条也将在二维坐标系下进行绘制。
着色器渲染过程
- 顶点着色器对顶点数据进行运算
- 通过图元装配和几何着色器,将顶点转换为图元
- 光栅化,将图元转换为像素
- 片元着色器对像素进行处理,赋予正确的颜色,经过混合与测试,得到位图,放入帧缓冲区
坐标系
2D笛卡尔坐标系
二维坐标系
3D笛卡尔坐标系
三维坐标系
投影方式
正投影
图片绘制不管远近,1:1进行绘制,显示的是2D效果
透视投影
远小近大,3D效果
iOS的渲染框架
Core Graphics
Core Graphics是一套基于C的API框架,使用了Quartz作为绘图引擎。实际上是在内存中开辟一块空间作为画布,然后提供一系列C的方法来绘制这块画布,绘制完成之后交由GPU进行显示。Core Graphics的绘制是可以在非主线程执行的,因为它仅仅是操作一块内存画布而已。
Core Animation
iOS中几乎所有东西都是通过Core Animation绘制出来的。
渲染、构建和实现动画,是app界面渲染和构建的基础架构,职责是尽快的组合屏幕上的不同的可视内容(CALayer)
Core Image
Core Image用来对图片作进一步的处理或者分析,用于一系列线程的图像滤镜,能对已经存在的图像进行高效的处理。