3.2 光照篇(2)

http://book.51cto.com/art/201104/255655.htm

3.2   光照篇(2)

2.光源

事实上光源才是所有光照效果的基础,没有光源一切都无从谈起。OpenGL中我们可以设置8个光源,其编号分别为GL_LIGHT0、GL_LIGHT1、……、GL_LIGHT7。就相当于现实生活中有8个太阳,但每个太阳的位置、方向及它发出的光线可以完全不同。因此,OpenGL中我们设置光源时,主要就是设置其颜色、位置、方向等性质。另外,OpenGL中任何一个光源都可以发出不同强度的环境光、散射光、镜面反射光,这几个方面综合起来就决定了光源的颜色。

我们通过glLightfv(光源编号,光源特性,参数数据)来设置光源。其中,光源编号可取GL_LIGHT0、GL_LIGHT1、……、GL_LIGHT7共8个值。光源特性主要可取GL_AMBIENT(设置光源的环境光属性,默认值(0,0,0,1))、GL_DIFFUSE(设置光源的散射光属性,默认值(1,1,1,1))、GL_SPECULAR(设置光源的镜面反射光属性,默认值(1,1,1,1))、GL_POSITION(设置光源的位置,默认值(0,0,1,0))。参数数据格式要求为数组形式,即数学上的向量形式。

下面一段代码,我们将一个光源的性质进行完整设置:

  1. GLfloat Va[]={0.4,0.4,0.4,1};           //光源环境光强度数组  
  2. GLfloat Vd[]={0.6,0.6,0.6,1};           //光源散射光强度数组  
  3. GLfloat Vs[]={0.6,0.6,0.6,1};           //光源镜面反射光强度数组  
  4. GLfloat Vp[]={1,1,1,1};             //光源位置数组  
  5. glLightfv(GL_LIGHT0,GL_AMBIENT,Va); //设置0号光源的环境光属性  
  6. glLightfv(GL_LIGHT0,GL_DIFFUSE,Vd); //设置0号光源的散射光属性  
  7. glLightfv(GL_LIGHT0,GL_SPECULAR,Vs);    //设置0号光源的镜面反射光属性  
  8. glLightfv(GL_LIGHT0,GL_POSITION,Vp);    //设置0号光源的位置属性  

光源的性质设置完毕,还要调用glEnable(GL_LIGHT0)来打开光源。就相当于你买回手电筒、装好电池(设置光源),但如果不打开开关(打开电源),手电筒是不起作用的。

另外,对于GL_POSITION,其位置数组(x,y,z,w)定义了光源在空间中的位置。但三维空间为什么需要4个量呢?事实上这里采用的是齐次坐标,当w≠0时,它表示光源处于空间中(x,y,z)处,这时的光源称为定点光源;当w=0时,根据齐次坐标的性质,它表示光源位于无穷远处,此时光源称为定向光源,其所有光线几乎是相互平等的,如太阳。其光线方向由点(x,y,z)指向(0,0,0)。

