hyde
路人甲
路人甲
  • 注册日期2003-09-24
  • 发帖数555
  • QQ
  • 铜币1457枚
  • 威望0点
  • 贡献值0点
  • 银元0个
阅读:1369回复:0

OpenGL系列讲座(13)

楼主#
更多 发布于:2004-03-20 10:43
7.4  材   质
 

7.4.1 材质颜色

 

OpenGL用材料对光的红、绿、蓝三原色的反射率来近似定义材料的颜色。象光源一样,

材料颜色也分成环境、漫反射和镜面反射成分,它们决定了材料对环境光、漫反射光和镜面

反射光的反射程度。在进行光照计算时,材料对环境光的反射率与每个进入光源的环境光结

合,对漫反射光的反射率与每个进入光源的漫反射光结合,对镜面光的反射率与每个进入光

源的镜面反射光结合。对环境光与漫反射光的反射程度决定了材料的颜色,并且它们很相似。

对镜面反射光的反射率通常是白色或灰色(即对镜面反射光中红、绿、蓝的反射率相同)。镜

面反射高光最亮的地方将变成具有光源镜面光强度的颜色。例如一个光亮的红色塑料球,球

的大部分表现为红色,光亮的高光将是白色的。

 

7.4.2 材质定义

 

    材质的定义与光源的定义类似。其函数为:

 

void glMaterial{if}[v](GLenum face,GLenum pname,TYPE param);

 

   定义光照计算中用到的当前材质。face可以是GL_FRONT、GL_BACK、GL_FRONT_AND_BACK,

它表明当前材质应该应用到物体的哪一个面上;pname说明一个特定的材质;param是材质的

具体数值,若函数为向量形式,则param是一组值的指针,反之为参数值本身。非向量形式

仅用于设置GL_SHINESS。pname参数值具体内容见表2-7-2。另外,参数

GL_AMBIENT_AND_DIFFUSE表示可以用相同的RGB值设置环境光颜色和漫反射光颜色。

 

______________________________________________________________________________

 

       参数名                  缺省值                说    明

______________________________________________________________________________

 

GL_AMBIENT                (0.2,0.2,0.2,1.0)       材料的环境光颜色

GL_DIFFUSE                (0.8,0.8,0.8,1.0)       材料的漫反射光颜色

GL_AMBIENT_AND_DIFFUSE                            材料的环境光和漫反射光颜色

GL_SPECULAR               (0.0,0.0,0.0,1.0)       材料的镜面反射光颜色

GL_SHINESS                 0.0                    镜面指数(光亮度)

GL_EMISSION               (0.0,0.0,0.0,1.0)       材料的辐射光颜色

GL_COLOR_INDEXES          (0,1,1)                 材料的环境光、漫反射光

                                                     和镜面光颜色

______________________________________________________________________________

 

                     表2-7-2  函数glMaterial*()参数pname的缺省值

 

 

    下面举出一个例子light1.c:

 

例 2-11  材质定义例程  light1.c

 

 

 #include "glos.h"

 

#include <GL/gl.h>

#include <GL/glaux.h>

 

void myinit(void);

void CALLBACK myReshape(GLsizei w, GLsizei h);

void CALLBACK display(void);

 

void myinit(void)

{

   /* 设置材质的各种光的颜色成分反射比率*/

    GLfloat mat_ambient[]={0.8,0.8,0.8,1.0};

    GLfloat mat_diffuse[]={0.8,0.0,0.8,1.0};    /* 紫色 */

    GLfloat mat_specular[] = { 1.0, 0.0, 1.0, 1.0 };  /* 亮紫色 */

    GLfloat mat_shininess[] = { 50.0 };

 

    GLfloat light_position[] = { 1.0, 1.0, 1.0, 0.0 };

 

    glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient);

    glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);

    glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);

    glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);

 

   glLightfv(GL_LIGHT0, GL_POSITION, light_position);

 

    glEnable(GL_LIGHTING);

    glEnable(GL_LIGHT0);

    glDepthFunc(GL_LESS);

    glEnable(GL_DEPTH_TEST);

}

 

void CALLBACK display(void)

{

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    auxSolidSphere(1.0);

    glFlush();

}

 

void CALLBACK myReshape(GLsizei w, GLsizei h)

{

    glViewport(0, 0, w, h);

    glMatrixMode(GL_PROJECTION);

    glLoadIdentity();

    if (w <= h)

    glOrtho (-1.5, 1.5, -1.5*(GLfloat)h/(GLfloat)w,

        1.5*(GLfloat)h/(GLfloat)w, -10.0, 10.0);

    else

    glOrtho (-1.5*(GLfloat)w/(GLfloat)h,

        1.5*(GLfloat)w/(GLfloat)h, -1.5, 1.5, -10.0, 10.0);

    glMatrixMode(GL_MODELVIEW);

    glLoadIdentity();

}

 

 

