第八、颜色与表面材质
OpenGL中使用RGBA色彩体系,RGB为红绿蓝三原色,A为α值,该值代表色彩融合时所占的比例。颜色是顶点的重要属性之一,没有色彩的世界是毫无生气的。
使用glColor*(R,G,B,A);设定当前颜色,此后定义所有的顶点都将是这个颜色的,直到再次改变当前颜色。该命令有两种常用形式glColor*f和glColor*ub,后者可以直接使用GetRValue(pixel)取得的颜色分量作为参数。下面左边的代码就可以生成右边漂亮的三角形:
glBegin(GL_TRIANGLES);
glColor3f(1.0,0.0,0.0);0);
glVertex3f(1.0,0.0,0.0);
glEnd();
可以看出,相邻顶点之间的部份也会有颜色,实际上OpenGL会在顶点之间进行插值分割,最终计算出对应光栅每一点的颜色,这个计算结果就是最终显示在屏幕上的图像。
也许上边的代码和文字暗示你给顶点指定的颜色就是屏幕图像上显示的颜色,其实最终的颜色取决于多个因素:顶点材质、法线方向、光照条件。不同颜色的光从不同角度照射在顶点上,顶点的颜色也会发生变化。上面的图是在白色光垂直照射条件下得到的(这也是默认设定)。
我们也可以不简单的指定顶点颜色,而是详细的说明该顶点产生的环境光、漫反射光、镜面反射光的颜色。OpenGL使用一种简易方法计算出面的图像:根据法向和光源位置的关系将以上几种光的颜色结合灯光对应成份颜色分别指定平面的各部份。从一个顶点产生的反射光不会再照射到其它顶点上,它对其它部份的影响直接在环境光中定义。要想取得更逼真的图像,可以使用光线追踪算法,该方法沿着每一条光线的轨迹,计算出它对所有顶点的影响,将所有光线的效果合并就是最终的图像,由于反射光的照明效果也是精确计算出来的,所以图像逼真。但是OpenGL并不直接支持该方法,需要自己编写计算例程,感兴趣的话去看看光线追踪的书好了。
用glMaterial*指定当前材质,第一个参数说明是给面的哪一侧指定材质(前或者后,详见法向部份说明),第二个参数指定要修改的分量,最后部份参数是相应的值。
GLfloat ambient[] ={0.8,0.8,0.8,1.0};//环境光
GLfloat diffuse[] ={0.8,0.0,0.8,1.0};//漫反射特性
GLfloat specular[] ={1.0,0.0,1.0,1.0};//镜面反射光色
GLfloat shininess[] ={50.0}; //镜面反射的光亮度
glMaterialfv(GL_FRONT,GL_AMBIENT,ambient);
glMaterialfv(GL_FRONT,GL_DIFFUSE,diffuse);
glMaterialfv(GL_FRONT,GL_SPECULAR,specular);
glMaterialfv(GL_FRONT,GL_SHININESS,shininess);
gluSphere(obj,0.1,10,10);//用10X10个面绘制半径0.1的球面
OpenGL还支持自动双面模式,这种模式下定义的每个面都将生成两个面,位置重合但法向相反,这可以简化对背面和物体内部的描述。该模式默认为关闭。
开/关命令是:void glLightModel* GL_LIGHT_MODEL_TWO_SIDE,0/1);
打开颜色材质可以简化材