1.实验七OpenGL光照效果(选做)1.实验七:OpenGL光照效果。
2.实验目的:通过上机编程,熟悉并掌握OpenGL中光照效果的制造方法。
3.实验要求:(1)先做实验项目:实验六“OpenGL组合图形”。
(2)每人一组,独立完成。
(3)利用OpenGL提供的颜色、光源、材质设置,对实验六“OpenGL组合图形”中自己设计的物体设置绘制颜色和材质参数,并在场景中添加光源,形成一定的光照明暗效果。
4.实验原理及内容:在现实世界中,光线和物体的材质共同决定了物体在人眼中的效果。
OpenGL 中则涉及到绘制颜色、物体的材质参数、场景中的光源颜色和位置,以此达到一定的真实感光照效果。
(1)颜色:OpenGL通过指定红、绿、蓝(RGB)三个成分的各自亮度来确定颜色,有时还有第四个成分alpha:glColor*(red,green,blue[,alpha]);glColor()函数设置当前的绘图颜色,red、green和blue分别为红、绿、蓝的亮度,alpha为透明度,取值均为0.0~1.0。
在该函数之后绘制的所有物体都将使用该颜色。
(2)光线:OpenGL的光照模型中将光源分成四种:发射光:一个物体本身就是一个发光源,如太阳、电灯等,这种光不受其它任何光源的影响。
环境光:从光源出发后光线被环境多次反射,以致没有明确的方向,或者说来自于所有的方向。
被环境光照射的物体,各个表面都均等受光。
散射光:来自于某个方向,被物体表面均匀地反射,例如荧光照明、窗口射入的阳光等。
镜面光:来自于一个方向,被物体强烈地反射到另一个特定的方向。
高亮度的镜面光往往能在被照射的物体表面产生亮斑,如金属球上的高光区。
对于散射光和镜面光,入射角度、距离和衰减因子还会影响到最终的光照效果。
除了物体本身的发射光以外,通常意义上的光并不会是单纯的环境光、散射光或镜面光,而是由这三种类型的光混合组成的。
在OpenGL中,光也是采用RGBA值来定义的,分别描述光线中红绿蓝各成分的相对亮度。
计算混合光的亮度时,则把相应的颜色亮度叠加即可,例如:环境光为(R1,G1,B1),散射光为(R2,G2,B2),镜面光为(R3,G3,B3),则混合后的光线为(R1+R2+R3,G1+G2+G3,B1+B2+B3)。
(3)材质:材质是物体本身的一种属性,主要用来表征物体对不同颜色、不同类型光线的反射、吸收性能。
在OpenGL中设置材质参数,就是要指定这种材质对环境光、散射光、镜面光的反射能力,有时还需要说明该种材质是否具有发光能力。
在最终绘制每个像素时,OpenGL自行将物体材质的各分量与光线的各分量相乘再叠加,从而得到每个像素的RGB值。
例如:光线为(R,G,B),材质为(MR,MG, MB),则最终绘制时颜色为(MR*R,MG*G,MB*B)。
(4)获得光照效果的一般过程为:a)使能光照:glEnable(GL_LIGHTING);b)设置一种光照模式:glLightModel*();如果只需要普通的无方向的环境光:GLfloat light_ambient[]={red,green,blue,alpha};//环境光的分值//全局环境光的默认取值为(0.2,0.2,0.2,1.0)glLightModel*(GL_LIGHT_MODEL_AMBIENT,light_ambient);如果需要在某个具体位置上放置某个光源,例如:GLfloat light_ambient[]={0.3,0.3,0.3,1.0};//环境光glLightfv(GL_LIGHT0,GL_AMBIENT,light_ambient);GLfloat light_diffuse[]={0.7,0.7,0.7,1.0};//散射光glLightfv(GL_LIGHT0,GL_DIFFUSE,light_diffuse);GLfloat light_specular[]={1.0,1.0,1.0,1.0};//镜面光glLightfv(GL_LIGHT0,GL_SPECULAR,light_specular);GLfloat light_position[]={0.0,0.0,0.0,1.0};//光的位置glLightfv(GL_LIGHT0,GL_POSITION,light_position);glEnable(GL_LIGHT0);//使能GL_LIGHT0光源OpenGL至少支持8种独立光源,用来指定这8个光源的常量为GL_LIGHT0~GL_LIGHT7。
利用glLight*()函数还可以指定聚光灯、衰减因子等参数。
c)设置材质属性:方法一:使用glMaterial*()设置材质,例如:GLfloat mat[]={0.75f,0.75f,0.75f,1.0f};//材质中的环境和散射glMaterialfv(GL_FRONT,GL_AMBIENT_AND_DIFFUSE,mat);GLfloat mat_shininess[]={50.0f};//材质的光亮度glMaterialfv(GL_FRONT,GL_SHININESS,mat_shininess);GLfloat mat_emission[]={0.75f,0.75f,0.75f,1.0f};//材质的发光glMaterialfv(GL_FRONT,GL_EMISSION,mat_emission);方法二:使用颜色跟踪法,即直接利用glColor*()设置的颜色来设置材质,这种方法使用起来更加方便。
例如:glEnable(GL_COLOR_MATERIAL);//使能颜色跟踪glColorMaterial(GL_FRONT,GL_AMBIENT_AND_DIFFUSE);glColor3f(0.75,0.75,0.75);d)绘制物体:对于有独立光源的场景,绘制的物体应事先计算好法线矢量。
对于直接使用glu和aux库函数绘制的图元,OpenGL将自动计算其法线;对于使用glBegin()和glEnd()逐点绘制的图元,则需要使用glNormal*()函数来指定法线。
一般来说,光源和材质的环境光和散射光成分相同,对物体的颜色有最重要的决定作用。
镜面光成分和材质属性趋向于浅灰色或白色,镜面光成分主要依赖于入射角度,物体上的亮斑往往是白色的。
5.实验软硬件环境:PC机,Windows2000,VC++6.实验步骤和方法:本实验重点在于熟悉OpenGL光照模型和光源的设置方法,对编程工具、语言、工程类型等没有严格要求。
下面是以Visual C++6.0作为开发环境,创建Win32应用程序工程为例进行的步骤说明,有兴趣的同学也可以使用更高版本的编程工具。
(1)启动Visual C++6.0;(2)新建一个“Win32Application”类型的Project,Project的名字应为“学号_7”,指定保存位置后单击“确定”按钮;(3)在工程向导第一步界面中选择“A simple Win32application.”,单击“Finish”按钮;(4)弹出工程信息对话框,确认信息无误后单击“确定”按钮,VC将自动创建好一个Win32应用程序框架;(5)参考“A01_OpenGL的程序框架”文件夹中的源代码,在自己的工程中添加相应的框架代码(参考程序中将OpenGL框架做成了一个类);注意:程序中要正确包含OpenGL的头文件和库文件,否则编译出错;添加代码时,注意头文件中要增加函数的声明。
(6)编译连接自己的OpenGL框架程序,运行结果应为一个空窗口;(7)将实验六“OpenGL组合图形”完成的组合物体的相应源代码拷贝到本实验的工程中;(8)添加上设置光源、材质的语句,要求场景中至少有两个光源;注意:先设置光源和材质,再绘制物体;绘制的物体要注意法线的计算问题,否则无法体现光源的光照效果;请参考“A03_OpenGL的组合图形”文件夹中的程序(参考程序中将光源的设置代码放置在bsipic::light0方法中,然后在OpenGL类的SetupPixelFormat方法中调用)。
(9)编译连接自己的程序,多尝试几种光照模型,寻找最佳效果,完成本次实验。
注意:代码调试成功后,可编译成一个release发布版本(选择菜单栏中“Compile”下的“Set Active Configuration…”菜单项,在出现的对话框中选中“release”,重新编译即可)。
7.实验预习要求:阅读OpenGL相关资料,了解颜色、光照、材质等方面的内容。
8.思考题:无9.评分标准:(1)能正确在自己设计的组合物体上打出光照阴影效果(80%);(2)实验报告编写认真详细,按时上交(20%)。
10.实验报告:要求提交1份实验报告、源程序代码(电子档)。
实验报告:“组别”:填写自己的学号;“测试记录”:填写自己程序的运行结果,绘制场景中光源和物体位置的示意图。
“小结”:填写自己的感想。
源代码:提交源程序时应提交整个工程,包括C/CPP文件、h文件、工程文件、res 文件夹等。
工程所在的文件夹中会包含有一个debug目录或release目录,只保留其中的exe文件,其它文件删除,然后将整个工程文件夹压缩打包后提交(包名中应含有学号)。