第二弹 OpenGL 快速理解 图形API(一)

2019-05-14  本文已影响0人  Mr_Lxh

快速了解图形API

图形API简介(定义)

图形API目的是解决什么问题 ?

简单来说就是实现图形的底层渲染 
a、比如在游戏开发中,对于游戏场景/游戏人物的渲染
b、比如音视频开发中,对于视频解码后的数据渲染
c、比如在地图引擎对于地图上的数据渲染
d、比如在动画中,实现动画的绘制
e、比如在视频处理中,对于视频加上滤镜效果

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

OpenGL 专业名词解析

OpenGL 上下文(context)
OpenGL 状态机
    * 有记忆功能,能记住当前的状态
    * 可以接收输入,根据输入的内容和自己的原先状态,修改自己当前状态。并且可以有对应输出
    * 当进入特殊状态(停机状态)的时候,便不再接收输入,停止工作
状态机和上下文的理解:
可以这样理解吧 
就比如说 我写了一本小说 
小说里面有一个人物  
我要描述这个人物
我就离不开这个小说 
然后我需要人物做什么事情
肯定就只能在这本小说里面去执行  
而且小说里面记录的这个人物做了什么事情  
这个人物有什么性格
有什么状态
其实也就是说这个小说就是一个状态机  
也可以说小说其实就是上下文
渲染
计算机将存储在内存中的形状转换成实际绘制在屏幕上的对应的过程
顶点数组(VertexArray)和顶点缓冲区(VertexBuffer)
* 画图一般是先画好图像的骨架,然后再往骨架里填充颜色,这对于OpenGL 也是一样的。顶点数据就是要画的图像的骨架,和现实中不同的是,OpenGL中的图像都是由图元组成,在OpenGL ES中,有3种类型的图元:点、线、三角形。那这些顶点数据最终是存储在哪里的呢?开发者可以选择设定函数指针,在调用绘制方法的时候,直接由内存传入顶点数据,也就是说这部分数据之前是存储在内存当中的,被称为顶点数组。而性能更高的做法是,提前分配一块显存,将顶点的数据预先传入到显存当中。这部分的显存,就被称为顶点缓冲区
* 顶点指的是我们在绘制一个图形时,它的顶点位置数据,而这个数据可以直接存储在数组中或者将其缓存到GPU内存中 所以顶点数据是由GPU处理的
管线

在OpenGL下渲染图形就会经历一个一个节点,而这样的操作可以理解为管线。类似于流水线 每个任务严格按照既定顺序依次执行。就像水从一根管子的一端流到另一端,这个顺序是不能打破的。

固定管线/存储着色器

在早期的Open GL版本,它封装了很多种着色器程序块内置的一段包含了光照,坐标变换、裁剪等等诸多功能的固定shader程序来完成,来帮助开发者来完成图形的渲染。而开发者只需要传入相应的参数,就能快速完成图形的渲染。类似于iOS会封装很多API 而我们只需要调用,就可以实现功能。不需要关注底层实现原理
但是由于OpenGL 的使用场景非常丰富,固定管线或存储着色器无法完成每一个业务,这时将相关部分开放成可编程 这叫做可编程管线

光栅化

光栅化就是将数据转化成可见像素的过程 具有将图转化为一个个栅格组成的图像的作用 特点是每个元素对应帧缓冲区中的一个像素

什么是GPU 图形渲染流水线(Pipeline)
opengl-graphics-pipeline.png

程序按照固定的顺序执行,且不能更改顺序,称为管线,这个翻译非常不友好,不好理解,容易有歧义,叫流程、流水线更好。
GPU 图形渲染流水线的具体实现可分为六个阶段,如下图所示。

顶点着色器(Vertex Shader)
形状装配(Shape Assembly),又称 图元装配
几何着色器(Geometry Shader)
光栅化(Rasterization)
片段着色器(Fragment Shader),又称 片元着色器
测试与混合(Tests and Blending)
帧缓冲区(Framebuffer)

