4 为图元指定法向量 OpenGL必须通过图元的法线向量来确定图元的明暗程度。只有场景中的物体有了明暗的不同,场景才有立体感。 确定一个平面的法向量是一件相当简单的事情。在一个平面上,随意寻找两个互不平行的向量,它们的外积(叉积)就是这个平面的法线。 计算两向量的外积可以使用公式:
上述公式中,U、V为两不平行向量,S为U、V的外积(即U×V)。计算完外积之后,我们还需要将得到的向量转换为单位向量。只要将一个向量的x、y、z因子全部除以该向量的模就可以得到单位向量。因此,可以使用下面的代码计算一个三角形的法线向量。 请注意应该将三角形的顶点按逆时针顺序传给函数以获得正确结果。 通过计算得到法线向量之后,我们需要在绘制顶点之前调用glNormal函数为顶点或图元指定法线。例如: glBegin(GL_TRIANGLES); 除此之外,也可以为同一图元的不同顶点指定不同法线向量。例如: glBegin(GL_TRIANGLES); 5 材质 指定了图元的法线之后,我们还需要为其指定相应的材质以决定物体对各种颜色的光的反射程度,这将影响物体表现为何种颜色。和光源的成分相似,材质也分为漫射光反光率、平行光反光率。材质的漫射光成分将决定该材质对环境中的漫射光的反射程度,相似的,平行光成分将决定材质对平行光的反射程度。与设置光源相似,我们只需在绘制图元之前调用glMaterialf或glMaterialfv函数就能对即将绘制的图元的材质的各项参数进行设定。 5.1 设置材质对各种光的反光率 调用: glMaterialfv(GL_FRONT,GL_DIFFUSE,@Diffuse); 可以指定材质对漫射光的反射率。其中,第一个参数决定该材质运用于图元的正面还是反面。可以取GL_FRONT(正面),GL_BACK(反面),GL_FRONT_AND_BACK(正反两面)。第2个值表示对何种光进行设置,GL_DIFFUSE表示对漫射光反射率进行设置,可以取GL_AMBIENT(环境光)、GL_DIFFUSE(漫射光)、GL_AMBIENT_AND_DIFFUSE(环境光和漫射光)、GL_SPECULAR(平行/镜面光)。而第三个参数是一个四维数组,这个数组描述了反光率的RGBA值,每一项取值都为0-1之间。例如 Diffuse[4]={1,0,0,1}; glMaterialfv(GL_FRONT,GL_DIFFUSE,Diffuse); 将会使物体在有红色成分的光照下表现为红色。 5.2 使用颜色跟踪 在启用光照系统之后,为图元指定颜色变得不太方便。首先我们需要创建一个数组,然后调用glMaterial函数将数组传给材质,以此决定物体的颜色。为了简便,我们可以开启颜色跟踪来简化代码。调用 glEnable(GL_CORLOR_MATERIAL); 启动颜色跟踪,再调用 glColorMaterial(GL_FRONT,GL_AMBIENT_AND_DIFFUSE); 来决定对物体的正面还是反面,对环境光、镜面光还是漫射光进行颜色跟踪。第一个参数可以取GL_FRONT、GL_BACK、GL_FRONT_AND_BACK中的任意一种,第二个参数可以取GL_AMBIENT、GL_DIFFUSE、GL_AMBIENT_AND_DIFFUSE、GL_SPECULAR中的任意一种。 启动颜色跟踪之后,我们就可以像以前一样,使用glColor函数来指定图元的颜色了。这时,OpenGL将自动根据从glColor函数传递的颜色来决定物体材质,省去了我们手工指定材质的麻烦。 例如,要在启用光照系统的前提下绘制一个红色的三角形,可以这样做: glEnable(GL_COLOR_MATERIAL); 5.3 材质的镜面指数 当光源中含有镜面光成分,且镜面光较强时,一些光滑的物体便会出现一些高亮的焦点 我们可以通过设置材质的镜面指数来确定光斑的大小和聚焦程度。调用 glMateriali(GL_FRONT,GL_SHININESS,N ); 可以对镜面指数进行设定。如果N值越大,则光斑尺寸越小,物体越有光泽,反之越大。N值可取1-128之间的任意整数。 5.4 辐射性材质 有些物体,本身会发光。我们可以设置材质的Emission成分来使物体看起来有发光效果。只需添加如下代码: int LightEmission[4]={1,1,0,1} glMaterialfv(GL_FRONT,GL_EMISSION,LightEmission); 其中,LightEmission表示物体所发光的颜色的RGBA值。 |