图形API简介
OpenGL
OpenGL (Open Graphics Library)是一个用于渲染2D、3D矢量图形的跨编程语言、跨平台的应用程序编程接口。它将计算机的资源抽象成为一个个 OpenGL 对象,对这些资源的操作抽象成为一个个 OpenGL 指令。
OpenGL ES
OpenGL ES (OpenGL for Embedded Systems) 是 OpenGL 三维图形应用程序接口的子集,针对手机、Pad和游戏主机等嵌入式设备而设计,去除了许多不必要的和性能较低的 API 接口
DirectX
DirectX 是由微软公司创建的一系列专为多媒体以及游戏开发的应用程序接口。旗下包含Direct3D、Direct2D、DirectCompute等等多个不同用途的子部分,因为这一系列 API 皆以 Direct 字样开头,所以 DirectX(只要把X字母替换为任何一个特定API的名字)就成为这一巨大的API系列的统称。
它并不支持 Windows 以外的平台,所以不是跨平台框架。按照性质分类,可以分为四大部分:显示部分、声音部分、输入部分和网络部分。
Metal
Metal 是苹果公司为游戏开发推出的新的平台技术,该技术能够为 3D 图像提高 10 倍的渲染性能。Metal 是为了解决 3D 渲染而推出的框架。
OpenGL 常用的专业名词
上下文 [context]
- 在应用程序调用 OpenGL 的指令之前,都需要先创建一个 OpenGL 的上下文。这个上下文其实就是一个庞大的状态机,保存了 OpenGL 中的各种状态,这也是 OpenGL 指令执行的基础
- OpenGL 函数不管在哪个语言中,都是类似 C 语言一样面向过程的函数,本质上都是对 OpenGL 上下文的这个庞大的状态机中的某个状态或者对象进行操作,当然你得首先把这个对象设置为当前对象。因此,通过对 OpenGL 指令的封装,是可以将 OpenGL 的相关调用封装成为一个面向对象的图形 API 的
- 由于 OpenGL 上下文是一个巨大的状态机,切换上下文会产生较大的开销,但是不同的绘制模块,可能需要使用完全独立的状态管理。因此,可以在应用程序中分别创建多个不同的上下文,在不同线程中使用不同的上下文,上下文之间共享纹理、缓冲区等资源。这样的方案,会比反复切换上下文,或者大量修改渲染状态,更加合理高效。
OpenGL 状态机
- OpenGL 可以记录自己的状态(如当前所使用的颜色、是否开启了混合功能等)
- OpenGL 可以接收输入(当调用 OpenGL 函数的时候,实际上可以看成OpenGL 在接收我们的输入),如我们调用glCOlor3f,则 OpenGL 接收到这个输入后会修改自己的“当前颜色”的这个状态
- OpenGL 可以进入停止状态,不再接收输入。在程序退出前,OpenGL 总会先停止工作。
渲染 [Rendering]
渲染是将图形、图像、视频等显示绘制到屏幕的过程
OpenGL 中的图像都是由图元组成的。在 OpenGL 中,有三种类型的图元:点、线、三角形。
顶点
顶点指的是我们在绘制一个图形时,它的顶点位置数据。
顶点数组 [VertexArray]
顶点数组是在调用绘制方法的时候,直接由内存传入顶点数据,这部分数据是之前就存在内存中的。
顶点缓存区 [VertexBuffer]
基于顶点数组的流程,我们可以提前分配一块显存,将顶点数据预先传入到显存当中。这部分的显存就被称为顶点缓冲区。
管线/存储着色器
在 OpenGL 的渲染过程中,会经历一个个节点,而这样的操作就被称为管线。也可以想象成流水线。每个任务类似流水线般执行。任务之间有先后顺序。之所以称之为管线,是因为显卡在处理数据的时候是严格按照一个固定的顺序来处理的。
固定管线/固定存储着色器
- 封装了很多种着色器程序块,它内置的一段包含了光照、坐标转换、裁剪等诸多功能的固定 shader 程序来帮助开发者完成图形的渲染。开发者只需要传入相应的参数,就能快速完成图形的渲染。类似于直接调用API,直接调用即可实现相应的功能,而不用关心底层原理。
- 代码段 (苹果提供API) —> 调用参数 (OpenGL提供)
可编程管线
- 当固定管线或存储着色器无法完成每一个业务时,这时将相关的部分开发出来让开发者可以进行自定义编程
- 基于 GLSL语法来进行编写代码段
着色器
着色器是一种计算机程序。原本用于进行图像的浓淡处理(计算图像中的光照、亮度、颜色等),但近来,它也被用于完成很多不同领域的工作,比如处理CG特效、进行与浓淡无关的影片后期处理、甚至用于一些与计算机图形学无关的其它领域。
它其实也可以被理解为是 CPU 使用的函数/方法,GPU中的代码段(shader)
固定着色器/存储着色器
顶点着色器
- 一般用来处理图形每个顶点变换【旋转、平移、投影等】
- 顶点着色器是 OpenGL 中用于计算顶点属性的程序。顶点着色器是逐顶点运算的程序,也就是说每个顶点数据都会执行一次顶点着色器,它是并行的,并且顶点着色器运算过程中无法访问其它顶点的数据。
典型的需要计算的顶点属性主要包括顶点坐标转换、逐顶点光照运算等。顶点坐标由自身坐标系转换到归一坐标系的运算,就是在这里发生的。
片元着色器
- 片元着色器又叫片段着色器或像素着色器
- 一般用来处理图形中每个像素点颜色的计算和填充
- 片元着色器是 OpenGL 中用于计算片段(像素)颜色的程序。片元着色器是逐像素运算的程序,也就是说每个像素都会执行一次片元着色器,当然也是并行执行的
栗子:120 * 120 像素点 —> 14400次 —> GPU运算
GLSL
GLSL(OpenGL Shading Language)是 OpenGL 的着色编程语言,它代替了固定渲染管线的一部分,使得渲染管线在不同层次上具有了可编辑性。比如:视图转换、投影等。
GLSL 的着色器代码可以分为两个部分:顶点着色器和片元着色器
光栅化
光栅化可以分为两个部分。一是先确定图形在屏幕中的像素范围。二是在确定的像素范围内着色。
纹理
- 纹理其实就是图片
- 在 OpenGL 中,是 .tga 纹理文件
- 在 OpenGL ES 移动端中,其实就是将图片转换成了位图
混合
当该像素点上颜色还未剔除的时候,有新的颜色需要着色在该像素点中,那么就要进行颜色的混合,它由 OpenGL 中提供混合算法(也就是函数)。
但是 OpenGL 中提供的算法是有限的,所以可以通过像素着色器来进行实现,但是性能会差些
变换矩阵
记录图形在发生平移、旋转、缩放时候顶点发生的变化
投影矩阵
用于将 3D 坐标转换为二维屏幕坐标
投影方式
投影方式分为两种:正投影和透视投影
- 1、正投影:1 : 1绘制,显示 2D 效果
- 2、透视投影:远小近大效果,3D 效果显示在二维屏幕中
渲染上屏/交换缓冲区(SwapBuffer)
- 渲染缓冲区一般是系统的窗口缓冲区。如果将图像直接渲染到窗口对应的缓冲区,则可以直接将图像显示到屏幕上
- 但是每个窗口只有一个缓冲区,如果在绘制的过程中进行了刷新,窗口则可能显示不完整的图像
- 为了解决上诉的问题,常规的 OpenGL 会有双缓冲区。显示在屏幕上的成为屏幕缓冲区,未显示在屏幕上的成为离屏缓冲区。在一个缓冲区渲染完成后,通过将屏幕缓冲区和离屏缓冲区进行切换,实现图像在屏幕上的显示
- 由于显示器的刷新一般是逐行进行的,所以为了防止交换缓冲区的时候屏幕上下区域的图像分属于两个缓冲区,因此交换会等待显示器刷新完成的信号,在显示器两次刷新的间隔中进行交换,这个信号被称为垂直同步信号,这个技术被称为垂直同步
- 使用了双缓冲区和垂直同步信号后,由于总要等待缓冲区交换之后在进行下一帧的渲染,使得帧率无法完全达到硬件允许的最高水平。所以引进了三缓冲区,即在等待垂直同步信号之前,来回交替两个离屏缓冲区,而垂直同步信号到来时,屏幕缓冲区会和最近渲染完成的离屏缓冲区进行交换
坐标系
- 物体坐标系/对象坐标
- 世界坐标系
- 观察者坐标系/摄像机坐标系
- 裁剪坐标系
- 规范化设备坐标系
- 屏幕坐标系