第一阶段:顶点着色器。该阶段的输入是 顶点数据(Vertex Data) 数据,比如以数组的形式传递 3 个 3D 坐标用来表示一个三角形。顶点数据是一系列顶点的集合。
第二阶段:图元生成。该阶段将顶点着色器输出的所有顶点作为输入,并将所有的点装配成指定图元的形状。图中则是一个三角形。图元(Primitive) 用于表示如何渲染顶点数据,如:点、线、三角形。
第三阶段:几何着色器。该 新顶点构造出新的(或是其它的)图元来生成其他形状。例子中,它生成了另一个三角形。
第四阶段:光栅化。该阶段会把图元映射为最终屏幕上相应的像素,生成片段。片段(Fragment) 是渲染一个像素所需要的所有数据。
第五阶段:片段着色器。该阶段首先会对输入的片段进行 裁切(Clipping)。裁切会丢弃超出视图以外的所有像素,用来提升执行效率。
第六阶段:测试与混合。该阶段会检测片段的对应的深度值(z 坐标),判断这个像素位于其它物体的前面还是后面,决定是否应该丢弃。此外,该阶段还会检查 alpha 值( alpha 值定义了一个物体的透明度),从而对物体进行混合。因此,即使在片段着色器中计算出来了一个像素输出的颜色,在渲染多个三角形的时候最后的像素颜色也可能完全不同。
最后阶段,帧缓冲区(未在图中标明)。是由像素组成的二维数组,每一个存储单元对应屏幕上的一个像素,整个帧缓冲对应一帧图像即当前屏幕画面。帧缓冲通常包括:颜色缓冲,深度缓冲,模板缓冲和累积缓冲。这些缓冲区可能是在一块内存区域,也可能单独分开。

什么是着色器(Shader)
着色器.png
着色器

想象一下给方块上色,画阴影,画线条。上色、画图的这个工具叫着色器。

在OpenGL中的着色器可以着很多东西,比如这三个
下面几种都属于三维着色器
* 顶点着色器(VertexShader)

顶点着色器是最早的三维着色器,顶点着色器处理每一个顶点,将顶点坐标投影在屏幕上,即计算顶点的二维坐标,同时还可以计算深度坐标。
一般用于处理每个顶点变换(旋转/平移/投影等)
* 几何着色器
几何着色器可以在着色器中生成新的顶点;
* 细分曲面着色器
细分曲面着色器(英语:tessellation shader)则可以向一组顶点中添加细节。这些着色器都会被安排在流水线(管线)中的。

纹理

纹理,简单的理解就是一副图像。而把一副图像映射到图形上的过程,叫做纹理映射。

混合

在OpenGL中,物体透明技术通常被叫做混合(Blending)。透明是物体的混合色,这种颜色来自于不同浓度的自身颜色和它后面的物体颜色。
什么是矩阵、变换矩阵、投影矩阵
首先要明白什么是矩阵,然后要明白矩阵的变换,之后就会明白什么是投影矩阵。

矩阵

下图就是矩阵,是初中二年级学的内容,图中包含三个坐标xyz。

矩阵.png
A:1,0,5
B:0,-1,2
C:0,0,1
矩阵变换
矩阵变换.png
矩阵变换即是矩阵和矩阵的计算,比如加减乘除等。
计算结果后得到一个新的矩阵。
投影矩阵

也就是很多矩阵在一起被计算成投影到屏幕的坐标。

实际上是将要绘制的对象带入到了不同的坐标系中。我们注意到有这样几个坐标系:

更加形象的过程,如下图所示:

坐标变换流程.png
渲染上屏/交换缓冲区
离屏渲染/交换缓冲区.png

常规的OpenGL程序⾄至少都会有两个缓冲区。显示在屏幕上的称为屏幕缓冲区,没有显示的称为离屏缓冲区。在⼀一个缓冲区渲染完成之后,通过将屏幕缓冲区和离屏缓冲区交换,实现图像在屏幕上的显示。

什么是GLSL

GLSL - OpenGL Shading Language 也称作 GLslang,是一个以C语言为基础的高阶着色语言。它是由 OpenGL ARB所建立,提供开发者对绘图管线更多的直接控制,而无需使用汇编语言或硬件规格语言。

void main(void){
    gl_Position = ftransform();
}
void main(void){
    gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
}

OpenGL状态机

程序跑起来后需要去修改、设置、添加各种不同的状态,使图像按照我们的想法显示出来。状态机中保存了对象的生命周期、响应事件、状态事件等等

参考:
http://chuquan.me/2018/08/26/graphics-rending-principle-gpu/

https://blog.yuegs.com/2018/03/06/Android-opengl-matrix/

上一篇 下一篇

猜你喜欢

热点阅读