下面我们来创建几种材质,全部的定义放在materials.h文件中。
/
// File: Materials.h
// Author: LotusOne
// Date: 03/10/2003
// Usage: Define some materials
/
float Materials[][13]=
{
//黄铜
0.329412, 0.223529, 0.027451, 1.000000,
0.780392, 0.568627, 0.113725, 1.000000,
0.992157, 0.941176, 0.807843, 1.000000,
27.897400,
//青铜
0.212500, 0.127500, 0.054000, 1.000000,
0.714000, 0.428400, 0.181440, 1.000000,
0.393548, 0.271906, 0.166721, 1.000000,
25.600000,
//亮青铜
0.250000, 0.148000, 0.064750, 1.000000,
0.400000, 0.236800, 0.103600, 1.000000,
0.774597, 0.458561, 0.200621, 1.000000,
76.800003,
//铬
0.250000, 0.250000, 0.250000, 1.000000,
0.400000, 0.400000, 0.400000, 1.000000,
0.774597, 0.774597, 0.774597, 1.000000,
76.800003,
//铜
0.191250, 0.073500, 0.022500, 1.000000,
0.703800, 0.270480, 0.082800, 1.000000,
0.256777, 0.137622, 0.086014, 1.000000,
12.800000,
//亮铜
0.229500, 0.088250, 0.027500, 1.000000,
0.550800, 0.211800, 0.066000, 1.000000,
0.580594, 0.223257, 0.069570, 1.000000,
51.200001,
//金
0.247250, 0.199500, 0.074500, 1.000000,
0.751640, 0.606480, 0.226480, 1.000000,
0.628281, 0.555802, 0.366065, 1.000000,
51.200001,
//亮金
0.247250, 0.224500, 0.064500, 1.000000,
0.346150, 0.314300, 0.090300, 1.000000,
0.797357, 0.723991, 0.208006, 1.000000,
83.199997,
//白蜡
0.105882, 0.058824, 0.113725, 1.000000,
0.427451, 0.470588, 0.541176, 1.000000,
0.333333, 0.333333, 0.521569, 1.000000,
9.846150,
//银
0.192250, 0.192250, 0.192250, 1.000000,
0.507540, 0.507540, 0.507540, 1.000000,
0.508273, 0.508273, 0.508273, 1.000000,
51.200001,
//亮银色
0.231250, 0.231250, 0.231250, 1.000000,
0.277500, 0.277500, 0.277500, 1.000000,
0.773911, 0.773911, 0.773911, 1.000000,
89.599998,
//翡翠、祖母绿
0.021500, 0.174500, 0.021500, 0.550000,
0.075680, 0.614240, 0.075680, 0.550000,
0.633000, 0.727811, 0.633000, 0.550000,
76.800003,
//碧玉
0.135000, 0.222500, 0.157500, 0.950000,
0.540000, 0.890000, 0.630000, 0.950000,
0.316228, 0.316228, 0.316228, 0.950000,
12.800000,
//黑曜石
0.053750, 0.050000, 0.066250, 0.820000,
0.182750, 0.170000, 0.225250, 0.820000,
0.332741, 0.328634, 0.346435, 0.820000,
38.400002,
//珍珠
0.250000, 0.207250, 0.207250, 0.922000,
1.000000, 0.829000, 0.829000, 0.922000,
0.296648, 0.296648, 0.296648, 0.922000,
11.264000,
//红宝石
0.174500, 0.011750, 0.011750, 0.550000,
0.614240, 0.041360, 0.041360, 0.550000,
0.727811, 0.626959, 0.626959, 0.550000,
76.800003,
//绿宝石、绿松石
0.100000, 0.187250, 0.174500, 0.800000,
0.396000, 0.741510, 0.691020, 0.800000,
0.297254, 0.308290, 0.306678, 0.800000,
12.800000,
//黑塑料
0.000000, 0.000000, 0.000000, 1.000000,
0.010000, 0.010000, 0.010000, 1.000000,
0.500000, 0.500000, 0.500000, 1.000000,
32.000000,
//黑橡胶
0.020000, 0.020000, 0.020000, 1.000000,
0.010000, 0.010000, 0.010000, 1.000000,
0.400000, 0.400000, 0.400000, 1.000000,
10.000000,
//紫罗兰
0.110000, 0.060000, 0.090000, 1.000000,
0.430000, 0.470000, 0.540000, 1.000000,
0.330000, 0.330000, 0.520000, 1.000000,
22.000000
};
glInit()仍然是启用光照,只是对场景背景作了些微调。
#include “materials.h”
……
int glInit()
{
// 启用纹理映射
glEnable(GL_TEXTURE_2D);
//启用阴影平滑(Smooth Shading)。
glShadeModel(GL_SMOOTH);
//调整场景背景颜色
glClearColor(0.2f,0.2f,0.2f,0.0f);
//设置深度缓冲
glClearDepth(1.0f);
//启动深度测试
glEnable(GL_DEPTH_TEST);
//深度测试的类型
glDepthFunc(GL_LEQUAL);
//进行透视修正
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
glLightfv(GL_LIGHT0, GL_AMBIENT , light_ambient );
glLightfv(GL_LIGHT0, GL_DIFFUSE , light_diffuse );
glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular);
glLightfv(GL_LIGHT0, GL_POSITION, light_position);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
return TRUE;
}
在glMain()中,使用glMaterialfv()来给球体设置材质,为了便于计算,我们使用了glPushMatrix()和glPopMatrix(),将20个球体分为4行,每行5个排列起来。
void glMain()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity(); //加载单位矩阵
glTranslatef(-6.0f, -4.5f, -15.0f);
for(int i=0; i<4; i++)
{
for(int j=0; j<5; j++)
{
glPushMatrix();
glTranslatef(3*j, 3*i, 0.0f);
glMaterialfv(GL_FRONT, GL_AMBIENT, &Materials[5*i+j][0]);
glMaterialfv(GL_FRONT, GL_DIFFUSE, &Materials[5*i+j][4]);
glMaterialfv(GL_FRONT, GL_SPECULAR, &Materials[5*i+j][8]);
glMaterialfv(GL_FRONT, GL_SHININESS, &Materials[5*i+j][12]);
auxSolidSphere(1.0);
glPopMatrix();
}
}
SwapBuffers(g_hDC);//交换前后缓冲区
}
程序运行后可以看到,在白光的照射下,各球体都表现出了材质对应的颜色。其中每个面向Z轴的方向都呈现出了白色的亮点,这就是高光(HightLight)现象。之所以是白色,是因为我们设置的GL_LIGHT0光源的镜面光是白色。效果如图7-2所示。
实际上人们所看到的物体的颜色是光照颜色和材质颜色的组合。假设光照颜色为(LR, LG, LB, LA),材质颜色为(MR, MG, MB, MA),那么我们看到的颜色就是两者的积(LR*MR, LR*MR, LB*MB, LA*MA)。如果场景中有多个光源,则整个光照颜色为几个光源对应分量之和(LR0+LR1+…+LRn, LG0+LG1+…+LGn, LB0+LB1+…+LBn),其中n<8。
图7-2 材质
float Materials[][13]=
{
//黄铜
0.329412, 0.223529, 0.027451, 1.000000,
0.780392, 0.568627, 0.113725, 1.000000,
0.992157, 0.941176, 0.807843, 1.000000,
27.897400,
//青铜
0.212500, 0.127500, 0.054000, 1.000000,
0.714000, 0.428400, 0.181440, 1.000000,
0.393548, 0.271906, 0.166721, 1.000000,
25.600000,
//亮青铜
0.250000, 0.148000, 0.064750, 1.000000,
0.400000, 0.236800, 0.103600, 1.000000,
0.774597, 0.458561, 0.200621, 1.000000,
76.800003,
//铬
0.250000, 0.250000, 0.250000, 1.000000,
0.400000, 0.400000, 0.400000, 1.000000,
0.774597, 0.774597, 0.774597, 1.000000,
76.800003,
//铜
0.191250, 0.073500, 0.022500, 1.000000,
0.703800, 0.270480, 0.082800, 1.000000,
0.256777, 0.137622, 0.086014, 1.000000,
12.800000,
//亮铜
0.229500, 0.088250, 0.027500, 1.000000,
0.550800, 0.211800, 0.066000, 1.000000,
0.580594, 0.223257, 0.069570, 1.000000,
51.200001,
//金
0.247250, 0.199500, 0.074500, 1.000000,
0.751640, 0.606480, 0.226480, 1.000000,
0.628281, 0.555802, 0.366065, 1.000000,
51.200001,
//亮金
0.247250, 0.224500, 0.064500, 1.000000,
0.346150, 0.314300, 0.090300, 1.000000,
0.797357, 0.723991, 0.208006, 1.000000,
83.199997,
//白蜡
0.105882, 0.058824, 0.113725, 1.000000,
0.427451, 0.470588, 0.541176, 1.000000,
0.333333, 0.333333, 0.521569, 1.000000,
9.846150,
//银
0.192250, 0.192250, 0.192250, 1.000000,
0.507540, 0.507540, 0.507540, 1.000000,
0.508273, 0.508273, 0.508273, 1.000000,
51.200001,
//亮银色
0.231250, 0.231250, 0.231250, 1.000000,
0.277500, 0.277500, 0.277500, 1.000000,
0.773911, 0.773911, 0.773911, 1.000000,
89.599998,
//翡翠、祖母绿
0.021500, 0.174500, 0.021500, 0.550000,
0.075680, 0.614240, 0.075680, 0.550000,
0.633000, 0.727811, 0.633000, 0.550000,
76.800003,
//碧玉
0.135000, 0.222500, 0.157500, 0.950000,
0.540000, 0.890000, 0.630000, 0.950000,
0.316228, 0.316228, 0.316228, 0.950000,
12.800000,
//黑曜石
0.053750, 0.050000, 0.066250, 0.820000,
0.182750, 0.170000, 0.225250, 0.820000,
0.332741, 0.328634, 0.346435, 0.820000,
38.400002,
//珍珠
0.250000, 0.207250, 0.207250, 0.922000,
1.000000, 0.829000, 0.829000, 0.922000,
0.296648, 0.296648, 0.296648, 0.922000,
11.264000,
//红宝石
0.174500, 0.011750, 0.011750, 0.550000,
0.614240, 0.041360, 0.041360, 0.550000,
0.727811, 0.626959, 0.626959, 0.550000,
76.800003,
//绿宝石、绿松石
0.100000, 0.187250, 0.174500, 0.800000,
0.396000, 0.741510, 0.691020, 0.800000,
0.297254, 0.308290, 0.306678, 0.800000,
12.800000,
//黑塑料
0.000000, 0.000000, 0.000000, 1.000000,
0.010000, 0.010000, 0.010000, 1.000000,
0.500000, 0.500000, 0.500000, 1.000000,
32.000000,
//黑橡胶
0.020000, 0.020000, 0.020000, 1.000000,
0.010000, 0.010000, 0.010000, 1.000000,
0.400000, 0.400000, 0.400000, 1.000000,
10.000000,
//紫罗兰
0.110000, 0.060000, 0.090000, 1.000000,
0.430000, 0.470000, 0.540000, 1.000000,
0.330000, 0.330000, 0.520000, 1.000000,
22.000000
};
glInit()仍然是启用光照,只是对场景背景作了些微调。
#include “materials.h”
……
int glInit()
{
// 启用纹理映射
glEnable(GL_TEXTURE_2D);
//启用阴影平滑(Smooth Shading)。
glShadeModel(GL_SMOOTH);
//调整场景背景颜色
glClearColor(0.2f,0.2f,0.2f,0.0f);
//设置深度缓冲
glClearDepth(1.0f);
//启动深度测试
glEnable(GL_DEPTH_TEST);
//深度测试的类型
glDepthFunc(GL_LEQUAL);
//进行透视修正
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
glLightfv(GL_LIGHT0, GL_AMBIENT , light_ambient );
glLightfv(GL_LIGHT0, GL_DIFFUSE , light_diffuse );
glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular);
glLightfv(GL_LIGHT0, GL_POSITION, light_position);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
return TRUE;
}
在glMain()中,使用glMaterialfv()来给球体设置材质,为了便于计算,我们使用了glPushMatrix()和glPopMatrix(),将20个球体分为4行,每行5个排列起来。
void glMain()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity(); //加载单位矩阵
glTranslatef(-6.0f, -4.5f, -15.0f);
for(int i=0; i<4; i++)
{
for(int j=0; j<5; j++)
{
glPushMatrix();
glTranslatef(3*j, 3*i, 0.0f);
glMaterialfv(GL_FRONT, GL_AMBIENT, &Materials[5*i+j][0]);
glMaterialfv(GL_FRONT, GL_DIFFUSE, &Materials[5*i+j][4]);
glMaterialfv(GL_FRONT, GL_SPECULAR, &Materials[5*i+j][8]);
glMaterialfv(GL_FRONT, GL_SHININESS, &Materials[5*i+j][12]);
auxSolidSphere(1.0);
glPopMatrix();
}
}
SwapBuffers(g_hDC);//交换前后缓冲区
}
程序运行后可以看到,在白光的照射下,各球体都表现出了材质对应的颜色。其中每个面向Z轴的方向都呈现出了白色的亮点,这就是高光(HightLight)现象。之所以是白色,是因为我们设置的GL_LIGHT0光源的镜面光是白色。效果如图7-2所示。
实际上人们所看到的物体的颜色是光照颜色和材质颜色的组合。假设光照颜色为(LR, LG, LB, LA),材质颜色为(MR, MG, MB, MA),那么我们看到的颜色就是两者的积(LR*MR, LR*MR, LB*MB, LA*MA)。如果场景中有多个光源,则整个光照颜色为几个光源对应分量之和(LR0+LR1+…+LRn, LG0+LG1+…+LGn, LB0+LB1+…+LBn),其中n<8。
图7-2 材质