状态机
可以理解为一个保存对象当前状态,且可以根据输入修改当前状态进行响应的机器
特点
- 记忆功能:保存当前状态(如使用颜色、混合功能是否开启等)
- 接收输入:根据输入修改当前状态,且有相应输出
- 进入停机状态时,不再接受输入,且停止工作
上下文 Context
- 一个保存OpenGL中各种状态的庞大状态机,
- 是OpenGL指令执行的基础,需要在调用指令之前创建
OpenGL函数 与 上下文
- 不论何种语言,OpenGL函数都是面向过程的函数
- 函数本质:对context中某个状态/对象进行操作
- 可以通过对OpenGL指令的封装,将OpenGL的相关函数调用封装成一个面向对象的图形API
问题:反复上下文切换/大量修改渲染状态,导致GPU开销较大
- 针对不同模块,创建不同的context进行状态管理,context之间共享纹理、缓冲区等资源
渲染 Rendering
将图形/图像数据通过解码,将其显示绘制到屏幕上的操作
OpenGL ES中的图元类型
屏幕中的所有图形/图像,都是由这三种图元组合而成的
- 点
- 线
- 三角形
顶点数据存储方式
顶点数组与顶点缓冲区的区别在于顶点数据的存储方式不同
- 存储在内存中,即 【顶点数组】
- 存储在GPU提前分配的显存中,即 【顶点缓冲区】
管线
可以理解为流水线,该流水线有一个固定顺序的操作,需要按着这个顺序一个个执行
固定管线/存储着色器
- 一个已经封装好的Shader程序,开发者使用时,只需要传入相应参数,即可快速完成渲染,类似苹果系统中封装好的API
- 当固定管线无法完成每个业务时,需要将与业务相关的部分变成可编程,用户根据需要自定义管线来完成业务
- 目前OpenGL中可编程的仅有两个程序:顶点着色器、片元着色器
顶点着色器
- OpenGL中用来处理顶点相关代码的程序
- 将顶点坐标由 自身坐标系 转换到 归一坐标系
- 是逐顶点运行的程序,即每个顶点数据都会执行一次,且是并行的
操作
- 确定顶点位置
- 处理图形顶点的变换(旋转、平移、缩放)
- 3D图形数据 投影换算 为2D图形数据
片元着色器
- 片元:理解为屏幕中的像素点
- 片元着色器主要用于处理一个个的像素点,例如像素颜色的计算和填充
- 逐像素且在GPU并行运行的程序,即每个像素都会执行一次
举例说明:图片饱和度是如何完成的?
- 通过片元着色器进行一个个像素点的修改来实现
GLSL(OpenGL Shading Language)
- OpenGL中着色编程的语言
- 开发者可以使用该语言,自定义着色器
光栅化
通过2个步骤产生片元的一个过程
具体描述
- 顶点数据转换为片元
- 几何图元转化为二维图像
- 把物体的数学描述和相关的颜色信息转换为屏幕上对应位置的像素及填充像素颜色
- 将模拟信号转换为离散信号
- 是不可编程的过程
作用
将图转化为一个个栅格组成的图像
特点
每个元素对应帧缓冲区中的一像素
执行的操作
- 确定图形的像素范围
- 颜色附着上去,即分配一个颜色值和一个深度值到各个区域
纹理
可以理解为图片
目的
- 渲染图形时,可以使场景更加逼真
混合 Blending
可以理解为两个图形/图像相交处的颜色,该颜色即为两个图形/图像颜色的混合
变换矩阵 Transformation
用于图形的平移、旋转、缩放时使用
投影矩阵 Projection
将3D坐标转换为2D屏幕坐标时使用
渲染上屏/交换缓冲区 SwapBuffer
- 渲染缓冲区:可以理解为是系统的资源,例如窗口
- 渲染上屏:将图像直接渲染到窗口对应的渲染缓冲区
问题:如果每个窗口只有一个缓冲区,在绘制过程中刷新了屏幕,窗口可能显示不出完整的图像
- 常规OpenGL程序中至少会有两个缓冲区
==> 屏幕缓冲区:用于显示在屏幕上
==> 离屏缓冲区:没有显示的 - 在一个缓冲区渲染完成后,将屏幕缓冲区和离屏缓冲区进行交换,实现图像在屏幕上的显示
问题:防止交换缓冲区时屏幕上下区域的图像分属于两个不同的帧
- 显示的刷新一般是逐行进行的,因此交换一般会等待显示器刷新完成的信号,在显示器两次刷新的间隔中进行交换
==> 信号:垂直同步信号
==> 技术:垂直同步技术
问题:使⽤用了了双缓冲区和垂直同步技术之后,由于总是要等待缓冲区交换之后再进行下一帧的渲染,使得帧率 无法完全达到硬件允许的最⾼⽔平
三缓冲区技术
- 在等待垂直同步时,来回交替渲染两个离屏的缓冲区
- 垂直同步发生时,屏幕缓冲区和最近渲染完成的离屏缓冲区交换