OpenGL - 002_1图形 API 的简单介绍

Posted 菜园子

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了OpenGL - 002_1图形 API 的简单介绍相关的知识,希望对你有一定的参考价值。

One:图形API的简单介绍

1)图形API

  1、OpenGL(Open Graphics Library) ,一门跨平台、跨编程语言的程序接口。一个标准,用来调度GPU处理事情的。

  OpenGL主要是针对PC端(Mac、Windows)的。

  2、OpenGL ES(OpenGL for Embedded System),ES = 嵌入式。它是 OpenGL 三维图形API的子集,可理解为比OpenGL少了一些API(许多不必要的和性能较低的API)

  针对 移动端的,手机端安卓ios系统、PDA(一般指掌上电脑)、游戏主机等嵌入式设备而设计,他去除了许多不必要的和性能较低的API。

    A、OpenGL/OpenCV  两者区别简单介绍:

      a、OpenGL主要做渲染 --> 显示位图 -->按钮图片等的显示都会以位图的形式处理,它们的显示就用到了OpenGL。

      b、OpenCV主要用来识别,人脸识别、卡号识别、物体识别等(OpenCV face++:付费商用) --> 与人工智能的结合。

  3、DirectX :由很多API组成,它并不是单纯的图形API,它是只支持Windows平台的一个多媒体处理框架,非跨平台框架,按性质可分为:显示部分、声音部分、输入部分、网络部分四大部分。

  4、Metal :Apple为了解决3D渲染而推出的框架。游戏开发者的新的技术平台,该技术能够为3D图像提高 10 倍的渲染性能。苹果底层渲染是由Metal来实现的。

上图,苹果核心动画 CoreAnimation,是基于OpenGL/Metal的高级封装,调 CoreAnimation 的时候其实就是在调度 OpenGL/Metal 来完成GPU的驱动。(2018年以前是OpenGL,后面就是Metal了)

2)图形API是干什么的?

  解决渲染问题。

  OpenGL/OpenGL ES/Metal 在任何项目中,解决问题的本质就是,利用GPU芯片来高效渲染图形图像。图形API是iOS开发者唯一接近GPU的方式。

  1、系统针对按钮图片,视图、图层渲染问题

  2、游戏引擎 --> 任务/场景渲染

  3、视频播放框架 --> 视频解码(ijkplayer、kxmovie) --> 渲染

  4、核心动画

  5、视频/图片 --> 特效

  6、离屏渲染(待续...)

 

Two: 专有名词介绍

一、OpenGL 上下文【context】

  在应用程序调用任何OpenGL的指令前,需要首先创建一个OpenGL的上下文。这个上下文是一个很庞大的状态机,保存了OpenGL中的各种状态,这些也是OpenGL指令执行的基础。

  OpenGL的函数不论在哪个语言环境下,都是类似于C的面向过程的函数,本质都是对OpenGL上下文中的 某个状态or某个对象 进行操作。自然,这个对象首先是需要设置为当前对象的,因此,通过对OpenGL指令的封装,是可以将OpenGL的相关调用封装为一个面向对象的图形API 的。

  OpenGL上下文是一个巨大的状态机,切换上下文时会产生较大的开销,但不同的绘制模块可能需要使用完全独立的状态管理,因此,可以在应用程序中,针对不同模块,分别创建多个不同的上下文,在不同线程中使用不同上下文,上下文之间共享纹理(位图)、缓冲区等资源。这样,相较于频繁的切换上下文or大量修改渲染状态,更加合理高效有条理。

二、OpenGL 状态机

1)首先理解 状态机是什么???

  状态机理论上是一种机器,可以理解为:记录了一堆 某个对象在其生命周期内所经历的各种状态,状态之间的转变,转变的动因、转变的条件,转变中执行的活动。====>>>> (借鉴百度知道的例子:人有三个状态:健康,感冒,康复中。触发的条件有淋雨(t1),吃药(t2),打针(t3),休息(t4)。所以状态机就是健康-(t4)->健康;健康-(t1)->感冒;感冒-(t3)->健康;感冒-(t2)->康复中;康复中-(t4)->健康,等等。就是这样状态在不同的条件下跳转到自己或不同状态的图)。

  状态机是一种行为,说明对象在其生命周期中 响应事件所经历的状态序列 以及 对那些状态事件的响应。它具有下面特点:

    A、有记忆功能,记录住当前的状态

    B、可以接收输入,根据输入内容和自己原先的状态,修改当前状态,病可以有对应的输出

    C、当进入特殊状态(停机状态)时,不再接收输入,停止工作。

