OpenGL(三): 名词解析
-
OpenGL上下文(context)
在应用程序调用任何OpenGL指令前,需要创建一个OpenGL的上下文。这个上下文是一个非常庞大的状态机,保存了OpenGL中的各种状态。
在应用程序中可以不止一个上下文。因为切换上下文会产生比较大的开销,所以绘制不同的模块,需要使用完全独立的状态管理。在不同的线程中使用不同的上下文,上下文之间共享纹理、缓冲区等资源。
-
OpenGL状态机
状态机是理论上的一种机器,状态机描述了一个对象在其生命周期内所经历的各种状态,状态间的转变,发生转变的动因、条件及在转变过程中所执行的活动。也可以说,状态机是一种行为,说明对象在其生命周期中响应事件所经历的状态序列以及对那些状态事件的响应。
状态机的特点:
- 具有记忆功能,能记住其当前的状态
- 可以接收输入,根据输入的内容和自己原先的状态,修改自己当前的状态,并且可以有对应输出
- 当进入特殊状态(停机状态)的时候,便不再接收输入,停止工作
-
渲染
将图形/图像数据转换成3D空间图像的操作叫做渲染
-
顶点数组和顶点缓冲区
顶点是指绘制图形的各个顶点的位置数据。而这些顶点数据一般存储在数组中,这个数组就叫做顶点数组。在图形渲染过程中,各个顶点的数据需要传给GPU做运算,但是GPU读取顶点数组是需要耗时的,为了提高性能,先将顶点数据缓存在GPU的显存中,这部分显存就是顶点缓冲区。
-
管线
在OpenGL中,任何事物都在3D空间中,而屏幕和窗口却是2D像素数组,这就导致OpenGL的大部分工作都是关于把3D坐标转换为适应屏幕的2D像素。而3D坐标转为2D坐标的处理过程是由OpenGL的图形渲染管线管理的。
图形渲染管线可以被划分为两个主要部分:第一部分把你的3D坐标转换为2D坐标,第二部分是把2D坐标转变为实际的有颜色的像素。
-
着色器
图形渲染管线接受一组3D坐标,然后把它们转变为屏幕上的有色2D像素输出。图像渲染管线分为几个阶段,每个阶段会把前一个阶段的输出作为输入。这些阶段使用特定的函数执行,并且可以并行执行。由于他们具有并行执行的特性,所以在GPU上为每一个阶段都运行了不同的程序,这些程序就叫做着色器。
-
图形渲染管线的各个阶段
image-20190516212634869.png
-
顶点着色器(Vertex Shader)
其主要目的是把3D坐标转换为另一种3D坐标(标准化设备坐标NDC),同时允许对顶点属性进行一些基本处理(旋转/平移/投影)。
顶点着色器是逐顶点运算的,每个顶点数据都会执行一次顶点着色器,并且这个执行都是并行的。
-
图元装配(Primitive Assembly)
图元装配阶段将顶点着色器输出的所有顶点数据作为输入,并将所有的点装配成指定图元的形状。
-
几何着色器(Geometry Shader)
图元装配阶段的输出会传递给几何着色器。几何着色器把图元形式的一些列顶点的集合作为输入,它可以通过产生新顶点构造出新的图元来生成其他形状。
-
光栅化(Rasterization Stage)
几何着色器的输出会被传入光栅化阶段,它会把图元映射为最终屏幕上相应的像素,生成供片元着色器使用的片元。在片元着色器运行之前会执行裁剪。裁剪会丢弃超出视图之外的所有像素,用来提升执行效率。
-
片元着色器(Fragement Shader)
片元着色器的主要目的是计算一个像素的最终颜色,这也是所有OpenGL高级效果产生的地方。通常,片元着色器包含3D场景的数据(关照、阴影、光的颜色等),这些数据可以被用来计算最终像素的颜色。
-
测试和混合
在所有对应颜色值确定以后,最终的对象将会被传递到最后一个阶段——Alpha测试和混合阶段。这个阶段检测片段的对应的深度值,用它们来判断这个像素是在其他物体的前面还是后面,决定是否应该丢弃。这个阶段也会检查alpha值并对物体进行混合。
在图形渲染管线的各个阶段中,部分着色器是允许开发者配置的,以适用于各种不同的使用场景中,而开发者经常配置的着色器是顶点着色器和片元着色器。
-
OpenGL的坐标变换
image-20190516221457571.png顶点坐标起始于局部空间(Local Space),在该空间中的坐标为局部坐标(Local Coordinate),经过模型变换(Model transformation)为世界空间(World Space),此时为世界坐标(World Coordinate)。再经视变换(View transformation)为观察者空间(View Space),该空间的坐标为观察坐标(View Coordinate)。经投影变换(Projection transformation)变换为裁剪空间(Clip Space),此时坐标为裁剪坐标(Clip Coordinate),最后再经视口变换(Viewport transformation)变换为屏幕空间(Screen Space)中的屏幕坐标(Screen Coordinate)。