OpenGL ES 入门之旅(2)--OpenGL 下的专业名词解析

524 阅读11分钟

多以概念名词解释和个人理解为主

快速了解图形API

OpenGL

OpenGL(Open Graphics Library,开放式图形库)是用于渲染2D, 3D矢量图形的跨语言,跨平台的应用程序编程接口。它将计算机的资源抽象称为一个OpenGL对象,对这些资源的操作抽象为一个OpenGL指令。OpenGL被设计为只有输出的,所以它只提供渲染功能。OpenGL常用于CAD、虚拟现实、科学可视化程序和电子游戏开发。

OpenGL ES

OpenGL ES (OpenGL for Embedded Systems) 是 OpenGL 三维图形 API 的子集,是从 OpenGL 裁剪的定制而来的,是针对手机、PDA和游戏主机等嵌入式设备而设计。

DirectX

DirectX,(Direct eXtension)是由微软公司创建的多媒体编程接口。DirectX并不是一个单纯的API,它是由很多个API组成的,并且只能支持Windows平台。(作为iOS开发者作为了解即可)

Metal

Metal 是一种低层次的渲染应用程序编程接口,提供了软件所需的最低层,保证软件可以运行在不同的图形芯片上。是苹果公司在2014年WWDC上为游戏开发者提供的新的平台技术,该技术能够为 3D 图像提高 10 倍的渲染性能 。Metal的优势就在于整合了渲染和异构计算(和OpenGL一样具有利用GPU加速渲染的功能 并且能和OpenCL一样利用GPU做异构计算) 在一个统一的框架上提供多种需求。 虽然苹果在2018WWDC上宣布将会放弃使用OpenGL,所以目前市场上的大部分的应用使用的还是OpenGL,不会在短时间内切换到Metal,所以学习OpenGL是非常有必要且重要的,Metal更为重要!!!

OpenGL专业名词

OpenGL 上下文(context)

在应用程序调用OpenGL指令之前,需要创建一个OpenGL上下文,这个上下文是一个庞大的状态机,保存着OpenGL中的各种状态,这也是OpenGL指令执行的基础。OpenGL采用了客户端-服务器模式,我们可以认为每一个硬件GPU是个服务器,每一个绘制上下文对应于申请的一个客户端,一个客户端维护着一套状态机,如果两个窗口分别对应两个不同的绘制上下文,则两个窗口彼此状态独立。

客户端和服务器.png

由于OpenGL上下文一个庞大的状态机,切换上下文可能会产生较大的系统资源开销,但是不同的绘制模块,可能需要使用完全独立的状态,因此,可以在应用程序中创建多个上下文,在不同的线程中使用不同的上下文,上下文之间共享纹理,缓冲区等资源。

OpenGL状态机

状态机就是一种存在于理论中的机器,它具有以下的特点: a. 它有记忆的能力,能够记住自己当前的状态。 b. 它可以接收输入,根据输入的内容和自己的状态,修改自己的状态,并且可以得到输出。 c. 当它进入某个特殊的状态(停机状态)的时候,它不再接收输入,停止工作。

所以从本质上来说,我们的电脑是不是也可以看成一种状态机:

  1. 电脑的存储器(内存、硬盘等等),可以记住电脑自己当前的状态(当前安装在电脑中的软件、保存在电脑中的数据,其实都是二进制的值,都属于当前的状态)。
  2. 电脑的输入设备接收输入(键盘输入、鼠标输入、文件输入),根据输入的内容和自己的状态(主要指可以运行的程序代码),修改自己的状态(修改内存中的值),并且可以得到输出(将结果显示到屏幕)。
  3. 当它进入某个特殊的状态(关机状态)的时候,它不再接收输入,停止工作。 下面把OpenGL也可以看成这样的一种机器: (1) OpenGL可以记录自己的状态(比如:当前所使用的颜色 glClearColor(1.0f,1.0f,0.0f,0.0f);、是否开启了深度测试功能glEnable(GL_DEPTH_TEST);,等等这些都是要记录的) (2) OpenGL可以接收输入(当我们调用OpenGL函数的时候,实际上可以看成OpenGL在接收我们的输入),根据输入的内容和自己的状态,修改自己的状态,并且可以得到输出(比如我们调用glColor3f,则OpenGL接收到这个输入后会修改自己的“当前颜色”这个状态;我们调用glRectf,则OpenGL会输出一个矩形) (3) OpenGL可以进入停止状态,不再接收输入。这个可能在我们的程序中表现得不太明显,不过在程序退出前,OpenGL总会先停止工作的。 #####渲染(Rendering) 将图像和图形数据转换成3D空间图像的操作叫做渲染(也可以理解为绘制3维图形的时候要根据光线等外部环境对绘制与纹理质材等内部结构,生成比较真实的三维效果)这里还有一个有意思的是:“绘制”,我理解绘制应该只是绘制基本的图形元素,而渲染应该更高级一点,在绘制图形元素的基础上加上一些效果把它显示出来。

顶点数组(VertexArray)和顶点缓冲区(VertexBuffer)

顶点:指的是我们在绘制一个图形的时候,它的顶点位置数据,而这个数据可以存储在数组中或者将其缓存到GPU的内存中。 顶点数组:就是把一些顶点数据保存到数组中储存,这些数据包括:顶点坐标,表面法线,RGBA颜色,辅助颜色,颜色索引,纹理坐标以及多边形的边界标志。这样就可以只通过一个函数调用来完成绘制,大大减少了函数的调用次数,同时还可以避免共享顶点的冗余处理,提高了程序性能。 顶点缓冲区:由于OpenGL是一个客户端-服务器模式结构,有时从客服端传输数据到服务端可能会比较缓慢,所以增加了一个缓冲区对象,可以直接显示的指定把哪些数据存储到图形服务器中。

