1. 简介
-
OpenGL(Open Graphics Library)
是一个跨编程语言、跨平台的编程图形程序接口,接口的实现是由显示设备厂商提供的,而且依赖于厂商提供的硬件设备
也是一个标准,将计算的资源抽象称为OpenGL对象,对资源的操作抽象为OpenGL指令。
主要应用于PC端处理图形/图像 -
OpenGL ES(OpenGLforEmbedded Systems)
OpenGL三维图形API的子集,针对手机、PDA和游戏主机等嵌入式设备设计,去除了许多不必要和性能较低的API接口.
-
DirectX
一个多媒体处理API(包含四大部分:显示,声音,输入,网络),不跨平台,只支持Windows
-
Mental
是Apple为了解决3D渲染推出的框架.能为3D图像提高10倍的渲染性能(主要应用于游戏),苹果底层渲染是由Metal 来实现的
2018年苹果弃用了OpenGLES,底层渲染迁移Metal
弃用OpenGL原因: OpenGL是三方,苹果需要契合你的项目做定制化需求和迭代,所以弃用;苹果不可能一直把非常重要的渲染核心框架使用第三方;GPU主要用来做并发运算,编解码,识别,Metal前不能做自定义事情,OpenGL ES也只是自定义图形图像的处理,不能做项目内容的处理,Metal可以自定义处理
-
OpenGL与OpenCV
OpenGL是做图形渲染,显示位图;OpenCV:识别(人脸识别,身份识别,物体识别)-->OpenCV face++,与人工智能结合使用
2. 功能:实现图形的底层渲染
- 游戏场景/游戏人物的渲染
- 视频解码后的数据渲染
- 地图上的数据渲染
- 实现动画的绘制
- 视频加滤镜效果
3. 本质
- OpenGL/OpenGL ES/Metal在任何项目中解决问题的本质就是利用GPU芯片来高效渲染图形图像.
4. 名词解析
-
OpenGL 上下文(context)
在调⽤OpenGL的指令之前,创建一个OpenGL的上下⽂,其实质是一个状态机,保存了OpenGL中的各种状态
OpenGL的函数是面向过程的函数,本质上都是对OpenGL上下⽂这个庞⼤的状态机中的某个状态或者对象进⾏操作。使用前把要操作的上下文设置为当前对象。
通过对penGL指令的封装,可以将OpenGL的相关调⽤封装成一个⾯向对象的图形API
在不同线程中可以创建多个不同的上下文,上下⽂之间共享纹理、缓冲区等资源。
- OpenGL 状态机
- 状态机
描述一个对象在其⽣命周期内所经历的各种状态,状态间的 转变,发生转变的动因,条件及转变中所执⾏的活动。或者说,状态机是一种⾏为,说明对象在其生命周期中响应事件所经历的状态序列以及对哪些状态事件的响应。因此具有以下特点:
* 有记忆功能,能记住其当前的状态
* 可以接收输⼊,根据输入的内容和自己的原先状态,修改自⼰当前状态,并且可以有对应输出
* 当进⼊特殊状态(停机状态)的时候,便不再接收输入,停止工作;
- OpenGL状态机
OpenGL可以记录状态(如当前所使用的颜色、是否开启了混合功能等)
OpenGL可以接收输入(当调⽤用OpenGL函数的时候,可以看成OpenGL在接收输入),如调用glColor3f,则OpenGL接收到这个输⼊后会修改⾃己的“当前颜色”这个状态;
OpenGL可以进⼊停止状态,不再接收输入。在程序退出前,OpenGL总 会先停止工作
-
渲染(Rendering)
将图形/图像数据转换成2D空间图像操作叫做渲染(Rendering)。
-
顶点数组(VertexArray)和顶点缓冲区(VertexBuffer)
顶点是顶点位置数据.存储在内存中。
顶点数据就是图像骨架,OpenGL中的图像都是由图元组成。在OpenGLES中,有3种类型的图元:点、线、三⻆形。
所有的顶点数据组成的数据就是顶点数组。
调用绘制⽅法时,由内存传入顶点数组,GPU会提前分配一块显存,将顶点数组数据预先传入到显存当中,这部分的显存称为顶点缓冲区(在GPU显存中)
-
管线
在OpenGL下,显卡在处理数据的时候按照一个固定的顺序,而且严格按照这个顺序,就像⽔从⼀根管子的一端流到另一端,这个顺序是不能打破的,称为管线。
-
固定管线/存储着色器
早期的OpenGL版本,封装了很多种着⾊器程序块,内置的一段包含了光照、坐标变换、裁剪等诸多功能的固定shader程序来完成,开发者绘制时只需要传⼊相应的参数,就能快速完成图形的渲染,不需要关注底层实现原理,因此被称为固定管线。
随着需求的发展,固定管线或存储着色器⽆法完成每⼀个业务,对开发者开发 对顶点着色器和片元着色器编码配置,这样的着色器称为可编程着色器(直到 OpenGL ES 3.0,只⽀持顶点着色器和片段着⾊器这两个着⾊器)
-
着色器程序Shader
调⽤绘制函数之前,需要指定⼀个由shader编译成的着⾊器程序。
常见的着色器器主要有:
顶点着⾊器(VertexShader), ⽚段着⾊器 (FragmentShader)/像素着⾊器(PixelShader)/片元着色器, ⼏何着⾊器 (GeometryShader), 曲⾯细分着⾊器(TessellationShader)
OpenGL在处理shader时,通过编译、链接等步骤,⽣成着⾊器程序(glProgram),着⾊器程序同时包含了顶点着⾊器和片段着⾊器的运算逻辑。
在OpenGL进行绘制的时候,⾸先由顶点着色器对传⼊的顶点数据进行运算。再通过图元装配,将顶点转换为图元。然后进⾏栅化,将图元这种⽮量图形,转换为栅格化数据。最后,将栅格化数据传入片段着⾊器中进⾏运算。片段着⾊器会对栅格化数据中的每⼀个像素进行运算,并决定像素的颜⾊
-
顶点着⾊器Vertex Shader
用来处理图形顶点变换(旋转/平移/投影等),
用于计算顶点属性(顶点坐标变换、顶点光照运算,将顶点坐标由⾃身坐标系转换到归一化坐标)。
位置计算 -- 位置换算(平移/缩放/旋转)--2D投影
-
⽚元着⾊器Fragment Shader/像素着色器
用来处理图形中每个像素点颜⾊计算和填充的程序
- OpenGL着色语言GLSL(OpenGL Shading Language)
开发人员自定义程序,在图形卡的GPU (Graphic Processor Unit图形处理单元)上执行的, 代替了固定的渲染管线的一部分,使渲染管线中不同层次具有可编程性。比如:视图转换、投影转换等。
GLSL(GL Shading Language)的着⾊器代码分成2个部分: Vertex Shader(顶点着⾊器) 和Fragment Shader(片段着⾊器)
- 光栅化Rasterization:把顶点数据转换为片元的过程
把物体的数学描述以及与物体相关的颜色信息转换为屏幕上⽤于对应位置的像素及用于填充像素的颜色,这个过程称为光栅化
两部分工作:
- 确定绘制区域:把物体的数学描述以及与物体相关的颜⾊信息转换为屏幕上用于对应位置的像素
- 填充颜色
- 纹理:图⽚
在渲染图形时需要编码填充图片,这里使用的图片,就是纹理,纹理的存储格式.tag
- 混合(Blending)
测试阶段之后,像素的颜⾊会和帧缓冲区中颜色进⾏混合形成混合色,混合的算法可以通过OpenGL的函数进⾏指定。
OpenGL提供的混合算法是有限的,如果需要更加复杂的混合 算法,一般可以通过像素着⾊器进⾏实现,性能会比原生的混合算法差⼀些.
-
变换矩阵(Transformation)
图形发⽣平移,缩放,旋转--坐标乘以变换矩阵. -
投影矩阵Projection
用于将3D坐标经过投影矩阵 转换为二维屏幕坐标
-
渲染上屏/交换缓冲区(SwapBuffer)
渲染缓冲区一般映射的是系统的资源,比如窗口。如果将图像直接渲染到窗⼝对应的渲染缓冲区,则可以将图像显示到屏幕上。
如果每个窗口只有一个缓冲区,那么在绘制过程中屏幕进⾏了刷新,窗⼝可能显示出不完整的图像--双缓冲区。
常规的OpenGL程序⾄少都会有两个缓冲区。显示在屏幕上的称为屏幕缓冲区,没有显示的称为离屏缓冲区。在一个缓冲区渲染完成之后,通过将屏幕缓冲区和离屏缓冲区交换,实现图像在屏幕上的显示。
由于显示器的刷新一般是逐⾏进⾏的,因此为了防止交换缓冲区的时候屏幕上下区域的图像分属于两个不同的帧,因此交换一般会等待显示器刷新完成的信号,在显示器两次刷新的间隔中进行交换,这个信号就被称为垂直同步信号,这个技术被称为垂直同步
双缓冲区要等待缓冲区交换之后再进行下一帧的渲染,使得帧率无法完全达到硬件允许的最⾼水平-->三缓冲区技术.
三缓冲区技术 :在等待垂直同步时,来回交替渲染两个离屏的缓冲区,而垂直同步发生时,屏幕缓冲区和最近渲染完成的离屏缓冲区交换,充分利用硬件性能
5. 投影方式 : 正投影和透视投影
- 正投影 不管远近1:1进行绘制 --->呈现2D效果
函数原型:
GLFrustum::SetOrthographic(GLfloat xMin, GLfloat xMax, GLfloat yMin, GLfloat yMax, GLfloat zMin, GLfloat zMax)
-
透视投影 :远小近大 ---> 呈现3D效果
GLFrustum类通过setPerspective方法为构建一个透视投影。
函数原型:
CLFrustum::SetPerspective(float fFov , float fAspect ,float fNear ,float fFar);参数:
fFov:垂直⽅向上的视场角度
fAspect:窗口的宽度与高度的纵横⽐
fNear:近裁剪面距离
fFar:远裁剪⾯距离
纵横⽐ = 宽(w)/高(h)
6. 坐标系和坐标变换
标准化设备坐标系:
OpenGL每次着色后,可见顶点都为标准化设备坐标(Normalized Device Coordinate,NDC),顶点(x,y,z)的取值都在-1到1之间,超出这个范围顶点不可见
从物体的坐标变换到屏幕上的二维坐标和像素,总共要经历5个不同的坐标系:局部空间/物体空间,世界空间,观察者空间/视觉空间,剪裁空间,屏幕空间,需要用的变换矩阵有模型,观察,投影,具体流程如下:
image- 补充:3D图形学中的常用坐标系:
世界坐标系(所有物体都在世界坐标系内),
物体坐标系
摄像机坐标系
惯性坐标系
OpenGL只定义了裁剪坐标系、规范化设备坐标系和屏幕坐标系,而局部坐标系(模型坐标系)、世界坐标系和照相机坐标系都是为了方便用户设计而自定义的坐标系,关系如下图:
image
用户自定义变换包括模型变换、视变换、投影变换,在顶点着色器中完成
OpenGL自动执行的变换包括:透视除法、视口变换,在顶点着色器处理后的阶段完成
- 注意: OpenGL中的相机始终位于原点,指向-Z轴,而以相反的方式来调整场景中的物体,从而达到相同的观察效果.
网友评论