基本颜色理论
OpenGL支持的大多数显示设备都会使用一种组合三原色的方法来构成颜色值,三原色就是红色,绿色和蓝色。我们将其称为RGB颜色空间,并且使用这三个颜色值来表达每一种颜色,通常还会在增加第四个alpha分量(透明度),因此也可以称为RGBA颜色空间。
在计算机中每个分量的值都是使用一定数量的位来保存。在RGB颜色空间中红色,绿色和蓝色分量都占用了8个比特位,因此得到一个24位的颜色缓存,它可以显示总共224种独立的颜色。
缓存和用途
所有的图形程序都会把图形绘制到帧缓存上(屏幕),帧缓存是由矩形的像素数组构成的,每个像素都显示一个颜色值。通常在OpenGL中帧缓存集成了颜色缓存,深度缓存和模板缓存这几种类型的缓存。
颜色缓存
是我们通常要绘制的对象,它包含RGB或sRGB形式颜色的数据,帧缓存中可能有多个颜色缓存,其中默认的颜色缓存与屏幕窗口直接关联,其中的图像信息会直接显示到屏幕上,在OpenGL中广泛用到了双缓存技术,双缓存的实现需要将主颜色缓存划分位两个部分,直接在窗口显示的前置缓存,以及用来渲染的后置缓存,当我们交换缓存的时候(调用glSwapBuffers()),前,后置缓存将互换。
深度缓存
深度缓存为每个像素保存一个深度值,它可以帕纳的三维空间中物体的可见性,这里的深度物体与视点的距离,因此深度值大的像素会被深度值小的覆盖,
模板缓存
使用模板缓存来限制屏幕特定区域的绘制,可以把他想象成一个带有孔洞花纹的硬纸板,将它按在纸面上再使用喷漆进行喷绘,最后得到非常精确的花纹图案。
缓存的清除
通常在绘制完一帧后都需要清除一次缓存。
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);//设置清除值
glClear();//执行清除操作
OPenGL与颜色
在OpenGL中,片元着色器负责设置每个片元的颜色值。我们需要给片元着色器提供足够的信息,以生成这些值。OpenGL使用浮点数来表示一个颜色分量,并负责维护它的精度,直到保存到帧缓存,片元着色器中输入总是浮点数类型,这些值被限制在[0.0, 1.0]的范围内(归一化数值),用户程序提供的数据基本上都是C语言的数据类型,可以选择让非浮点数类型自动转化为归一化的浮点数。即通过glVertexAttribPointer()或者glVertexAttribN*()系列函数。
测试与操作
概述
在OPenGL渲染管线中,经过光栅化阶段后会生成一个个独立的片元,片元在进入帧缓存之前需要经过完整的测试过程,也就是渲染管线中的最后一个阶段——测试与混合阶段。这个阶段会对片元进行测试和操作,这些都可以用glEnable()和glDisable()来启用和禁止。如果一个片元在某项测试中没有通过,那么将会被丢弃,不参与之后的所有测试和操作。测试和操作的顺序为:剪切测试→多重采样→模板测试→深度测试→融混→抖动→逻辑操作
裁剪测试
裁剪测试是片元可见性测试的第一个附加测试。我们将程序窗口中的举行区域称为剪切盒,如果片元位于这个剪切盒内,那么它将通过剪切测试。可以使用glSocissor()来设置这个剪切盒的位置和大小,使用glEnable()并设置其参数为GL_SOCISSOR_TEST来开启测试。
默认情况下剪切矩形和窗口的大小是相等的,并且剪切测试是关闭的。
void glScissor(GLint x, GLint y, GLsizei width, GLsizei height) 功 能:设置剪切盒的位置和大小 返回值:void 参数:x 矩形左下角x坐标 y 矩形左下角y坐标 width 宽度 height 高度 |
多重采样
默认情况下,多重采样在技术片元的覆盖率时不会考虑alpha的影响,如果使用glEnable()开启某个特定模式中,那么片元alpha值将被纳入计算过程中。
void glSampleCoverage(GLfloat value, GLboolean invert) 功 能:设置多重采样覆盖率的参数 返回值:void 参数:value 如果开启GL_SAMPLE_CPVERAG或者 GL_SAMPLE_ALPHA_TO_CPVERAGE那么value是个临时的采样覆盖值 invert 设置这个临时的采样覆盖值是否先进行位反转 |
void glSampleMaski(GLuint index, GLbitfield mask) 功 能:设置一个32位的采样掩码mask。 返回值:void 参数:index 掩码本身的索引位置 mask 新的掩码 |
模板测试
要使用模板测试,需要在窗口建立的过程中创建好对应的模板缓存。如果没有模板缓存,那么模板测试总是通过的。
深度测试
对于屏幕上的每一个像素点,深度缓存都会记录场景中物体与视点在这个像素上的距离信息。深度缓存的主要用途是隐藏表面的消除。如果当前有一个新的候选颜色,那么只有对应的物体更靠近观察者的时候,才会绘制这个颜色.这样在绘制完整个场景后,只有那些没有被其他物体遮掩的物体才会出现在视野里。可以使用glDepthFunc()函数设置一个不同的深度测试比较函数。
void glDepthFunc(GLenum func) 功 能:设置深度测试的比较函数 返回值:void 参 数:func 默认的比较函数为GL_LESS,只有输入的片元的Z值小于模板缓存中的值时,深度测试值才会通过 |
融混
当一个片元通过所有所有相关测试,那么就可以与颜色缓存中当前的内容进行某种方法进行合并了,需要使用glEnable()函数并设置参数为GL_BLEND开器融混,如果需要使用alpha值,那么管线就需要得到更多有关当前图元的颜色信息,并且必须指定帧缓存的当前像素位置已经写入过什么颜色值。
在基本的融混模式下,输入的片元颜色将采样线性的方式与当前像素的颜色进行混合。如果使用(Sr,Sg,Sb,Sa)表示源混合参数,使用(Dr,Dg,Db,Da)表示目标混合参数,使用(Rs,Gs,Bs,As)和(Rd,Gd,Bd,Ad)分别表示源和目标像素的颜色值,那么得到一个融混方程,计算方式为(SrRs+DrRd, SgGs+ DgGd,SbBs+DbBs,SaAs+ DaAd).
可以调用glBlendFunc()设置两个融混参数
void glBlendFunc(GLenum sfactor, GLenum dfactor) 功 能:设置设置两个融混参数 返回值:void 参 数:sfactor 源数据的RGBA dfactor 目标数据的RGBA |
抖动
抖动操作本身是与硬件相关的。OpenGL能做的只是允许开启或者关闭这个特性。可以将参数GL_DITHER传入glEnable()glDisable()和中设置抖动的开启和关闭。抖动默认是开启的。
逻辑操作
逻辑操作包括或(OR),异或(XOR),和反转(INVERT),它作用于输入的片元数据和当前的颜色缓存中的数据。这类片元操作对位块传输是非常有用的,主要的图像操作就是将某一矩形数据拷贝到另一处,或者从窗口拷贝到内存中来。通常情况下这一操作不会直接写入到内存。而是允许用户对输入的数据和已有的数据直接进行一次逻辑操作,然后用操作的结果替换当前已有的数据。
参见:《OpenGL编程指南》第八版第4章