void main(void)

{

    auxInitDisplayMode (AUX_SINGLE | AUX_RGBA | AUX_DEPTH16);

    auxInitPosition (0, 0, 500, 500);

    auxInitWindow ("Lighting_1 ");

    myinit();

    auxReshapeFunc (myReshape);

    auxMainLoop(display);

}

 

以上程序运行结果是一个紫色的球。在函数myinit()中定义了球的材质颜色,光源的定

义仍延用light0.c 中的,而light.c物体的光源定义为缺省形式。从例子中明显地看出,物

体的材质颜色定义与光源颜色定义几乎一样,物体反射到眼中的颜色与二者都有关系,具体

关系请看下一小节。

 

7.4.3 材质RGB值和光源RGB值的关系

 

材质的颜色与光源的颜色有些不同。对于光源,R、G、B值等于R、G、B对其最大强度

的百分比。若光源颜色的R、G、B值都是1.0,则是最强的白光;若值变为0.5,颜色仍为白

色,但强度为原来的一半,于是表现为灰色;若R=G=1.0,B=0.0,则光源为黄色。对于

材质,R、G、B值为材质对光的R、G、B成分的反射率。比如,一种材质的R=1.0,G=0.5,

B=0.0,则材质反射全部的红色成分,一半的绿色成分,不反射蓝色成分。也就是说,若OpenGL

的光源颜色为(LR,LG,LB),材质颜色为(MR,MG,MB),那么,在忽略所有其他反射效果的情况

下,最终到达眼睛的光的颜色为(LR*MR,LG*MG,LB*MB)。

同样,如果有两束光,相应的值分别为(R1,G1,B1)和(R2,G2,B2),则OpenGL将各个颜色

成分相加,得到(R1+R2,G1+G2,B1+B2),若任一成分的和值大于1(超出了设备所能显示的亮

度)则约简到1.0。

   下面一例light2.c就说明了二者之间的关系。

 

例 2-12  材质与光源的RGB关系例程 light2.c

 

 #include "glos.h"

 

#include <GL/gl.h>

#include <GL/glaux.h>

 

void myinit(void);

void CALLBACK myReshape(GLsizei w, GLsizei h);

void CALLBACK display(void);

 

void myinit(void)

{

    GLfloat mat_ambient[]= { 0.8, 0.8, 0.8, 1.0 };

    GLfloat mat_diffuse[]= { 0.8, 0.0, 0.8, 1.0 };    /* 紫色 */

    GLfloat mat_specular[] = { 1.0, 0.0, 1.0, 1.0 };

    GLfloat mat_shininess[] = { 50.0 };

 

    GLfloat light_diffuse[]= { 0.0, 0.0, 1.0, 1.0};   /* 蓝色 */

    GLfloat light_position[] = { 1.0, 1.0, 1.0, 0.0 };

 

    glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient);

    glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);

    glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);

    glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);

 

    glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse);

    glLightfv(GL_LIGHT0, GL_POSITION, light_position);

 

    glEnable(GL_LIGHTING);

    glEnable(GL_LIGHT0);

    glDepthFunc(GL_LESS);

    glEnable(GL_DEPTH_TEST);

}

 

void CALLBACK display(void)

{

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    auxSolidSphere(1.0);

    glFlush();

}

 

void CALLBACK myReshape(GLsizei w, GLsizei h)

{

    glViewport(0, 0, w, h);

    glMatrixMode(GL_PROJECTION);

    glLoadIdentity();

    if (w <= h)

    glOrtho (-1.5, 1.5, -1.5*(GLfloat)h/(GLfloat)w,

        1.5*(GLfloat)h/(GLfloat)w, -10.0, 10.0);

    else

    glOrtho (-1.5*(GLfloat)w/(GLfloat)h,

        1.5*(GLfloat)w/(GLfloat)h, -1.5, 1.5, -10.0, 10.0);

    glMatrixMode(GL_MODELVIEW);

    glLoadIdentity();

}

 

void main(void)

{

    auxInitDisplayMode (AUX_SINGLE | AUX_RGBA | AUX_DEPTH16);

    auxInitPosition (0, 0, 500, 500);

    auxInitWindow ("Lighting_2 ");

    myinit();

    auxReshapeFunc (myReshape);

    auxMainLoop(display);

}

 

 

   以上程序运行结果是一个蓝色的球,其中高光部分仍为上一例的亮紫色。从上可看出,球

漫反射光的结果是mat_diffuse[]与light_diffuse[]中的三个颜色分量值相乘,即

(0.0*1.0,0.0*1.0,0.8*1.0,1.0*1.0)=(0.0,0.0,0.8,1.0),所以球大部分呈现蓝色。
喜欢0 评分0
夜落了,风静了,我喜欢一本书,一杯茶,一粒摇曳的烛光...
游客

返回顶部