这章学了基本光照模型,物体的显示受到以下效果影响:全局环境光,点光源(环境光漫反射分量,点光源漫反射分量,点光源镜面反射分量),材质系数(漫反射系数,镜面反射系数),自身发光,雾气效果等。其中点光源有辐射衰减(距离)和角衰减,根据距离或角度影响光的强度(即颜色)。
透明度计算公式:
雾气计算公式:
下例画出的是浅灰色雾气的环境下,有浅黄色背景光,偏红色的漫反射光和偏灰白的镜面反射光照在茶壶上的效果:
1 #include <GLUT/GLUT.h> 2 3 GLsizei winWidth = 500, winHeight = 500; 4 5 void init (void) 6 { 7 glEnable(GL_DEPTH_TEST); // 开启深度测试,才会让每个球深度显示正确 8 9 // init lighting 10 11 // 点光源位置 12 GLfloat light0PosType [] = {0.5, 0.5, 3.0, 1.0}; 13 glLightfv(GL_LIGHT0, GL_POSITION, light0PosType); 14 15 // 点光源颜色:环境光、漫反射、镜面反射颜色 16 GLfloat color1 [] = {0.0, 0.0, 0.0, 1.0}; 17 GLfloat color2 [] = {1.0, 0.0, 1.0, 1.0}; 18 glLightfv(GL_LIGHT0, GL_AMBIENT, color1); 19 glLightfv(GL_LIGHT0, GL_DIFFUSE, color2); 20 glLightfv(GL_LIGHT0, GL_SPECULAR, color2); 21 22 // 点光源辐射衰减系数 23 glLightf(GL_LIGHT0, GL_CONSTANT_ATTENUATION, 1); // 之前设置的衰减系数太高,导致点光源没有效果 24 glLightf(GL_LIGHT0, GL_LINEAR_ATTENUATION, 0.005); 25 glLightf(GL_LIGHT0, GL_QUADRATIC_ATTENUATION, 0.001); 26 27 // 点光源角度衰减系数 28 GLfloat dirVector [] = {0.0, 0.0, 0.0}; 29 glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, dirVector); 30 glLightf(GL_LIGHT0, GL_SPOT_CUTOFF, 30); 31 glLightf(GL_LIGHT0, GL_SPOT_EXPONENT, 2.7); // 系数越大,衰减的越快,看起来光圆锥体的范围变小 32 33 glEnable(GL_LIGHTING); 34 glEnable(GL_LIGHT0); 35 { 36 // 设置全局环境光颜色,是否固定视点,是否区分镜面反射与非镜面反射,是否前后面都绘制 37 GLfloat globalAmbient [] = {0.8, 0.8, 0.0, 1.0}; // 偏黄的环境光 38 glLightModelfv(GL_LIGHT_MODEL_AMBIENT, globalAmbient); 39 glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE); 40 glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR); 41 // glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE); 42 43 GLfloat ambLight[3] = {0.17f, 0.11f, 0.11f}; // 环境光漫反射系数 ka 44 glMaterialfv(GL_FRONT, GL_AMBIENT, ambLight); 45 GLfloat difLight[3] = {0.61f, 0.24f, 0.24f}; // 光源0漫反射系数 kd 46 glMaterialfv(GL_FRONT, GL_DIFFUSE, difLight); 47 GLfloat speLight[3] = {0.73f, 0.63f, 0.63f}; // 镜面反射系数 影响高光的亮度ks 48 glMaterialfv(GL_FRONT, GL_SPECULAR, speLight); 49 glMaterialf(GL_FRONT, GL_SHININESS, 100.0f); // 镜面反射指数参数 ns 光滑表面ns较大,粗糙表面ns可小到1 50 51 // 设置自身发光颜色,看起来很丑。。 52 // GLfloat surfEmissionColor [] = {0.0, 0.2, 0.0}; // 自身发浅绿光 53 // glMaterialfv(GL_FRONT, GL_EMISSION, surfEmissionColor); 54 } 55 56 glEnable(GL_FOG);//启用雾功能 57 GLfloat fogColor[4] = {0.5f, 0.5f, 0.5f, 1.0f}; 58 59 glFogi(GL_FOG_MODE, GL_LINEAR); 60 glFogfv(GL_FOG_COLOR, fogColor); 61 glFogf(GL_FOG_DENSITY, 0.35f); 62 glHint(GL_FOG_HINT, GL_DONT_CARE); 63 glFogf(GL_FOG_START, 1.0f); 64 glFogf(GL_FOG_END, 10.0f); 65 glClearColor(fogColor[0], fogColor[1], fogColor[2], fogColor[3]);//用雾气背景色 66 } 67 68 void drawTeapot (GLfloat x, GLfloat y, GLfloat z) 69 { 70 glPushMatrix(); 71 glTranslatef(x, y, z); 72 glutSolidTeapot(0.8); 73 glPopMatrix(); 74 } 75 76 void displayFcn (void) 77 { 78 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 79 80 drawTeapot(0, 0, 0); 81 drawTeapot(0, 0, -2); 82 drawTeapot(0, 0, -4); 83 drawTeapot(0, 0, -6); 84 85 glFlush(); 86 } 87 88 void reshapeFcn (GLint w, GLint h) 89 { 90 glViewport(0, 0, (GLsizei)w, (GLsizei)h); 91 glMatrixMode(GL_PROJECTION); 92 glLoadIdentity(); 93 glFrustum(-1, 1, -1, 1, 2, 30); 94 95 glMatrixMode(GL_MODELVIEW); 96 glLoadIdentity(); 97 gluLookAt(2, 2, 3, 0, 0, 0, 0, 1, 0); 98 } 99 100 void onMenu (int value) 101 { 102 GLint fogMode = 0; 103 switch (value) 104 { 105 case 1: 106 fogMode = GL_LINEAR; 107 break; 108 case 2: 109 fogMode = GL_EXP; 110 break; 111 case 3: 112 fogMode = GL_EXP2; 113 break; 114 } 115 glFogi(GL_FOG_MODE, fogMode); 116 if (value == 0) 117 { 118 glDisable(GL_FOG); 119 } 120 else 121 { 122 glEnable(GL_FOG); 123 } 124 glutPostRedisplay(); 125 } 126 127 void CreateMenu(void) 128 { 129 glutAddMenuEntry("线性", 1); 130 glutAddMenuEntry("指数", 2); 131 glutAddMenuEntry("指数2", 3); 132 glutAddMenuEntry("无雾", 0); 133 glutAttachMenu(GLUT_RIGHT_BUTTON); 134 } 135 136 int main(int argc, char * argv[]) 137 { 138 glutInit(&argc, argv); 139 glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH); 140 glutInitWindowPosition(50, 50); 141 glutInitWindowSize(winWidth, winHeight); 142 glutCreateWindow("Lighting"); 143 glutCreateMenu(onMenu); 144 CreateMenu(); 145 146 init(); 147 glutDisplayFunc(displayFcn); 148 glutReshapeFunc(reshapeFcn); 149 glutMainLoop(); 150 151 return 0; 152 }