OpenGL glLightfv 函数的应用以及光源的相关知识
Posted ZHEXI_Coding free
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了OpenGL glLightfv 函数的应用以及光源的相关知识相关的知识,希望对你有一定的参考价值。
事实上光源才是所有光照效果的基础,没有光源一切都无从谈起。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))。参数数据格式要求为数组形式,即数学上的向量形式。
下面一段代码,我们将一个光源的性质进行完整设置:
- GLfloat Va[]=0.4,0.4,0.4,1; //光源环境光强度数组
- GLfloat Vd[]=0.6,0.6,0.6,1; //光源散射光强度数组
- GLfloat Vs[]=0.6,0.6,0.6,1; //光源镜面反射光强度数组
- GLfloat Vp[]=1,1,1,1; //光源位置数组
- glLightfv(GL_LIGHT0,GL_AMBIENT,Va); //设置0号光源的环境光属性
- glLightfv(GL_LIGHT0,GL_DIFFUSE,Vd); //设置0号光源的散射光属性
- glLightfv(GL_LIGHT0,GL_SPECULAR,Vs); //设置0号光源的镜面反射光属性
- 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)处的代码如下(其余位置不变):
- void __fastcall TForm1::OpenGL1GLPaint(TObject *Sender)
- glEnable(GL_DEPTH_TEST); //隐藏表面消除
- glClear(GL_DEPTH_BUFFER_BIT); //清除窗口颜色
- const GLfloat glfLightAmbient1[4] = 0.1, 0.1, 0.1, 1.0;
- const GLfloat glfLightAmbient2[4] = 0.4, 0.4, 0.4, 1.0;
- const GLfloat glfLightDiffuse1[4] = 0, 0.8, 0.8, 1.0;
- const GLfloat glfLightDiffuse2[4] = 0.8, 0.8, 0.8, 1.0;
- const GLfloat glfLightSpecular1[4] = 0, 0.8, 0.8, 1.0;
- const GLfloat glfLightSpecular2[4] = 0.8, 0.8, 0.8, 1.0;
- const GLfloat glPosition1[4]=0,0,1,0;
- const GLfloat glPosition2[4]=0.6,0.6,-0.6,1;
- glLightfv(GL_LIGHT0, GL_AMBIENT, glfLightAmbient1);
- glLightfv(GL_LIGHT0, GL_DIFFUSE, glfLightDiffuse1);
- glLightfv(GL_LIGHT0, GL_SPECULAR, glfLightSpecular1);
- glLightfv(GL_LIGHT0,GL_POSITION,glPosition1);
- glLightfv(GL_LIGHT1, GL_AMBIENT, glfLightAmbient2);
- glLightfv(GL_LIGHT1, GL_DIFFUSE, glfLightDiffuse2);
- glLightfv(GL_LIGHT1, GL_SPECULAR, glfLightSpecular2);
- glLightfv(GL_LIGHT1,GL_POSITION,glPosition2);
- glLightModeli(GL_LIGHT_MODEL_TWO_SIDE,GL_TRUE);//两面照亮
- glEnable(GL_LIGHTING);//启用光照
- glEnable(GL_LIGHT0);
- glEnable(GL_LIGHT1);//打开光源
- glEnable(GL_COLOR_MATERIAL);//启用颜色追踪
- glColorMaterial(GL_FRONT,GL_AMBIENT_AND_DIFFUSE);
- //物体正面的材料环境颜色和散射颜色,追踪glColor所设置的颜色(比较拗口,
事实上就是让OpenGL根据glColor所设置的颜色自动设置物体的反射强度)- glShadeModel(GL_FLAT);//设置颜色填充模式
- glBegin(GL_QUAD_STRIP) ;
- glVertex3f(i,-i,i);
- glVertex3f(i,-i,-i);
- glColor3f(1,0,0);
- glVertex3f(-i,-i,i);
- glVertex3f(-i,-i,-i);
- glColor3f(0,1,0);
- glVertex3f(-i,i,i);
- glVertex3f(-i,i,-i);
- glColor3f(0,0,1);
- glVertex3f(i,i,i);
- glVertex3f(i,i,-i);
- glColor3f(1,1,0);
- glVertex3f(i,-i,i);
- glVertex3f(i,-i,-i);
- glEnd();
- glBegin(GL_QUADS);
- glVertex3f(i,-i,i);
- glVertex3f(-i,-i,i);
- glVertex3f(-i,i,i);
- glColor3f(1,0,1);
- glVertex3f(i,i,i);
- glVertex3f(i,-i,-i);
- glVertex3f(-i,-i,-i);
- glVertex3f(-i,i,-i);
- glColor3f(0,1,1);
- glVertex3f(i,i,-i);
- glEnd();
- glDisable(GL_LIGHTING);//关闭光照
- glDisable(GL_LIGHT0);//关闭0号光源
- glDisable(GL_LIGHT1); //关闭1号光源
程序运行效果如图3-5和图3-6所示(旋转一下可以发现,图形的3D效果同第2章相比有了长足的进步。第2章中感觉像是几个放置在空间中的木板,现在的第一感觉就是空间中的正方体)。
效果图见路径 http://book.51cto.com/art/201104/255655.htm
以上是关于OpenGL glLightfv 函数的应用以及光源的相关知识的主要内容,如果未能解决你的问题,请参考以下文章
Opengl场景中加光照包含几个步骤,各个步骤实现用的函数是啥?
我啥时候需要提交我的应用以供 Facebook 审核(当只有少数人会使用它时)?
我应该如何配置我的应用以跨类保留 Firebase 用户数据?