管线

管线可以理解为渲染流水线。在OpenGL下渲染图形的时候,显卡在处理数据时是按照一个固定的顺序,类似于流水线般,按照先后顺序一个接一个的执行。而且必须严格按照这个顺序,不能打破。(管线,实际上指的是一堆原始图形数据途经一个输送管道,期间经过各种变化处理最终出现在屏幕的过程的管理。)

固定管线(存储着色器)

OpenGL在早期的时候封装了很多种着色器程序块内置的一段包含了光照,坐标变换,剪裁等等功能的固定Shader程序来完成,帮助开发者完成图形的渲染。 #####可编程管线 在OpenGL使用的过程中,固定管线可能无法完成每一个业务,这是可以将相关的部分开放成可编程。 (举个个人理解的栗子:比如说生产肥皂的流水线,即管线,从原料按照流水线步骤,一步一步到最后生产出方形的,白色的肥皂块,肥皂颜色单一,形状单一,少了自由性,这就是固定管线。如果在生产肥皂的过程中,可以定制肥皂的形状,肥皂的颜色,到最后我们就可以生产出各种形状,各种颜色的肥皂) #####着色器程序Shader 着色器(Shader)是用来实现图像渲染的,用来替代固定渲染管线的可编辑程序,即是可编程渲染管线。因此,OpenGL在实际调用绘制函数之前,还需要指定一个由shader编辑成的着色器程序。 常见的着色器主要有:顶点着色器(VertexShader),片段着色器(FragmentShader)/像素着色器(PixelShader) ,几何着色器(GeometryShader),曲面细分着色器(TessellationShader)。最重要的是顶点着色器和片段着色器。 OpenGL在处理shader的时候,通过编译,链接等步骤,生成着色器程序(glProgram),着色器程序同时包含了顶点着色器和片断着色器的运算逻辑。在OpenGL进行渲染的时候,首先由顶点着色器对传入的顶点数据进行计算,再通过图元装配,将顶点转换为图元,然后进行光栅化,将图元转换为栅格化数据,最后,将栅格化数据传入片段着色器中进行计算,片段着色器会对栅格化数据中的每一个像素进行计算,并决定像素的颜色。 #####顶点着色器(VertexShader) 顶点着色器一般用来处理图形的每个顶点的变换(旋转/平移/投影)实现了一种通用的可编程的方法操作顶点。顶点着色器是逐个顶点运算的程序,即是每一个顶点数据都会执行一次顶点着色器(并行的)。就好像每一件商品都需要经过质量部门的检验,加盖合格章才可以出厂。 #####片段着色器(FragmentShader) 片断着色器:一般用来处理图形中的每个像素点的颜色的填充和计算。是OpenGL中用于计算片段颜色的程序,并且逐个像素进行运算(并行的),任何一个图形中都会有很多个像素点,那么就会执行很多的计算,所以此时CPU就无法完成这些大量的计算,此时就需要用GPU来做辅助。 #####GLSL(OpenGL Shading Language) 是用来在OpenGL中着色编程的语言,是一种面向过程的语言,基本的语法和C/C++基本相同,他们是在图形卡的GPU (Graphic Processor Unit图形处理单元)上执行的,代替了固定的渲染管线的一部分,使渲染管线中不同层次具有可编程性。比如:视图转换、投影转换等等。GLSL的着色器代码分成2个部分:顶点着色器和片段着色器。

光栅化Rasterization

1.是指把顶点数据转换为片元的过程,片元中的每一个元素对应缓冲区中的一个像素。 2.是一种将几何图元转变为二维图像的过程,该过程包含了两部分内容:1.决定窗口坐标中的哪些整型栅格区域被基本图元占用,2.分配一个颜色值和一个深度值到各个区域,光栅化的过程就是产生片元。

纹理

纹理是一个用来保存图像颜色元素值的OpenGL ES缓存,可以理解为图片/图像,在渲染图形的时候需要在其编码填充图片,为了使得场景更加逼真,在这里使用纹理。

混合(Blending)

在OpenGL中,混合通常是实现物体的透明度的一种技术,透明就是说一个物体并不是纯色的,它的颜色是它物体本身的颜色和它背后的其他物体的颜色的不同程度的结合。比如我们可以混合多个颜色为一种颜色,三原色红绿蓝和在一起之后就是黑色。 在测试阶段之后,如果像素依然没有被剔除,那么像素的颜色将会和帧缓冲区中颜色附着上的颜色进行混合。

变换矩阵(Transformation)

在图形绘制过程中,有三种变换,分别是平移,缩放,旋转。就需要使用变换矩阵。

投影矩阵(Projection)

用于将3D坐标转换为二维屏幕坐标,实际线条也将在二维坐标下进行绘制。

渲染上屏/交换缓冲区(SwapBuffer)

渲染缓冲区一般映射的是系统的资源比如窗口。如果将图像直接渲染到窗口对应的渲染缓冲区,则可以将图像显示到屏幕上。要注意的是,如果每个窗口只有一个缓冲区,那么在绘制过程中屏幕进行了刷新,窗口可能显示出不完整的图像。 为了解决这个问题,常规的OpenGL程序至少都会有两个缓冲区。显示在屏幕上的称为屏幕缓冲区,没有显示的称为离屏缓冲区。在一个缓冲区渲染完成之后,通过将屏幕缓冲区和离屏缓冲区交换,实现图像在屏幕上的显示。 由于显示器的刷新一般是逐行进行的,因此为了防止交换缓冲区的时候屏幕上下区域的图像分属于两个不同的帧,因此交换一般会等待显示器刷新完成的信号,在显示器两次刷新的间隔中进行交换,这个信号就被称为垂直同步信号,这个技术被称为垂直同步。