14.2 OpenGL纹理和插值图案
填充多边形的另一种方法是使用纹理。这将生成仿真木材、砖、纹钢(brushed ateel )或某些其他材料外貌的图案。也可以如线图元中的那样得到多边形内部的插值颜色。为此,我们对多边形的顶点赋以不同颜色。插值填充用来为各种光照条件下的着色表面生成真实感显示。
作为插值填充的例子,下面的程序段将蓝色、红色和绿色分别赋给一个三角形的三个顶点。多边形填充就是在三个顶点间的颜色插值。
14.3 OpenGL线框图方法
我们也可以仅显示多边形的边,这生成线框图或多边形的空心显示。也可以通过显示一组顶点来显示多边形。这些选项通过下面的函数来选定:
另一个显示多边形的选项是在填充内部的同时用不同的颜色或图案来显示它的边或顶点。这通过指定该多边形两次来实现:先将displayMode设定为GL_FILL然后再设定为GL_LINE(或GL_POINT )。例如,下面的程序段用绿色填充多边形内部,而用红色显示边。
消除三维多边形显示边的缝隙的一个办法是移动由填充子程序计算的深度值,使它们与多边形的边深度值不重叠。下列两个函数用来实现这一点。
这里, maxSlope是多边形的 最大斜率, const是 实现常数。对于xy平面上的一个多边形来说,斜率为0。否则,最大斜率用多边形深度的变化除以x或y的变化而得。两因子的典型值是0.75和1.0,尽管某些经验因子值对生成好的结果是必要的。作为对位移因子赋值的例子,我们可以把前一程序段修改如下:
另一种消除多边形边上缝线效果的方法是使用OpenGL的模板缓存来限制多边形内部填充,从而使它和边不重叠。但这种方法较为复杂且一般较慢,因而多数使用深度位移方法。
为了使用OpenGL函数显示一个凹多边形,必须先将它分割为一组凸多边形。凹多边形一般用3.15节()讨论的方法分割为一组三角形。然后通过填充这些三角形来显示填充的凹多边形。类似地,如果只要显示多边形顶点,我们可以只绘制三角形顶点。但为了显示原凹多边形的线框图,就不能将显示模式设定为GL_LINE,因为这将把作为多边形内部的所有三角形的边显示出来(参见图4.33 )。
幸好,OpenGL提供了从线框图显示中消除选定边的机制。每一个多边形顶点与一个指示该顶点是否通过边界上的边与下一顶点连接的一位标志一起存储。我们要做的就是将该位标志设为“关”,从而使在这个顶点之后的边不被显示。使用下列函数可以设定一条边的这个标志。
14.4 OpenGL前向面函数
尽管默认情况下由多边形顶点的次序来控制前向面和后向面的确认,我们还是可以使用下列函数单独地指定一场景中的前向面和后向面:
填充多边形的另一种方法是使用纹理。这将生成仿真木材、砖、纹钢(brushed ateel )或某些其他材料外貌的图案。也可以如线图元中的那样得到多边形内部的插值颜色。为此,我们对多边形的顶点赋以不同颜色。插值填充用来为各种光照条件下的着色表面生成真实感显示。
作为插值填充的例子,下面的程序段将蓝色、红色和绿色分别赋给一个三角形的三个顶点。多边形填充就是在三个顶点间的颜色插值。
glShadeModel (CL_SMOOTH);
glBegin (GL_TRIANGLES);
glColor3f (0.0, 0.0, 1.0);
glVertex2i (50, 50);
glColor3f (1.0, 0.0, 0.0);
glVertex2i (150, 50);
glColor3f (0.0, 1.0, 0.0);
glVertex2i (75, 150);
glEnd ( );
当然,如果为三角形整体设定一个单色,则用一种颜色来填充多边形。而如果将
glShadeModel函数中的变量改变为
GL_FLAT,则多边形用最后指定的颜色(绿色)来填充。值
GL_SMOOTH是着色的默认值,但包含这一描述可提醒我们多边形将用顶点插值法填充。
14.3 OpenGL线框图方法
我们也可以仅显示多边形的边,这生成线框图或多边形的空心显示。也可以通过显示一组顶点来显示多边形。这些选项通过下面的函数来选定:
glPolygonMode (face, displayMode);
参数
face用来指定在多边形的哪一个面上仅显示边或顶点。它赋以GL_FRONT, GL_BACK或GL_FRONT_AND_BACK。 然后,如果迭择仅显示多边形的边,就给参数
displayMode赋值GL_LINE。如果仅绘出多边形顶点,则将GL_POINT赋给参数dispiayMode。第三个选项是GL_FILL。但这是默认的显示模式,所以我们通常仅在要设定多边形边或顶点属性时引用glPolygonModeo
另一个显示多边形的选项是在填充内部的同时用不同的颜色或图案来显示它的边或顶点。这通过指定该多边形两次来实现:先将displayMode设定为GL_FILL然后再设定为GL_LINE(或GL_POINT )。例如,下面的程序段用绿色填充多边形内部,而用红色显示边。
glColor3f (0.0, 1.0, 0.0);
\* Invoke polygon-generating routine.*\
glColor3f (1.0, 0.0, 0.0);
glPolygonMode (GL_REONT, GL_LINE);
\* Invoke polygon-generating routine again.*\
对于一个三维多边形(即并不是所有顶点都在xy平面内)来说,这种显示填充多边形边的方法可能在边之间的生成缝隙。这种称为
缝线(stitching)的效果由扫描线填充算法和边的画线算法的计算差别造成。在对一个三维多边形进行填充时,深度值(离xy平面的距离)按每一(x,y)位置计算。但是在多边形一条边上的这个深度值通常与在同一(x, y)力位置用画线算法计算所得的深度值不完全相同。因此,在进行可见性测试时,内部填充色可用来代替边的颜色以显示沿多边形边界的点。
消除三维多边形显示边的缝隙的一个办法是移动由填充子程序计算的深度值,使它们与多边形的边深度值不重叠。下列两个函数用来实现这一点。
glEnable (GL_POLYGON_OFFSET_FILL);
glPolygonOffest (factor1, fatcor2);
第一个函数激活扫描线填充的位移子程序,而第二个函数用来设定一对计算深度位移总量的浮点值factorl和factor2。这一深度位移的计算是
这里, maxSlope是多边形的 最大斜率, const是 实现常数。对于xy平面上的一个多边形来说,斜率为0。否则,最大斜率用多边形深度的变化除以x或y的变化而得。两因子的典型值是0.75和1.0,尽管某些经验因子值对生成好的结果是必要的。作为对位移因子赋值的例子,我们可以把前一程序段修改如下:
glColor3f (0.0, 1.0, 0.0);
glEnable (GL_POLEGON_OFFSET_FILL);
glPolygonOffset (1.0, 1.0);
/* Invoke polygon-generating routine. */
glDisable (GL_POLYGON_OFFSET_FILL);
glColor3f (1.0, 0.0, 0.0);
glPolygonMode (GL_FRONT, GL_LINE);
/* Invoke polygon-generating routine again. */
现在将多边形的内部填充往更深处加强了一些,因此它不妨碍其边的深度值。也有可能通过把位应用于画线算法,即通过将glEnable函数的变量改变为GL_POLYGON_OFFSET_LINE来实现该方法。此时,我们要使用负因子使边的深度值靠近些。如果仅需要显示多边形顶点位置的不同颜色点而不是醒目的边,那么glEnable函数的变量将是GL_POLYGON_OFFSET_POINT。
另一种消除多边形边上缝线效果的方法是使用OpenGL的模板缓存来限制多边形内部填充,从而使它和边不重叠。但这种方法较为复杂且一般较慢,因而多数使用深度位移方法。
为了使用OpenGL函数显示一个凹多边形,必须先将它分割为一组凸多边形。凹多边形一般用3.15节()讨论的方法分割为一组三角形。然后通过填充这些三角形来显示填充的凹多边形。类似地,如果只要显示多边形顶点,我们可以只绘制三角形顶点。但为了显示原凹多边形的线框图,就不能将显示模式设定为GL_LINE,因为这将把作为多边形内部的所有三角形的边显示出来(参见图4.33 )。
幸好,OpenGL提供了从线框图显示中消除选定边的机制。每一个多边形顶点与一个指示该顶点是否通过边界上的边与下一顶点连接的一位标志一起存储。我们要做的就是将该位标志设为“关”,从而使在这个顶点之后的边不被显示。使用下列函数可以设定一条边的这个标志。
glEdgeFlag(flag);
要指明一个顶点不在边界的边的前面,需要将OpenGL常量GL_FALSE赋给参数flag。这作用于所有其后的顶点直至再次调用glEdgeFlag。 OpenGL常量GL_TRUE再次将标志置回工作状态,即默认状态。函数glEdgeFlag可放在glBegin/glEnd之间。作为边标志应用的一个展示,下列程序段仅显示所定义三角形的两条边(参见图4.34 )。
glPolygonMode (GL_FRONT_AND_BACK, GL_LINE);
glBegin (GL_POLYGON);
glVertex3fv (v1);
glEdgeFlag (GL_FALSE);
glVertex3fv (v2);
glEdgeFlag (GL_TRUE);
glVertex3fv (v3);
glEnd ( );
多边形标志也可以在一个数组中指定,该数组可与顶点数组混合或作为其附加数组(
顶点数组和
OpenGL颜色函数)。创建一个边标志数组的语句为
glEnableClientState (GL_EDGE_FLAG_ARRAY);
glEdgeFlagPointer (offset, edgeFlagArray);
参数offset 指出数组edgeFlagArray中边标志值之间字节数。参数offset的默认值是0。
14.4 OpenGL前向面函数
尽管默认情况下由多边形顶点的次序来控制前向面和后向面的确认,我们还是可以使用下列函数单独地指定一场景中的前向面和后向面:
glFrontFace(vertexOrder);
如果设定参数vertexOrder的值为OpenGL常量GL_CW,则随后定义的顺时针多边形可看做前向面。该OpenGL特性用来交换以顺时针次序指定顶点的多边形的面。常量GL_CCW标志多边形顶点的逆时针次序为前向面朝向,即默认次序。