将第2章中的正方体的例子做以下修改。修改后的void __fastcall TForm1::OpenGL1 GLPaint(TObject *Sender)处的代码如下(其余位置不变):

  1. void __fastcall TForm1::OpenGL1GLPaint(TObject *Sender)  
  2. {  
  3.   glEnable(GL_DEPTH_TEST);          //隐藏表面消除  
  4.   glClear(GL_DEPTH_BUFFER_BIT); //清除窗口颜色  
  5.  
  6.   const GLfloat glfLightAmbient1[4] = {0.1, 0.1, 0.1, 1.0};  
  7.   const GLfloat glfLightAmbient2[4] = {0.4, 0.4, 0.4, 1.0};  
  8.   const GLfloat glfLightDiffuse1[4] = {0, 0.8, 0.8, 1.0};  
  9.   const GLfloat glfLightDiffuse2[4] = {0.8, 0.8, 0.8, 1.0};  
  10.   const GLfloat glfLightSpecular1[4] = {0, 0.8, 0.8, 1.0};  
  11.   const GLfloat glfLightSpecular2[4] = {0.8, 0.8, 0.8, 1.0};  
  12.   const GLfloat glPosition1[4]={0,0,1,0};  
  13.   const GLfloat glPosition2[4]={0.6,0.6,-0.6,1};  
  14.   glLightfv(GL_LIGHT0, GL_AMBIENT,  glfLightAmbient1);  
  15.   glLightfv(GL_LIGHT0, GL_DIFFUSE,  glfLightDiffuse1);  
  16.   glLightfv(GL_LIGHT0, GL_SPECULAR, glfLightSpecular1);  
  17.   glLightfv(GL_LIGHT0,GL_POSITION,glPosition1);  
  18.   glLightfv(GL_LIGHT1, GL_AMBIENT,  glfLightAmbient2);  
  19.   glLightfv(GL_LIGHT1, GL_DIFFUSE,  glfLightDiffuse2);  
  20.   glLightfv(GL_LIGHT1, GL_SPECULAR, glfLightSpecular2);  
  21.   glLightfv(GL_LIGHT1,GL_POSITION,glPosition2);  
  22.   glLightModeli(GL_LIGHT_MODEL_TWO_SIDE,GL_TRUE);//两面照亮  
  23.       glEnable(GL_LIGHTING);//启用光照  
  24.       glEnable(GL_LIGHT0);  
  25.       glEnable(GL_LIGHT1);//打开光源  
  26.       glEnable(GL_COLOR_MATERIAL);//启用颜色追踪  
  27.       glColorMaterial(GL_FRONT,GL_AMBIENT_AND_DIFFUSE);  
  28. //物体正面的材料环境颜色和散射颜色,追踪glColor所设置的颜色(比较拗口,
    事实上就是让OpenGL根据glColor所设置的颜色自动设置物体的反射强度)  
  29.  
  30.   glShadeModel(GL_FLAT);//设置颜色填充模式  
  31.    glBegin(GL_QUAD_STRIP) ;  
  32.      glVertex3f(i,-i,i);  
  33.      glVertex3f(i,-i,-i);  
  34.      glColor3f(1,0,0);  
  35.      glVertex3f(-i,-i,i);  
  36.      glVertex3f(-i,-i,-i);  
  37.      glColor3f(0,1,0);  
  38.      glVertex3f(-i,i,i);  
  39.      glVertex3f(-i,i,-i);  
  40.      glColor3f(0,0,1);  
  41.      glVertex3f(i,i,i);  
  42.      glVertex3f(i,i,-i);  
  43.      glColor3f(1,1,0);  
  44.      glVertex3f(i,-i,i);  
  45.      glVertex3f(i,-i,-i);  
  46.    glEnd();  
  47.    glBegin(GL_QUADS);  
  48.      glVertex3f(i,-i,i);  
  49.      glVertex3f(-i,-i,i);  
  50.      glVertex3f(-i,i,i);  
  51.      glColor3f(1,0,1);  
  52.      glVertex3f(i,i,i);  
  53.  
  54.      glVertex3f(i,-i,-i);  
  55.      glVertex3f(-i,-i,-i);  
  56.      glVertex3f(-i,i,-i);  
  57.      glColor3f(0,1,1);  
  58.      glVertex3f(i,i,-i);  
  59.    glEnd();  
  60.  
  61.       glDisable(GL_LIGHTING);//关闭光照  
  62.       glDisable(GL_LIGHT0);//关闭0号光源  
  63.       glDisable(GL_LIGHT1); //关闭1号光源  
  64. }  

程序运行效果如图3-5和图3-6所示(旋转一下可以发现,图形的3D效果同第2章相比有了长足的进步。第2章中感觉像是几个放置在空间中的木板,现在的第一感觉就是空间中的正方体)。

 
图3-5  原始效果图
 
图3-6  增加光照后的效果图
【责任编辑:云霞 TEL:(010)68476606】
原文地址:https://www.cnblogs.com/xuejinhui/p/4387904.html