0
点赞
收藏
分享

微信扫一扫

计算机图形学笔记(七)

码农K 2022-04-26 阅读 95
c++

5.1何为“帧”缓冲区(Frame buffer)?

图形流水线

 

帧缓冲区(Frame buffer)与片元处理

1、缓冲区的每个单元对应的就是屏幕上一个个像素

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

 

显示器的分类

光栅扫描显示器---Raster-Scan Display

随机扫描显示器(向量显示器)---Random-Scan Display(Vector Displays)

随机扫描显示器(向量显示器)

像一个电子枪在画图

 

光栅扫描显示器(Raster-Scan Display)

 

1、像素的颜色都存储在一块缓冲区中

2、需要不断重复绘制,即不断刷新屏幕

帧缓冲区(Frame buffer)

1、存储视口中每个像素的信息

2、与视口像素一一对应

 

Refersh Rate(刷新率)

1、存储视口中每个像素的信息

2、常用单位:FPS,Frame per second

 

5.2颜色缓冲区

多种类型的帧缓冲区

颜色缓冲(Color buffer)

深度缓冲(Depth buffer)

模板缓冲(Stencil buffer)

累积缓冲(Accumulation buffer)----已废除

用户自定义的缓冲

颜色缓冲

存储视口中每个像素的颜色

 

颜色缓冲所占的存储空间

1、Resolution(分辨率):1024*768

2、像素颜色:采用RGB三个分量来表示颜色,每个分量采用8bits来表示

问题:该颜色缓冲需要多大的存储空间?

1024 * 768 * 8 bit / 1024 = 6144Kb

清除缓冲的操作

glClearColor(0.0,0.0,0.0,0.0);

glClear(GL_COLOR_BUFFER_BIT);

glClearDepth(1.0);

glClear(GL_DEPTH_BUFFER_BIT);

1、同时清除帧缓冲和深度缓冲

2、glClearColor(0.0,0.0,0.0,0.0);

glClear(GL_COLOR_BUFFER_BIT);

glClearDepth(1.0);

glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);

3、尽量同时清除多块缓冲,这样效率更高

问题:GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT是什么意思?

GL_COLOR_BUFFER_BIT :指定当前被激活为写操作的颜色缓存。

GL_DEPTH_BUFFER_BIT: 指定深度缓存。

单缓冲与双缓冲

双缓冲可避免屏幕闪烁

 

单缓冲只在Front Buffer缓冲,边画边缓冲,可能会出现闪屏的现象。

双缓冲先在Back Buffer缓冲,然后一次性复制到Front Buffer。

5.3深度缓冲去与Z-buffer消隐算法

Color Buffer and Depth Buffer

 

深度缓冲(Depth buffer)

1、Projection:3D->2D

(x,y,z)->(wx,wy)其实投影后也有一个z值,当为(wx,wy,wz)

2、在投影时,每个投影点的深度也会被记录下来,写入深度缓冲。

3、其实是:在光栅化时,每个片元的深度会计算出来,写入深度缓冲

 

视域空间中的深度范围

透视投影后的深度坐标范围是[0,1],其深度分布不均匀

 

深度缓冲(Depth buffer)

Depth buffer 也叫Z-buffer,为什么呢?

因为Z值,物体的Z值表示它的深度,

深度缓冲用处很多,但其中最主要的一个应用是“消隐(Visible surface detection)”

消隐(Visible surface detection)

 

若不作消隐处理,后绘之物总会挡住先绘之物

 

消隐的方法

Depth Sorting Method(深度排序算法)

Area-Subdivision Method(区域子算法)

Ray Casting Method(光线投射法)

Z-buffer算法

Z-buffer消隐算法

1、在把显示对象的每个面上每一点的颜色值填入帧缓冲器相应单元前,要把这点的深度值和Z-buffer中相应单元的值进行比较。

2、只有前者小于后者时才改变缓冲器的那一单元的值,同时Z-buffer中相应单元的值也要改成这点的深度值;否则帧缓冲器相应单元的值不变。

 

Z-buffer Method

 

 

 

 

 

 

 

 

 

 

 

 

 

 

1、Z-buffer算法在像素级上以近物取代远物。面片在屏幕上的出现顺序是无关紧要的。

2、这种取代方法实现起来远比总体排序灵活简单,有利于硬件实现。

3、缺点:占用空间大,没有利用图形的相关性与连续性。

深度精度不够的导致的闪烁现象

透视投影后的深度坐标范围是[0,1],其深度分布不均匀。

 

5.4OpenGL中关于深度缓冲的函数

深度缓冲使用相关的三个函数

glEnable(GL_DEPTH_TEST);

会进行深度比较      注意:是两个作用

会根据当前绘制内容更新 depth buffer

Void glDepthFunc(GLenum func);

深度比较的方式:Func

Func可取:

GL_NEVER,GL_LESS,GL_LEQUAL,GL_EQUAL,

GL_GREATER,GL_NOTEQUAL,GL_GEQUAL,GL_ALWAYS

Void glDepth Mask(GLboolean flag);

设置是否更新深度缓冲

如果不想更新深度,那么将flag设为false

glDisable(GL_DEPTH_TEST);

---深度比较和更新深度缓冲这两个动作都不会发生

如果不想更新深度缓冲,只想比较,那可以:

glEnable(GL_DEPTH_TEST);

glDepthMask(false);

默认是:

glDisablee(GL_DEPTH_TEST);

glDepthMask(false);

glDepthFunc(GL_LESS);

深度缓冲的使用技巧举例

预绘制:

打开深度绘制;

绘制这片树林,记录其深信度值到深度缓冲;

保存绘制的树木图像。

实时绘制:

把预存的树木图像画到屏幕上;

glEnable(GL_DEPTH_TEST);

glDepthMask(false);

画树林中的物体。---也就是说进行深度比较,但并不更新深度缓存。

 

问题:如果不想比较深度值,只想更新深度缓冲,那怎么办?

glEnable(GL_DEPTH_TEST);

glDepthFunc(GL_ALWAYS);

glDepthMask(true);

举报

相关推荐

0 条评论