2)OpenGL状态机:类推过里可以这样理解:

  A、OpenGL可以记录自己的状态(当前的使用的颜色、是否开启了混合功能等)

  B、OpenGL可以接收输入(当调用OpenGL函数时,可以看成是OpenGL在接收我们的输入),例如,我们调用 glColor3f,则OpenGL接收到这个输入后就会修改自己的‘当前颜色’这个状态。

  C、OpenGL可以进入停止状态,不再接收输入。在程序退出前,OpenGL总会先停止工作。

三、渲染(Rendering):将 图形/图像数据转换成 2D 空间图像的操作,叫做渲染

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

  类比,做一张图,首先画图像的骨架,之后再往里填充颜色。OpenGL的顶点数据就是要画的图像的骨架,OpenGL的图像都是由图元组成的。在OpenGL ES中,由3中类型的图元:点、线、三角形。如下图,绘制一个长方形的图片,要首先要知道绘制在屏幕的哪个位置,因为OpenGL没有长方形一说,所以是被分割成2个三角形的,它有6个顶点(不规则图形相通的就是有多个顶点),这6个顶点数据存储在哪里呢?(何为顶点?指在绘制一个图形时,他的顶点位置数据。) 

  顶点数组存储有2种方式:

    顶点数组:顶点数据存储在内存中,被称为顶点数组。没那么高效

    顶点缓冲区:更加快速的被GPU拿到,顶点数据存储到GPU的显存中来,这部分显存则被称为顶点缓冲区。

  (要显示的PNG图片,前提是此图片已解压成位图了,PNG --解压--> 位图 ,coreGraphic,PNG对应的位图大小:120*120 --> RGBA -> 每个占8位 == 4个字节 --> 14400 * 4)

  纹理(位图)坐标只关乎到映射,对应关系,图像的绘制就是点对点的映射关系。

 

五、管线

  流水线,在OpenGL下渲染图形,会经历像流水线工作的一个个节点,这样的操作可以理解为管线。类似流水线,每一个任务都像生产流水线似的执行,任务之间是有先后顺序。

  为何叫管线?显卡在处理数据的时候是严格按照一个固定的顺序来的,像一个水管,一端流到另一端,顺序是不可打破的。

  1)固定管线/存储着色器(固定着色器):

    特定模具,提供了很多着色器,只能调用固定的 API,不可自定义。

    在早起的OpenGL版本,封装了很多种,着色器 程序块 内置的,一段包含了光照、坐标变换、裁剪等诸多功能的,固定shader程序,来完成 帮助开发者完成图形的渲染,只需要传入相应的参数就可以完成图形的渲染。类似iOS中封装的一堆API们,我们只调用。

  2)可编程管线:

    可自定义编程的模具。

    由于OpenGL的使用场景非常丰富,固定管线或存储着色器无法完成每一个业务,此时,相关一部分 开放成可编程,可基于GLSL语法进行一些编写。

五(2)、着色器程序 Shader (自定义)

类似于一个函数/方法,它是给GPU用的。

1、为全面的将固定渲染管线架构变成可编程渲染管线。OpenGL在实际调用绘制函数之前,还需要制定一个由 shader 编译承德着色器程序。

常见的着色器:

  顶点着色器(VertexShader)、

  片元/片段着色器(FragmentShader)/像素着色器(PixelShader)、 --> // 两者知只是在 OpenGL 和 DX中的不同叫法;

  几何着色器(GeometryShader)、

  曲面细分着色器(RessellationShader)。

