第5章 图元的属性
任何影响图元显示方法的参数一般称为属性参数(attribute parameter),例如颜色和大小等属性参数确定了图元的基本特性。
将属性选择加入图形软件包的一种方法是,为每个输出图元函数扩充相关的参数表,从而引入合适的属性。例如,画线功能除了包括端点坐标以外,还可以包含颜色、宽度和其他属性的参数。另一种方法是提供一张系统当前属性值表,并使用包含在图形软件包中的独立函数来为属性表设置当前值。为了生成一个输出图元,系统要检测相关的属性,并使用当前属性设置来调用该显示程序。有些图形软件包使用两种属性值设定方法的组合,而OpenGL等其他图形库则使用更新系统属性表的独立函数来设定属性。
维护属性和其他参数当前值表的图形系统称为状态系统(state system)或状态机(state machine)。输出图元的属性和当前帧缓存位置等其他参数称为状态变量(state variable)或状态参数(state parameter)。在给一个或几个状态参数赋值时,系统进入一个特定状态。该状态一直保留到状态参数的值再次改变。
5.1 OpenGL状态变量
属性值和其他参数设置由定义当前OpenGL状态的独立函数指定。OpenGL中的状态变量有颜色和其他图元属性、当前矩阵模式、模型观察矩阵的元素、缓存当前位置和场景光照效果参数等。所有OpenGL参数都有默认值,它们在被指定新值前保持不变并发挥作用。任何时候我们都可以查询系统状态参数的当前值。
5.2 颜色和灰度
5.2.1 RGB颜色分量
在彩色光栅系统中,可以选用的颜色数量依赖于帧缓存中提供的存储容量。颜色信息可以用两种方式存储在帧缓存中:直接在帧缓存中存储红色、绿色和蓝色(RGB)编码,或将颜色码存入一个独立的表中并在像素位置存储指向颜色表表项的索引
颜色码 | 红色 | 绿色 | 蓝色 | 显示颜色 |
---|---|---|---|---|
0 | 0 | 0 | 0 | 黑色 |
1 | 0 | 0 | 1 | 蓝色 |
2 | 0 | 1 | 0 | 绿色 |
3 | 0 | 1 | 1 | 青色 |
4 | 1 | 0 | 0 | 红色 |
5 | 1 | 0 | 1 | 黑色 |
6 | 1 | 1 | 0 | 品红 |
7 | 1 | 1 | 1 | 白色 |
2.2 颜色表
在颜色查找表(color lookup table)或颜色表(color map)中存储颜色值的一种可能方案。有时颜色表还称为视频查找表(video lookup table)。这时帧缓存中的值用做指向颜色表的索引。
例如,每一像素可引用256个表位置中的任意一个,而每一表项使用24位来指定一个RGB颜色。十六进制颜色码0x0821使像素位置 ( x , y ) (x,y) (x,y)处显示绿蓝混合色。使用这种特殊的查找表的系统让用户可从近1700万种颜色中任选256种颜色同时显示。与全彩色系统相比,这种方案减少了可同时显示的颜色量,但也使帧缓存容量减少到只要1MB。处理反走样等特殊的绘制应用及有多个输出设备时,有时需要多个颜色表。
2.3 灰度
由于计算机图形系统都具有彩色功能,我们可以在应用程序中使用RGB颜色函数来设定灰色程度或灰度(gray scale)。当RGB函数中指定相同量的红色、绿色和蓝色时,结果是某种程度的灰色。靠近0的值生成暗灰色,而靠近1的值生成亮灰色。灰度显示方法的应用包括增强黑白照片和产生可视化效果。
2.4 其他颜色参数
除了RGB颜色描述,计算机图形应用还使用一些其他的三分量颜色描述。例如,打印机输出颜色用青色、品红和黄色三分量来描述,而颜色的界面有时用亮和暗来选择颜色。通常意义下的颜色和光是一种复杂现象,在光学、辐射度和心理学中提出了许多术语及概念,用来描述光源和光照效果的各个方面。在物理上,一种颜色可以描述为有一定频率范围和能量分布的电磁辐射,但也涉及我们对颜色的感觉。因此,我们使用物理术语强度(intensity)来量化一个时间段中在特定方向的光能辐射,而用心理学术语亮度(luminance)来描述感觉光亮的特征。
3. OpenGL颜色函数
颜色显示模型(color display mode)设定为RGB
glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB)
变量表中的第一个常量指示正在使用单个帧缓存,第二个常量设定RGB模式,即默认模型。如果要用指向颜色表的索引来指定颜色,则用OpenGL常量GLUT_INDEX
取代GLUT_RGB。在需要为图元指定一组特殊的颜色值时,将OpenGL定义成这种颜色状态。
3.1 OpenGL的RGB和RGBA颜色模型
可以在调用函数glutInitDisplayMode时使用OpenGL常量GLUT_RGBA
来选择这个模式,颜色调和是一个重要应用的模拟透明效果。
在RGB(或RGBA)模式中,使用下面的函数来选择当前颜色分量:
g1Color*(colorComponents)
使用3或4及数值的数据类型码和一个任选的向量后缀一起指定RGB或RGBA模式。该数值数据类型是b(字节)、i(整数)、s(短整数)、f(浮点数)和d(双精度浮点数)及无符号数值。颜色分量的浮点数范围从0.0到1.0,g1Color包括 α \alpha α值的默认颜色分量是(1.0,1.0,1.0,1.0),它将RGB颜色设成白色而 α \alpha α值为1.0。如果我们使用RGB描述(即使用g1Color3代替g1color4),则 α \alpha α分量自动地设成1.0,表示不需要颜色调和。
g1Color3f (0.0, 1.0, 1.0);
如果要使用数组指定三个颜色分量,则可按如下方式设定这个例子中的颜色:
g1Color3fv(colorArray):
在OpenGL的内部,颜色信息用浮点数表示。我们也可以用整数来描述颜色,但它们被自动地转换成浮点数。该转换依赖于我们选择的数据类型和该类型数据能描述的范围。
例如, 无符号字节型数值(后缀码为ub)的范围从0到255,对应于某些窗口系统中使用的颜色描述。我们可以在前面的例子中这样来指定青色:
g1Color3ub(0, 255, 255)
如果用无符号32位整数(后缀码为ui),范围是 0 ∼ 4294967295 0\sim 4294967295 0∼4294967295。
3.2 OpenGL颜色索引模式
OpenGL中也可以使用指向颜色表的颜色索引模式(color-index mode) 来指定颜色。在该模式下,通过指定一个指向颜色表的索引来设定当前颜色:
g1Index*(colorIndex):
在OpenGL基本库中没有装载颜色查找表的函数,因为表处理子程序是窗口系统的一部分。有的窗口系统支持多个颜色表,而另外一些则仅有一个颜色表及有限的选择。然而,有一个GLUT子程序可用来与窗口系统进行交互,从而为给定的一个索引位置指定颜色如下:
glutSetColor(index, red, green , blue);
OpenGL核心库扩充了处理另外三个颜色表的子程序。它们是OpenGL成像子集(Imaging Subset)的一个部分。存在这些表中的颜色值可通过各个缓存处理来修改像素值。使用这些表的例子有设定照相机的聚焦效果、从图像中过滤掉某些颜色、增强某种强度或调整亮度、将灰度照片转换成彩色及显示的反走样等。可以利用这些表来改变颜色模型,即将RGB颜色改变为使用另外三个“基色”(如青色、品红和黄色)的颜色描述。
OpenGL成像子集中使用GL_COLOR_TABLE
、GL_POST_CONVOLUTION_COLOR_TABLE
或GL_POST_COLOR_MATRIX_COLOR_TABLE
名字的特定颜色表由g1Enable函数来激活。
3.3 OpenGL颜色调和
在许多应用中,很容易混合重叠对象的颜色或将一个对象与背景调和。这样的例子有模拟画笔效果、将两张或多张照片混合成一张、透明效果建模和场景中对象的反走样。许多图形软件包提供生成多种颜色调和效果的方法,这些函数称为颜色调和函数(color-blending function)或图像混合函数(image-compositing function)。在OpenGL中,通过先将第一个对象装载进帧缓存,再将第二个对象的颜色与帧缓存颜色相混合来实现两个对象颜色的调和。当前帧缓存颜色称为OpenGL目标颜色(destination color),而第二个对象的颜色称为OpenGL源颜色(source color)。调和方法仅在RGB或RGBA模式下完成。要在应用中进行颜色调和,必须先用下面的函数激活这个OpenGL特性:
g1Enable(GL_BLEND)
使用下面的函数将关闭OpenGL的颜色调和子程序:
g1Disable (GL_BLEND)
如果颜色调和没有被激活,则一个对象的颜色将简单地取代帧缓存中相应位置的内容。
将要装入帧缓存的新的调和颜色计算如下:
(
S
r
R
s
+
D
r
R
d
,
S
g
G
s
+
D
g
G
d
,
S
b
B
s
+
D
b
B
d
,
S
α
A
s
+
D
α
A
d
)
(S_rR_s + D_rR_d, S_gG_s+D_gG_d, S_bB_s+D_bB_d, S_\alpha A_s + D_\alpha A_d)
(SrRs+DrRd,SgGs+DgGd,SbBs+DbBd,SαAs+DαAd)
其中,RGBA源颜色分量为
(
R
s
,
G
s
,
B
s
,
A
s
)
(R_s,G_s,B_s,A_s)
(Rs,Gs,Bs,As) ,目标颜色分量为
(
R
d
,
G
d
,
B
d
,
A
d
)
(R_d,G_d,B_d,A_d)
(Rd,Gd,Bd,Ad),源调和因子为
(
S
r
,
S
g
,
S
b
,
S
α
)
(S_r,S_g,S_b,S_\alpha)
(Sr,Sg,Sb,Sα),而目标调和因子为
(
D
r
,
D
g
,
D
b
,
D
α
)
(D_r,D_g,D_b,D_\alpha)
(Dr,Dg,Db,Dα)。计算出的组合颜色分量归一到0.0到1.0之间。即任何大于1.0的总和均设为1.0,而任何小于0.0的总和设为0.0。
使用下列函数可选择调和因子的值:
g1BlendFunc(sFactor,dFactor)
参数sFactor和dFactor,即源和目标因子,都用OpenGL符号常量赋值以指定为预定义的一组四元素调和系数。例如,常量GL_ZERO表示调和因子(0.0, 0.0, 0.0, 0.0),而GL_ONE表示(1.0, 1.0, 1.0, 1.0)。
使用GL_DST_ALPHA
或GL_SRC_ALPHA
将四个调和因子设为
α
\alpha
α。其他可用来设定调和因子的OpenGL常量有GL_ONE_MINUS_DST_ALPHA
、GL_ONE_MINUS_SRC_ALPHA
、GL_DST_COLOR
和GL_SRC_COLOR
。调和因子的作用是模拟透明性。
sFactor的默认值是GL_ONE,而dFactor的默认值是GL_ZERO。因此,这两组调和因子的默认值将导致新来的颜色值取代帧缓存中的当前颜色值。
3.4 OpenGL颜色数组
必须先激活OpenGL数组
g1EnableClientState (GL_COLOR_ARRAY)
然后,对RGB模式要指定颜色分量的位置和格式:
g1ColorPointer (nColorComponents, dataType , offset, colorArray):
参数nColorcomponents赋值为3或4,取决于是否在数组colorArray中列出RGB或RGBA颜色分量。OpenGL符号常量如GL_INT或GL_FLOAT赋给参数datarype来指向颜色值的数据类型。对于一个单独的颜色数组,我们可将0赋给参数offset。但是如果将颜色数据和顶点数据组合在同一个数组中,则offset的值是数组中每一组颜色分量的字节数。
我们可以将颜色和顶点坐标一起装入一个交错数组(interlaced array)。每一个指针用适当的位移值指向单一的交错数组。例如,
static GLint hueAndPt []=
[1.0,0,0,0,0,1,0,0,0.1.0.
0.0,1,1,0.0,0,0,1,1.1.0.
1.0,0,0,0,1.1,0,0,0,1,1,
0,0,1,1,0,1,0,0,1,1.1,1];
g1VertexPointer (3. GL_INT.6* sizeof(GLint). hueAndPt[3]);
g1ColorPointer (3. GL_INT,6* sizeof(GLint), hueAndPt[0]);
因为一个场景通常包括若干个对象,每个对象有多个平表面,OpenGL提供一个可以一次性指定所有顶点和颜色数组及其他类型信息的函数。如果我们要将上例中的颜色和顶点值改为浮点数,则需按照下面的格式使用该函数:
glInterleavedArrays (GL_C3F_V3F,0,hueAndPt)
第一个参数是一个OpenGL常量,用来指定颜色(C)和顶点(V)的三元素浮点描述。而数组hueAndPt按每个顶点的颜色放在其坐标前的方式交错。该函数也自动地激活顶点和颜色数组。
3.5 其他OpenGL颜色函数
OpenGL中有几个颜色缓存可用做显示场景的当前刷新缓存,而函数g1Clearcolor 指定所有颜色缓存的颜色。然后用下面的命令将净颜色用于这些颜色缓存:
g1Clear(GL_COLOR_BUFEER_BIT)
我们也可以用g1Clear函数设定OpenGL中有效的其他缓存的初始值。它们是存放调和颜色信息的累积缓存(accumulation buffer)、存放场景对象深度值(离观察位置的距离)的深度缓存(depth buffer)及存放定义图形范围的模板缓存(stencil buffer)。
在颜色索引模式下,使用下面的函数(而不是g1Clearcolor)设定显示窗口的颜色:
g1ClearIndex (index)
窗口背景色用存放在颜色表中index位置的颜色来指定。执行g1Clear(GL_COLOR_BUFFER_BIT)函数后窗口就以该颜色显示。
4. 点的属性
一般情况下,我们可以设定点的两个属性:颜色和大小。
5. OpenGL点属性函数
指定点位置的显示颜色由状态表中的当前颜色值控制。而该颜色用g1Color函数或g1Index函数来指定。
我们使用下面的函数来指定OpenGL中点的大小:
g1PointSize(size)
该点以像素方块的形式显示。参数size用正浮点数值指定,该值舍入到一个整数(除非该点经反走样处理)。显示该点的水平和垂直像素数由参数size决定。
属性函数可以出现在g1Begin/g1End函数对之内或之外。例如,下列程序段绘制三个不同颜色和大小的点。第一个是标准大小的红色点,第二个是双倍尺寸的绿色点,而第三个是三倍尺寸的蓝色点:
g1Color3f(1.0,0.0,0.0);
g1Begin (GL_POINTS);
g1Vertex2i(50.100);
g1PointSize (2.0);
g1Color3f (0.0,1.0,0.0);
g1Vertex2i(75.150);
g1PointSize (3.0);
g1Color3f (0.0.0.0,1.0);
g1Vertex2i(100,200);
g1End();
6. 线的属性
直线段可以使用三个基本属性来显示:颜色、线宽和线型。线的颜色使用对所有图元相同的函数进行设定,而线宽和线型则使用单独的线函数选择。另外,线还可以生成如画笔和笔刷等其他效果。
6.1 线宽
线宽选择的实现取决于输出设备的能力。在视频监视器上的粗线可以用相邻的平行线进行显示,而在笔式绘图仪上则可能需要更换画笔来绘制粗线。
在光栅实现中,类似于Bresenham算法,通过在每个取样位置处使用一个像素来生成标准线宽。其他线宽则是作为标准线宽的正整数倍,通过沿相邻平行线路径绘制额外的像素而显示。
6.2 线型
可以选用的线型属性有实线、虚线和点线等。许多图形系统都允许选择划线长度和划线间隔的长度。
6.3 画笔或画刷的选择
7. OpenGL线属性函数
7.1 OpenGL线宽函数
用下面的OpenGL函数可设定线宽:
glLineWidth(width):
参数width赋以实数,该值舍入到最近的非负整数。如果输入值舍入到0.0,则线段用默认的标准宽度1.0显示。然而,在对线段进行反走样时,其边界进行光滑处理以减少阶梯现象,因而有可能出现小数宽度。有些线宽函数的实现仅支持有限的几种线宽,其他一些则不支持1.0以外的线宽。
7.2 OpenGL线型函数
默认状态下,直线段显示成实线。但也可以显示划线、点线或短划和点混合的线段。还可以改变短划及短划或点之间的长度。可以利用下面的OpenGL函数设定当前线型:
glLineStipple(repeatFactor,pattern)
参数pattern用来引入描述如何显示线段的一个16位整数。值为1的位对应一个“开”像素,值为0的位对应一个“关”像素。该模式从低位开始应用于线路径。默认模式为OxFFFF(每一位的值均为1),它生成实线。整数参数repeatFactor说明模式中每一位重复应用多少次才轮到下一位。默认的重复值是1。
作为指定一个线型的例子,假定参数pattern赋予了十六进制数0x00FF而重复因子为1。这将显示一条由8像素短划和8像素短划间隔的划线。同样,由于先应用低位值,线段从始端开始先显示一个8像素短划。接着是一个8像素间隔,然后再显示一个8像素短划,如此直到第二个端点。
在使用当前线型显示线段之前,必须先激活OpenGL的线型特性。下面的函数可实现这一点:
g1Enable(GL_LINE_STIPPLE):
7.3 其他OpenGL线效果
除了指定线宽、线型和实心颜色之外,还可以使用颜色渐变来显示线段。
g1ShadeMode1(GL_SMOOTH);
g1Begin (GL_LINES);
g1Color3f (0,0,0.0,1.0);
g1Vertex2i(50,50);
g1Color3f(1.0,0.0.0.0);
g1Vertex2i(250.250):
g1End():
通过将蓝色赋给线段的一个端点而将红色赋给另一端点来展示这一点。线段按两端点颜色的线性插值方式进行显示。
函数g1shadeMode1可以有另一个变量GL_FLAT。在这种情况下,线段用单一颜色即第二个点(250,250)的颜色来显示,即显示一条红色线段。实际上,GL_SMOOTH是默认值,因此,即使未使用该函数也会显示一条均匀颜色插值的线段。
8. 曲线属性
曲线属性的参数与线段相同,可以使用各种颜色、宽度、点划线模式和有效的画笔和笔刷选择来显示曲线。采用画曲线算法来实现属性选择,这一点类似于画直线。
严格地说,OpenGL并不把曲线作为和点及线段一样的图元来考虑。在OpenGL中可使用几种方法来显示曲线。最简单的方法可能是使用一组短线段逼近曲线,另外,曲线段可以用样条(spline)来画。这可以使用OpenGL的evaluator 函数来绘制,或者使用OpenGL实用函数(GLU)库中画样条的函数来绘制。
9. 填充区属性
多数图形软件包将填充区限定为多边形,因为它们用线性方程来描述。更进一步的限制是要求填充区是一个凸多边形,因此扫描线不会与两条以上的边相交。然而,我们一般可以填充任意指定的区域,包括圆、椭圆和其他有曲线边界的对象。而像绘画程序等应用系统则提供针对任意形状区域的填充功能。
9.1 填充模式
一般的图形软件包提供的基本填充属性是内部的显示模式。我们可以将一区域显示为单一颜色、指定填充图案或只给出边界的“空心”模式。
有些图形系统提供对覆盖掩模的初始位置的选择。从该初始位置开始,掩模在水平和垂直方向反复填充直到所有显示区域都填满了无重叠的掩模。在使用图案覆盖的填充区,矩阵掩模指出哪些像素应该使用特定颜色显示。这种用矩形图案填充一个区域的处理称为平铺(tiling),而矩形填充图有时称为平铺图案(tiling patem)。
9.2 颜色调和填充区域
也可以按照多种方式将填充图案和背景颜色混合。图案和背景色混合时使用透明因子来确定背景中有多少应该混合到对象颜色中。 某些使用调和颜色的填充方法称为软填充(soft-fill)或色彩填充(tint-fill)算法。这些填充方法的一种作用是,减弱在已经模糊的对象边界上的填充颜色,从而实现对边的反走样。
10. OpenGL填充区属性函数
OpenGL中仅提供对凸多边形的填充区子程序。显示一个填充凸多边形要经过下面四个步骤:
- 定义一个填充图案。
- 引用多边形填充子程序。
- 激活OpenGL多边形填充特性。
- 描述要填充的多边形。
多边形填充图案一直显示到包括多边形的边。因此,填充区中没有边界线,除非特别指定要显示边界线。
10.1 OpenGL填充图案函数
默认时,凸多边形使用当前颜色设定显示成一个实心颜色区域。为了用OpenGL的图案填充一个多边形,我们使用 32 × 32 32\times 32 32×32的位掩模。掩模中值为1表示对应像素设为当前颜色,值为0表示对应的帧缓存位置的值不变。填充图案使用OpenGL数据类型GLubyte以无符号字节进行描述,如同在g1Bitmap函数中一样。
一旦建立了一个掩模,可以使用下列函数将其用做当前填充图案:
g1PolygonStipple(fillPattern)
接下来,在指定要使用当前图案填充的多边形顶点之前必须激活填充子程序。这使用下列语句来实现:
g1Enable(GL POLYGON_STIPPLE)
类似地,使用下列语句关掉图案填充:
glDisab1e(GL_POLYGON_STIPPLE)
10.2 OpenGL纹理和插值图案
这将生成仿真木材、砖、拉丝钢(brushed steel)或某些其他材料外貌的图案。也可以仿照线图元中的做法得到多边形内部的插值颜色。为此,我们对多边形的顶点赋以不同颜色。插值填充用来为各种光照条件下的着色表面生成真实感显示。
作为插值填充的例子,下面的程序段将蓝色、红色和绿色分别赋给一个三角形的三个顶点。多边形填充就是在三个顶点间的颜色插值:
glShadeMode1(GL_SMOOTH);
g1Begin (GL_TRIANGLES);
g1Color3f (0.0.0.0.1.0);
g1Vertex2i(50.50);
g1Color3f(1.0,0.0,0.0);
g1Vertex2i(150,50);
g1Color3f (0.0,1.0.0.0);
g1Vertex2i (75,150);
g1End();
当然,如果为三角形整体设定一个单色,则用一种颜色来填充多边形。而如果将g1ShadeMode1函数中的变量改变为GL_FLAT,则多边形用最后指定的颜色(绿色)来填充。值GL_SMOOTH是着色的默认值,但包含这一描述可提醒我们多边形将用顶点插值法填充。
10.3 OpenGL线框图方法
我们也可以仅显示多边形的边,来生成线框图或多边形的空心显示。还可以通过显示一组顶点来显示多边形。这些选项通过下面的函数来选定
g1PolygonMode(face, displayMode)
参数face用来指定在多边形的哪一个面上仅显示边或顶点。它赋以GL_FRONT、GL_BACK或GL_FRONT_AND_BACK。
如果选择仅显示多边形的边,就将GL_LINE赋给参数display-Mode。如果仅绘出多边形顶点,则将GL_POINT赋给参数displaywode。第三个选项是GL_FILL。但这是默认的显示模式,所以我们通常仅在需要设定多边形边或顶点属性时引用g1PolygonMode。
显示多边形的选项是在填充内部的同时使用不同的颜色或图案来显示它的边或顶点。这可以通过指定该多边形两次来实现:先将displayMode设定为GL_FILL然后再设定为GL_LINE(或GL_POINVT)。
用绿色填充多边形内部,而用红色显示边
g1Color3f (0.0,1.0,0.0);
g1Color3f(1.0,0.0.0.0):
g1PolygonMode (GL_FRONT, GL_LINE);
显示填充多边形边的方式可能在边之间生成缝隙,这种称为**缝线(stiching)**的效果由扫描线填充算法和边的画线算法的计算差别造成。在对一个三维多边形进行填充时,深度值(离xy平面的距离)按每一(x,y)位置计算。但是在多边形一条边上的这个深度值通常与在同一(x,y)位置用画线算法计算所得的深度值不完全相同。因此在讲行可见性测试时,内部填充色可用来代替边的颜色以显示沿多边形边界的点。
消除三维多边形显示边缝隙的一个办法是移动由填充子程序计算的深度值,使他们与多边形的边深度值不重叠。
g1Enable(GL_POLYGON_OFFSET_FILL);
g1PolygonOffset (factor1. factor2);
第一个函数激活扫描线填充的位移子程序,而第二个函数用来设定一对计算深度位移总量的浮点值factor1和factor2。这一深度位移的计算是
d
e
p
t
h
O
f
f
s
e
t
=
f
a
c
t
o
r
1
×
m
a
x
S
l
o
p
e
+
f
a
c
t
o
r
2
×
c
o
n
s
t
depthOffset = factor1 \times maxSlope + factor2\times const
depthOffset=factor1×maxSlope+factor2×const
maxslope是多边形的最大斜率,const是实现常数。
另一种消除多边形边上缝线效果的方法是使用OpenGL的模板缓存来限制多边形内部填充,从而估它和边不重叠。但这种方法较为复杂且一般较慢,因而多数使用深度位移方法。
10.4 OpenGL前向面函数
尽管默认情况下由多边形顶点的次序来控制前向面和后向面的确认,我们还是可以使用下列函数单独地指定一个场景中的前向面和后向面:
g1FrontFace(vertexorder)
如果设定参数vertexOrder的值为OpenGL常量GL_CW,则随后定义的顺时针多边形可看做前向面。该OpenGL特性用来交换以顺时针次序指定顶点的多边形的面。常量GL_CCW标识多边形顶点的逆时针次序为前向面朝向,即默认次序。
11. 字符属性
显示的字符外观由字体、大小、颜色和方向这些属性控制。在许多软件包中,既可对整个字符串(文本)设置属性,也可对诸如绘制数值图等特殊应用中的单个字符设置属性。
字符串的方向按字符向上向量(character up vector) 设定。
12. OpenGL字符属性函数
使用OpenGL软件包显示字符有两种方法。使用核心库中的位图函数来设计字体集,或引用OpenCL.字符生成函数。GLUT库中包含显示预定义点阵和笔划字符集的函数。因此,可以设定的字符属性是那些能应用于位图或线段的属性。
对点阵或轮廓字体,显示颜色由当前颜色状态来确定。一般而言,字符的间隔和大小由子符描述确定,如 GLUT_BITMAP_9_BY_15
和``GLUT_STROKE_MONOROMAN`。但也可以为轮廓字体设定线宽和线型。我们用g1Linewidth函数指定宽度,用g1Linestipp1e函数选择线型。然后GLUT笔划字体用指定的当前线宽和线型属性值来显示。
13. OpenGL反走样函数
取样过程将物体上的坐标点数字化为离散的整数像素位置,因此光栅算法生成的图元显示具有锯齿形或阶梯状外观。这种由于低频取样(不充分取样)而造成的信息失真称为走样(aliasing)。可以使用校正不充分取样过程的反走样(antialiasing) 方法来改善所显示的光栅线的外观。
OpenGL提供三类图元支持反走样。使用下列函数可激活OpenGL的反走样子程序:
g1Enab1e(primitiveType)
其中参数 primitiveType
被赋以符号常量GL_POINT_SMOOTH
、GL_LINE_SMOOTH
或GL_POLYGON_SMOOTH
。假定我们用RGBA模式指定颜色,则同样需要激活OpenGL颜色调和操作:
glEnab1e(GL_BLEND)
14. OpenGL询问函数
使用OpenGL查询函数(query function)可以获得包括属性设定在内的任意状态参数的当前值。这些函数将指定状态值复制到一个数组中,以便存储起来在以后使用或检查当前的系统状态是否有错误。
要查询当前属性值,需要使用一个合适的“g1Get”函数:
g1GetBooleanv()
g1GetFloatv()
g1GetIntegerv()
g1GetDoublev()
在其中的每一个函数中,我们指定两个变量。第一个变量是标识一个属性或状态参数的OpenGL符号常量。第二个变量是一个指针,指向由函数名指出的数据类型的一个数组。
g1GetFloatv (GL_CURRENT_COLOR,colorValues):
当前颜色分量被传递给数组colorValues。要获取整数的当前颜色分量,必须引用g1GetIntegerv函数。有些情况下,必须在返回指定数据类型时进行类型转换。
可以将GL_POINT_SIZE
、GL_LINE_WIDTH
和GL_CURRENT_RASTER_POSITION
等其他一些OpenGL常量应用于这些函数来获取相应的当前状态值。常量GL_POINT_SIZE_RANGE
和GL_LINE_WIDTH_RANGE
可以用来支持对点的大小和线的宽度的检查。
15. OpenGL属性组
属性和其他状态参数按属性组(attribute group) 进行组织。每一组包括相关的状态参数集合。例如,点属性组(point-attribute group)包括了大小和点的平滑(反走样)参数,而线属性组(line-attribute group) 包括了宽度、模板状态、模板图案、模板重复计数及线段光滑状态等。类似地,多边形属性组(polygon-atribute group) 包括了11种多边形参数,如填充模式、前向面标志及多边形平滑状态。因为颜色是所有图元所共有的一个属性,所以它有单独的属性组。而有些参数被包含在多个组内。
保存一个指定属性组所有参数的工作由下列命令实现:
g1PushAttrib(attrGroup)
参数attrGroup
用标识一个属性组的OpenGL符号常量来赋值,如GL_POINT_BIT
、GL_LINE BIT
或GL_POLYGON_BIT
。为了保存颜色参数,使用符号常量GL_CURRENT_BIT
。我们可以用符号常量GLALL_ATTRIB_BITS
来存储所有属性组中的所有状态参数。g1pushattrib函数将指定组的所有参数放进属性栈(attribute stack)。
利用逻辑OR操作,可以组合符号常量,从而将参数存储在两个或更多的组中。下面的语句给出了属性栈上用于点、直线和多边形的参数:
g1PushAttrib(GL_POINT_BIT I GL_LINE_BIT I GL_POLYGON_BIT)
将一组状态参数存储起来后,我们可以用下列函数将属性栈的所有值进行重建:
g1PopAttrib()
在g1PopAttrib
函数中不使用任何变量,因为它使用栈中的所有值来设定OpenGL的当前状态。