OpenGL

002 --- 帧缓存区 光栅化 图形撕裂 CoreAnimat

2020-07-16  本文已影响0人  清风烈酒2157

[toc]

image.png

何为帧缓冲区

(Frame buffer)帧缓冲区的每个单元对应的就是屏幕上的一个个像素.

image.png image.png

对片元的处理就是在利用并修改缓冲区的数据

  1. 帧缓冲区存储视口中的每个像素的信息
  2. 并且与视口像素一一对应
  3. 常用单位刷新率:FPS (Frame per second),以每秒钟绘制几屏为标准

显示器分类

也称向量显示器,它像一个电子枪在画图

image.png

光栅扫描显示器(Raster-Scan Display),它不会控制电子枪,只会一行一行的扫描,每扫描一行都会去缓冲区中查询像素值,然后进行填充

image.png

视觉暂留,每扫描的一屏称为一帧(frame)

帧缓存区

  1. 像素的颜色都存储在一块缓冲区
  2. 需要不断重复绘制,即不断刷新屏幕
  3. 光栅扫描需要至少每秒扫描60帧,来保证荧光粉或者液晶的视觉暂留,每扫描的一屏称为一帧(frame)
颜色缓冲区

帧缓冲区分为多种类型,它存在于显存中:

颜色缓冲区中存储的就是颜色,其所占的空间与分辨率以及颜色分量有关,例如下面的条件:

则需要占据空间是
1024×768×3=2.25m1024×768×3=2.25m字节

在画图之前需要清除当前缓冲区,也就是画图之前需要铺一张白纸,在OpenGL中有以下函数

// 1、清除颜色缓存
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);//定义清除颜色缓冲区需要用什么颜色来清除
glClear(GL_COLOR_BUFFER_BIT);       // 清除颜色缓存传递参数

// 2、清除深度缓存
glCLearDepth(1.0);          // 定义用1.0来清除深度缓存,1.0是最大深度
glClear(GL_DEPTH_BUFFER_BIT);// 清除深度缓存传递参数

// 3、同时清除颜色和深度缓存
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glCLearDepth(1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // 同时清除颜色和深度缓存


单缓冲机制就是直接向前置缓冲(Front buffer)绘制,然后立刻显示在显示器上:

image.png

双缓冲机制在绘图之前先不向前置缓冲(Front buffer)中绘制,而是把数据存储在后置缓冲(Back buffer 此buffer和屏幕没有连接)起到了一个过渡的作用,等Front buffer绘制完成之后,后再把Back buffer 中的数据 Copy 到 Front Buffer 中,然后再显示在显示器上:

image.png

双缓冲可以避免屏幕的闪烁

参考

OPENGL - 帧缓冲区了解

图像撕裂问题好解决方法

image.png

图像 -> CPU将图片解码,交给GPU -> GPU进行图像的渲染 -> 存储到到帧缓存区 -> 视频控制器进行读取帧缓存区信息,并刷新部件(视频控制器只是负责帧缓存区与显示器的对应关系) -> 显示器逐行扫描显示。

在视频控制器进行读取显示图像时,当当前这一帧的内容还未读取完成时,GPU将新的一帧内容提交到帧缓冲区并把两个帧缓冲区进行更新后,视频控制器就会把新的一帧数据的下半段显示到屏幕上,造成画面撕裂的现象。

既撕裂就是在于显卡输出帧的速度比显示器快,显示器的处理速度跟不上显卡,在显示器处理显卡丢过来的第1帧的时候,第2帧就又到了,导致同一个画面同时出现1、2两帧,撕裂就产生了。

  1. 苹果方案:垂直同步又称场同步(Vertical synchronization) + 双缓冲区
image.png

垂直同步就是加锁,在当前读取的帧数据结束之前,不会读取下一帧的数据。
双缓冲区是在帧缓存区中开辟两个缓冲区,一个缓冲区通过视频控制器进行当前帧数据的读取显示,另一个缓冲区进行接收下一帧GPU渲染的图像。两个缓冲区都执行结束,然后再交换缓冲区。

使用以上两个解决方案后,图像撕裂问题解决了,但是有引发了一个新问题掉帧/卡顿。
GPU等待VSynv信号的到来,进行新一轮渲染和缓存区更新,如果下一个垂直同步信号到来,没有完成渲染,就会发生掉帧(卡顿),原因,cpu或者gpu任务繁重.看到还是上一秒内容.

  1. 三缓存区
上一篇 下一篇

猜你喜欢

热点阅读