2、OpenGL 在处理 shader 时,和其他编译器一样。通过编译、链接等步骤,生成着色器程序(glProgram),着色器程序同时包含了 顶点着色器和片元着色器的运算逻辑。

  在 OpenGL 进行绘制时,首先由顶点着色器对传入的顶点数据进行运算 --> 再通过图元装配、将顶点转换为图元 --> 然后进行光栅化,将图元这种事量图形转化为栅格化数据 --> 最后,将栅格化数据传入 片元着色器 中进行运算。 --> 片元着色器会对栅格化数据中的每一个像素进行运算,并决定像素的颜色。

着色器渲染过程:

渲染过程中,必须存储 2 种着色器:顶点着色器、片元着色器;顶点着色器处理顶点数据,片元着色器处理像素点颜色。

有且仅有顶点着色器和片元着色器我们可触碰到。

  1)顶点着色器(VertexShader):

    OpenGL中用来处理顶点相关的程序代码,一般用来处理图形每个顶点变换:

    -->1、确定位置;2、旋转缩放平移;3、投影换算:手机端显示3D屏幕(实际还是2D),3D图形数据 --> 2D投影换算   

  2)片元着色器(FragmentShader)

    片元其实就是指像素,Fragment翻译成片元只是个名字而已,所以片元着色器也被叫做 像素着色器。

    用来处理一个个像素点的,处理图形中每个像素点颜色的计算和填充。片元着色器是逐像素运算的程序,即:每个像素都会执行一次片元着色器(并行的)。120*120的PNG图片转换成位图--> 要计算14400次,但是对GPU并行运行来说来说就不算多是小case。

六、GLSL(OpenGL Shading Language)

  一门语言,OpenGL着色语言,是用来在OpenGL中 着色编程的语言,遵循OpenGL的规则,来调动GPU做运算的语言。

  开发人员编写的自定义程序,它是在图形卡的GPU上执行的,替代了固定的渲染管线的一部分,是渲染管线中不同层次具有可编程性。比如:试图转换、投影转换等。GLSL的着色器代码分2个部分:顶点着色器、片元着色器。

七、光栅化

  核心动画的属性里有个属性就是打开光栅化 --> shouldRasterize(光栅化)是比较特别的一种离屏渲染。

  光栅化是把 顶点数据转化成片元数据的过程,(光栅化不可编程),把图转化成由一个个栅格组成的图像,每个元素对应帧缓冲区的一像素。参照上面的图一。

  光栅化的2个过程:1、确定图形的像素范围(在哪个位置) 2、计算好的颜色附着上去。物理过程,我们可操作的就只有顶点和片元着色器。

八、纹理

  可以理解为图片,在OpenGL中的图片并非pngJPG图片,而是位图图片,在OpenGL中称之为纹理。  .tga纹理文件

九、混合(Blending)

例:layer有2个图层,一个粉色有透明度,一个蓝色有透明度,两个layer叠加在一起会有个混合的颜色,这个混合行为是需要 混合计算 的,混合运算。

混合的算法可以通过OpenGL的函数进行指定。但OpenGL提供的混合算法是有限的,需要更加复杂的混合算法,可通过像素着色器实现,但是当然性能方面会比原生的混合算法差些。

十、矩阵

1)变换矩阵(Transformation):

  图形想要发生平移、缩放、旋转变换,需要一个变换矩阵。例如旋转一个三角形,每个顶点都要进行一定的旋转,这个旋转就对应一个变换矩阵。

  图形 * 变换矩阵(旋转/缩放/平移)

2)投影矩阵(Projection)

  用于3D坐标转换为一个二维2D坐标。

 

以上是关于OpenGL - 002_1图形 API 的简单介绍的主要内容,如果未能解决你的问题,请参考以下文章

OpenGL - 002_2OpenGL 常见专业名词解析

计算机图形学输出图元_12_OpenGL顶点数组

计算机图形学输出图元_10_多边形填充区_8_OpenGL顶点数组

超简单的OpenGL & WebGL & Three.js介绍

Android API Guides---OpenGL ES

计算机图形学输出图元_14_OpenGL像素阵列函数_1_位图函数