常用图形处理框架
OpenGL(Open Graphics Library)是⼀个跨编程语⾔言、跨平台的编程图形程序接⼝,它将计算机的资源抽象称为⼀个OpenGL的对象,对这些资源的操作抽象为⼀个的OpenGL指令。
OpenGL ES(OpenGL for Embedded Systems)是OpenGL三维图形 API 的子集,针对⼿手机、 PDA和游戏主机等嵌⼊入式设备⽽而设计,去除了了许多不不必要和性能较低的API接⼝口。
Metal : 2018年 Apple为游戏开发者推出了了新的平台技术Metal,该技术能够为 3D 图像提⾼高 10 倍的渲染性能。Metal是Apple为了了解决3D渲染⽽而推出的框架。Apple在2018年之前 图形渲染使用的是OpenGL,之后替换成Metal。metal提供了一些入口,让开发者可以调用GPU做一些事情(如GPU并发运算,编解码,识别等)
专业名词
OpenGL 上下文(context)
图形绘制中经常出现这个名词 在了解之前我们需要先了解一下OpenGL 状态机的概念。
OpenGL 状态机
它是一种理论上机器。他描述了一个对象在器生命周期内所有经历的各种状态,状态间转变,发生转变的动因,条件及转变中所执行的活动。
具有一下特点:
1.有记忆功能,能记住其当前的状态
2.可以接受输入,根据输入的内容和自己的原先状态,修改自己当前状态,并且可以有对应输出
3.当前进入特殊状态(停机状态)的时候,变不在接受输入,停止工作
注:就像使用电风扇似的。此时电风扇就是个状态机,插上电源,打开开关,进入工作状态;否则就是停机状态,不接受输入,停止工作。你需要一级风力你需要旋转按钮,调到一级状态(输入),这时候吹出一级的风。
现在来到OpenGL 中,再调用OpenGL的指令之前,需要安排首先创建一个OpenGL的上下文。这个上下文就是一个非常庞大的状态机,保存了OpenGL中的各种状态,这也是OpenGL指令执行的基础。
OpenGL是一个面向过程函数集合。本质上都是对OpenGL上下文这个庞大的状态机的某个状态或对象进行操作。
由于OpenGL上下文是一个巨大的状态机,切换上下文往往会产生较大的开销,但是不同的绘制模块,可能需要使用完全的状态管理。因此,可以在应用程序中分别创建不同的上下文或在不同线程中使用不同上下文,然后上下文之间共享纹理、缓冲区等资源。这样比反复切换上下文或者大量修改状态更加合理高效。
渲染(Rendering)
将图形/图像数据转换成2D空间图像操作叫做渲染
顶点
顶点:又称顶点数据,指的是绘制一个图形时,它的顶点数据。这些顶点有2中存储方法
1.存储到内存当中 绘制的时候GPU要从内存中拿去,代价有点大
2.存储到顶点缓存区。顶点缓存区就是GPU显存
顶点数组(VertexArray)、顶点缓冲区(VertexBuffer)
管线
这是OpenGL中的一个重要名词。在OpenGL下渲染图形,就会经历一个一个节点。而这样的操作可以理解为管线。就像流水线一样。它是一个抽象的概念,之所以称之为管线是因为显卡在处理数据的时候是按照一个固定的顺序来的。
固定管线
早期OpenGL版本,内部分装很多着色器程序内置的一段包含光照、坐标转换、裁剪等诸多功能来帮助开发者完成图形渲染。开发者只需调用,不需要关注底层实现。
自定义可编程管线
由于OpenGL的使用场景非常丰富,固定管线或存储着色器无法完成每一个业务员,这时将相关部分开放成可编程。
着色器程序
OpenGL 在调用绘制函数之前,还需要制定一个由shader编译成的着色器程序。常见的着色器主要有顶点着色器(VertexShader),片段着色器(FragmentShader)/像素着色器(PixelShader),几何着色器(GeometryShader),曲面细分着色器(TessellationShader)。 OpenGL EL3.0仍然只支持顶点着色器和片段着色器
OpenGL 在处理shader程序时,通过编译,链接等步骤生成着色器程序(glProgram)。着色器程序包含顶点着色器和片段着色器的运算逻辑。OpenGL进行绘制的时候,首先由顶点着色器对传入的顶点数据进行运算,在通过图元装配,将顶点转化成图元。然后光栅化,将图元这种矢量图形,转化成光栅化数据。最后将光栅化数据传入片段着色器进行运算。普安段着色器会对光栅化数据中的每一个像素进行运算,并决定像素的颜色
着色器编程语言
GLSL(OpenGL Shading Language):用来在OpenGL中着色变成的语言,他们是在图形卡的GPU(Graphic Processor Unit图形处理单元)上执行的,代替了固定的渲染管线的一部分,使渲染管线中不同层次具有可编程行。比如:视图转换、投影转换等。GLSL的着色器代码分为2部分:顶点着色器(Vertex Shader)和片元着色器(Fragment Shader)
顶点着色器(VertexShader)
用来处理顶点数据的shader程序
作用:
1.确定位置
2.缩放、平移、旋转位置换算
3.手机端显示 3D 手机屏幕实际是2D 3D图形数据 ->2D(投影换算)
片元着色器(FragmentShader)
又叫像素着色器,用来处理图形中每一个像素颜色计算和填充。每一个像素都会执行片元着色器,这里是GPU并行计算,所以非常高性能。
光栅化(Rasterization)
光栅化就是将顶点数据转换成片元的过程。实际上试讲几何图元(OpenGL ES就三种点、线、三角形)转为片元的过程。片元中每个元素对应帧缓冲区中的一像素。该过程包含2部分工作。
1.决定窗口坐标中的哪些整型栅格区域被基本图元占用
2.分配一个颜色值和一个深度值到各个区域
纹理
纹理即是位图,渲染图形时需要在其编码填充图片,这里使用的图片称之为纹理
混合(Blending)
在测试阶段之后,如果像素依然没有被剔除,那么像素的颜色将会和帧缓冲区的颜色附着上的颜色进行混合。混合的算法可以通过OpenGL 的函数进行指定。但是OpenGL提供的混合计算有限,如需更加复杂的混合算法,一般可以通过着色器进行实现,当然性能比原生的混合差些
变换矩阵(Transformation)
图形想要发生平移、缩放、旋转变化,就需用到变换矩阵
投影矩阵(Projection)
用于将3D坐标转换为二维坐标,实际线条也将在二维坐标下进行绘制
渲染上屏/交换缓冲区(SwapBuffer)
渲染缓冲区一般映射的是系统的资源比如窗口。如果将图像直接渲染到窗口对应的渲染缓冲区,则可以将图像显示到屏幕上。
但是,指的注意的是,如果每个窗口只有一个缓冲区,那么在绘制过程中屏幕进行刷新,窗口可能显示不完整的图像。
为了解决这个问题,常规的OpenGL程序至少都会有两个缓冲区。显示在屏幕上的称为屏幕缓冲区,没有显示的称为离屏缓冲区。在一个缓冲区渲染完成之后,通过将屏幕缓冲区和离屏缓冲区交换,实现在屏幕上的显示。
由于显示器的刷新一般是逐行进行的,因此为了防止交换缓冲区的时候屏幕上下区域分属于两个不同的帧,因此交换一般会等待显示器刷新完成的信号,在显示器两次刷新的间隔中进行交换,这个信号就被称为垂直同步信号,这个技术被称为垂直同步。
使用了双缓存区和垂直同步技术之后,由于总是等待缓冲区交换之后再进行下一帧的渲染,使得帧率无法完全达到硬件允许的最好水平。为了解决这个问题,引入了三缓冲区技术,在等待垂直同步时,来回交替渲染两个离屏的缓冲区,而垂直同步发生时,屏幕缓冲区和最近渲染完成的离屏缓冲区交换,实现充分利用硬件性能的目的。