OpenGL开发 颜色、材料和光照:基础知识

设置颜色模式:

glShadeModel();

GL_SMOOT  //  平滑着色,图元的内部颜色是每个顶点颜色的平滑过渡。

GL_FLAT  //  单调着色,图元的内部颜色就是最后一个顶点所指定的颜色。唯一例外的是GL_POLYGON图元,它的内部颜色是第一个定点的颜色。

在OpenGL光照模型中,除非一个物体自己会发光,否则它将受到3种不同类型的光的照射:环境光(ambient)、散射光(diffuse)和镜面光(specular)。

环境光(ambient):

环境光并不来自任何特定的方向。它来自某个光源,但光线却是在房间或场景中四处反射,没有方向可言。由环境光所照射的物体在所有方向的表面都是均匀照亮的。

散射光(diffuse):

散射光具有方向性,来自于一个特定的方向,它根据入射光线的角度在表面上均匀地反射开来。

镜面光(specular):

镜面光具有很强的方向性,但它的反射角度很锐利,只沿一个特定的方向反射。

打开关照:

glEnable(GL_LIGHTING);

这个调用告诉OpenGL在确定场景中的每个顶点的颜色时使用材料属性和光照参数。但是,如果没有指定任何的材料属性或光照参数,物体将会保持为黑暗的无光照状态。

设置光照模式:

glLightModel

glLightModelfv();

启动光源:

GLfloat ambientLight[ ] = { 0.3f, 0.3f , 0.3f, 1.0f};

GLfloat diffuseLight[ ] = { 0.7f, 0.7f, 0.7f, 1.0f};

//设置并启用光照0

glLightfv(GL_LIGHT0 , GL_AMBIENT, ambientLight);

glLightfv(GL_LIGHT0 , GL_DIFFUSE, diffuseLight);

启动光源0:

glEnable(GL_LIGHT0);

光的位置:

GLfloat lightPos [ ] = { -50.0f, 50.0f, 100.0f, 1.0f};

glLightfv(GL_LIGHT0,GL_POSITION, lightPos);

在此,lightPos数组包含了光的位置。这个数组的最后一个值是1.0,表示指定的坐标是光源的位置。如果这个数组的最后一个值是0.0,则表示光是从无限远处沿这个数组所指定的向量照射过来的。

把一个位置光源变成一个聚光灯:

glLightf(GL_LIGHT0, GL_SPOT_CUTOFF, 60.0f);

设置材料属性:

glMaterial();

glMaterialfv();

函数的第一个参数指定了材料属性是作用于正面、背面还是双面(GL_FRONT、GL_BACK或GL_FRONT_AND_BACK)。第二个参数指定将要设置哪个属性。最后一个参数是一个数组,它包含了构成这些属性的RGBA值。

第二种方法是我们所推荐的设置材料属性的方法,称为颜色追踪。使用颜色追踪,可以告诉OpenGL仅仅通过调用glColor来设置材料属性。为了启用颜色追踪,需要以GL_COLOR_MATERIAL为参数调用glEnable。

glEnable(GL_COLOR_MATERIAL);

接着,glColorMaterial函数根据glColor所设置的值来指定材料参数。

glColorMaterial(GL_FRONT,GL_AMBIENT_AND_DIFFUSE);

指定法线向量:

glNormal3f();

启动法线规范化:

glEnable(GL_MORMALIZE);

glEnable(GL_RESCALE_NORMALS);

建议使用第二种,第一种会在效率上有所牺牲。第二种调用告诉OpenGL,法线不是单位长度,但他们可以通过相同数量的缩放实现单位长度。

打开混合:

glEnable(GL_BLEND);

glBlendFunc(GLenum S, GLenum D);

对点、直线和多边形进行抗锯齿处理:

glEnable(GL_POINT_SMOOTH);

glEnable(GL_LINE_SMOOTH);

glEnable(GL_POLYGON_SMOOTH); //需要其他的规则,这个并不常用

打开或关闭多重采样:

glutInitDisplayMode(GL_MULTISAMPLE);

glEnable(GL_MULTISAMPLE);

关闭多重采样:

glDisable(GL_MULTISAMPLE);

使用多重采样后,点、直线和多边形的平滑特性都将被忽略。

应用雾:

打开或关闭雾:

glEnable/glDisable(GL_FOG);

设置雾参数:

GLfloat fogColor [ ] = {0.0f,1.0f,0.0f,1.0f};

glFogfv(GL_FOG_COLOR, fogColor);  //设置雾颜色

glFogf(GL_FOG_START, 5.0f);  //雾从多远开始

glFogf(GL_FOG_END, 30.0f);  //雾到多元结束

glFogf(GL_FOG_DENSITY, 0.5f);  //雾稠密度

glFogi(GL_FOG_MODE, GL_LINEAR);  //使用哪种雾模式

注意,GL_FOG_START和GL_FOG_END只对GL_LINEAR雾有效。稠密度值对于线性雾并无效果。

显式地请求片段雾:

glHint(GL_FOG_HINT,GL_NICEST);

为了实现更快、精确度稍低的雾,可以调用:

glHint(GL_FOG_HINT,GL_FASTEST);

雾坐标:

我们可以自己完成计算雾距离,可以用glFogCoordf(GLfloat fFogDistance)函数来设置,除非使用下面这个函数更改了雾坐标的来源,否则雾坐标是被忽略的:

glFogi(GL_FOG_COORD_SRC,GL_FOG_COORD);   //  使用glFogCoordf

为了打开OpenGL产生的雾值,要把最后一个参数改为GL_FRAGMENT_DEPTH:

glFogi(GL_FOG_COORD_SRC,GL_FRAGMENT_DEPTH);

累积缓冲区:

void glAccum(GLenum op, GLfloat value);

第一个参数指定了希望使用哪种累积操作,第二个参数是个浮点值,用于对操作进行缩放。

下面是OpenGL支持的累积操作:

GL_ACCUM 根据参数值对颜色缓冲区的值进行缩放,并把它们添加到累积缓冲区的当前内容中;

GL_LOAD 根据参数值对颜色缓冲区的值进行缩放,并用它们替换累积缓冲区的当前内容;

GL_RETURN 根据累积缓冲区的值对颜色值进行缩放,然后把结果复制到颜色缓冲区;

GL_MULT 根据累积缓冲区的值对颜色值进行缩放,然后把结果存储到累积缓冲区;

GL_ADD 根据累积缓冲区的值对颜色值进行缩放,然后把结果添加到累积缓冲区的当前内容上;

最后,当我们设置OpenGL渲染环境时,必须记住要请求一个累积缓冲区。GLUT还通过glutInitDisplayMode函数传递GLUT_ACCUM标志来提供对累积缓冲区的支持:

glutInitDisplayMode(GLUT_ACCUM);

其他颜色操作:

颜色掩码:

void glColorMask(GLboolean red,GLboolean green GLboolean blue,GLboolean alpha);

如果对其中的一个通道所传递的标志是GL_TRUE,表示可以对这个通道进行写入。如果传递的是GL_FALSE,表示无法写入到这个通道。

alpha测试:

alpha测试值和比较函数是通过glAlphaFunc函数指定的:

void glAlphaFunc(GLenum func,GLclampf ref);

可以用glEnable/glDisable(GL-ALPHA_TEST)来打开或关闭alpha测试。

抖动:

可以通过glEnable/glDisable(GL_DITHER);来打开或关闭抖动。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wwzpjx.html