第四章 颜色、像素和帧缓存
4.1 基本颜色理论
- RGB颜色空间–三原色构成显示设备的整个色域
- 颜色缓存的一个通常格式是:每个红色、绿色和蓝色分量都占用8位;因此我们得到了一个像素深度为24位的颜色缓存,它可以显示总共2的24次方种独立的颜色
4.2 缓存及其用途
-
每个片元都包含与像素对置对应的坐标数据,以及颜色和深度的存储值
-
通常来说,像素(x,y)填充的区域是以x为左侧,x+1为右侧,y为底部,y+1为顶部的一处矩形区域
-
颜色缓存只是记录像素信息的多个缓存中的一个
-
硬件系统的帧缓存包含所有的缓存内容,因此我们也可以在应用程序中使用多个帧缓存
-
OpenGL系统中通常包含三种缓存类型:
- 一个或多个可用的颜色缓存(color buffer)
- 深度缓存(depth buffer)
- 模板缓存(stencil buffer)
-
所有类型的缓存都被集成到帧缓存当中,尽管我们可以自由决定需要用到哪些缓存,但是当启动应用程序后,我们使用的是默认的帧缓存,它是与应用程序所关联的帧缓存
-
默认帧缓存总是会包含一个双重缓冲机制(double-buffered)的颜色缓存
颜色缓存
- 颜色缓存是我们通常进行绘制的缓存对象。
- 它包含RGB或者sRGB形式的颜色数据,也可能包含帧缓存中每个像素的alpha值
- 帧缓存中可能会包含多个颜色缓存。其中,默认帧缓存中的“主”颜色缓存要特别对待,因为它是与屏幕上的窗口相关联的,所以绘制到其中的图像都会直接显示到屏幕上,而所有其他的颜色缓存都是与屏幕无关的
- 颜色缓存中的像素,可能是采用每个像素存储单一颜色值的形式,也可能从逻辑上被划分为多个子像素,因此启用了一种名为多重采样(multisampling)的反走样技术形式
- 双重缓冲的实现需要将主颜色缓存划分为两个部分:直接在窗口中显示的前置缓存(front buffer),以及用来渲染新图像的后备缓存(back buffer)
- 只有默认帧缓存中的主颜色缓存可以使用双重缓冲的特性
深度缓存
- 深度缓存为每个像素保存一个深度值,它可以用来判断三维空间中物体的可见性
- 这个深度是物体与观察者眼睛的距离
模板缓存
- 模板缓存可以用来限制屏幕特定区域的绘制
4.2.1 缓存的清除
-
通常每帧都至少需要一次清除缓存的操作
-
设置不同缓存的清除值:
- void glClearColor(GLclampf red, GLclampf green, GLclamp blue, GLclampf alpha)
- void glClearDepth(GLclampd depth)
- void glClearDepthf(GLclampf depth)
- void glClearStencil(GLint s)
- GLclampf和GLclampd类型(即截断后的GLfloat和GLdouble)需要被截断到0.0~1.0区间内
-
设置清除值之后,就可以使用glClear()来执行缓存清除操作了
-
void glClear(GLbitfield mask) mask的取值
- GL_COLOR_BUFFER_BIT
- GL_DEPTH_BUFFER_BIT
- GL_STENCIL_BUFFER_BIT
-
如果启用了像素的所有权测试(ownership test)、剪切测试(scissor test)或者抖动(dithering)特性,那么他们会对清除操作产生影响;同理还有glColorMask()所设置的掩码操作;但是,深度测试和模板测试不会影响到glClear()的结果
4.2.2 缓存的掩码
- void glColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
void glColorMaski(GLuint buffer, GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
void glDepthMask(GLboolean flag)
void glStencilMask(GLboolean mask)
void glStencilMaskSeparate(GLenum face, GLuint mask) - 如果glDepthMask()的参数flag为GL_TRUE,那么深度缓存可以写入;否则无法写入
- glStencilMask()的mask参数与模板值按位“与”操作,如果对应位操作的结果为1,那么像素的模板值可以写入;如果为0则无法写入
- glStencilMaskSeparate()可以为多边形的正面和背面设置不同的掩码值
- 如果需要渲染到多个颜色缓存,glColorMask()可以对特定的缓存对象设置颜色掩码
4.3 颜色与OpenGL
- 片元着色器负责设置每个片元的颜色值,而有多种方式完成这一操作
- 片元着色器可以不借助任何外部数据,直接就生成片元的颜色值
- 每个输入的顶点都会提供一个附加的颜色数据,这个颜色数据可以其他着色阶段中修改再传入片元着色器,并且用它来判断颜色值
- 颜色的补充(并不是具体的颜色值)–可以在片元着色器中通过计算来生成颜色值