环境光:环境光来自于四面八方。所有场景中的对象都处于环境光的照射中。 漫射光:漫射光由特定的光源产生,并在您的场景中的对象表面上产生反射。处于漫射光直接照射下的任何对象表面都变得很亮,而几乎未被照射到的区域就显得要暗一些。 创建光源的过程和颜色的创建完全一致。前三个参数分别是RGB三色分量,最后一个是alpha通道参数。 glLightfv(GL_LIGHT1, GL_AMBIENT, LightAmbient); //设置1号光源环境光 glLightfv(GL_LIGHT1, GL_DIFFUSE, LightDiffuse); //设置1号光源漫射光 glLightfv(GL_LIGHT1, GL_POSITION,LightPosition);//设置1号光源位置 glEnable(GL_LIGHT1);//启用1号光源 glEnable(GL_LIGHTING);//启用光源 glDisable(GL_LIGHTING);//禁用光源 禁用光源只是禁用了漫射光 在设置图形坐标点时需要设置法线的位置 glNormal3f 所谓法线是指经过面(多边形)上的一点且垂直于这个面(多边形)的直线。使用光源的时候必须指定一条法线。法线告诉OpenGL这个多边形的朝向,并指明多边形的正面和背面 glNormal3f( 0.0f, 0.0f, 1.0f);// (前侧面)法线指向观察者 glNormal3f( 0.0f, 0.0f, -1.0f);// (后侧面)法线背向观察者 |
材质:OpenGL中的材质并非我们平常所说的组成物体的元素(如木材、金属材质),而是指一个物体对不同颜色的光的反射和吸收程度。比如,在光照系统中,如果一个物体表现为红色,则是因为这个物体吸收了从光源放射出来的绿色和蓝色光,而将绝大多数红色的光反射了出来。正因如此,一旦你开启了光照系统,就要通过指定物体的材质来决定这个物体是什么颜色 |
环境光: 环境光是一种无处不在的光。环境光源放出的光线被认为来自任何方向。因此,当你仅为场景指定环境光时,所有的物体无论法向量如何,都将表现为同样的明暗程度。 光的成分: 对于每一种光源,都有漫射光和平行光两种成分。在OpenGL中,环境光也被作为一种特殊的光源的成分来看待。漫射光是指在光源中能够被漫反射的光的颜色成分(白色则包含所有颜色),而平行光是指光源中所有能够被镜面反射的光的颜色成分。通过指定这两种成分的颜色,就能决定光源是平行光源还是点光源。 设置光源成分: OpenGL可以同时为我们提供8个有效的光源。也就是说,我们最多可以同时启用8个光源。它们分别是GL_LIGHT0,GL_LIGHT1,GL_LIGHT2 …… 其中,GL_LIGHT0是最特殊的一个光源。我们可以为GL_LIGHT0指定环境光成分。 |
设置漫射光: floatDiffuseLight[4]={R,G,B,A}; 其中RGBA分别是光的颜色,如(1,0,0,1) 红色光 glLightfv(GL_LIGHT0,GL_DIFFUSE,DiffuseLight); |
设定材质: 指定了图元的法线之后,我们还需要为其指定相应的材质以决定物体对各种颜色的光的反射程度,这将影响物体表现为何种颜色。和光源的成分相似,材质也分为漫射光反光率、平行光反光率。材质的漫射光成分将决定该材质对环境中的漫射光的反射程度。绘制图元之前调用glMaterialf或glMaterialfv函数 |
举例1:散射光设置为(1,0,0,1) 材质反射率设置为(1,0,0,1) |
举例2:散射光设置为(1,0,0,1) 材质反射率设置为(0.5,0,0,1) |
举例3:散射光设置为(1,1,0,1) |
#include "header.h" bool light; GLfloat xrot; GLfloat yrot; GLfloat xspeed; GLfloat yspeed; GLfloat z=-5.0f; GLfloat LightAmbient[]= { 0.5f, 0.5f, 0.5f, 1.0f }; GLfloat LightDiffuse[]= { 1.0f, 1.0f, 1.0f, 1.0f }; GLfloat LightPosition[]= { 0.0f, 0.0f, 2.0f, 1.0f }; GLfloat mat_specular[]={1,0,0,1}; GLuint filter; GLuint texture[3]; AUX_RGBImageRec *LoadBMP(char *Filename) { FILE *File=NULL; if (!Filename) { return NULL; } File=fopen(Filename,"r"); if (File) { fclose(File); return auxDIBImageLoad(Filename); } return NULL; } int LoadGLTextures() { int Status=FALSE; AUX_RGBImageRec *TextureImage[1]; memset(TextureImage,0,sizeof(void *)*1); if (TextureImage[0]=LoadBMP("Data/Crate.bmp")) { Status=TRUE; glGenTextures(3, &texture[0]); glBindTexture(GL_TEXTURE_2D, texture[0]); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST); glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[0]->sizeX, TextureImage[0]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[0]->data); glBindTexture(GL_TEXTURE_2D, texture[1]); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[0]->sizeX, TextureImage[0]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[0]->data); glBindTexture(GL_TEXTURE_2D, texture[2]); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_NEAREST); gluBuild2DMipmaps(GL_TEXTURE_2D, 3, TextureImage[0]->sizeX, TextureImage[0]->sizeY, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[0]->data); } if (TextureImage[0]) { if (TextureImage[0]->data) { free(TextureImage[0]->data); } free(TextureImage[0]); } return Status; } GLvoid ReSizeGLScene(GLsizei width, GLsizei height) { if (height==0) { height=1; } glViewport(0,0,width,height); glMatrixMode(GL_PROJECTION); glLoadIdentity(); // Calculate The Aspect Ratio Of The Window gluPerspective(45.0f,(GLfloat)width/(GLfloat)height,0.1f,100.0f); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); } int InitGL(GLvoid) { if (!LoadGLTextures()) { return FALSE; } glEnable(GL_TEXTURE_2D); glShadeModel(GL_SMOOTH); glClearColor(0.0f, 0.0f, 0.0f, 0.5f); glClearDepth(1.0f); glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LEQUAL); glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); glLightfv(GL_LIGHT1, GL_AMBIENT, LightAmbient); glLightfv(GL_LIGHT1, GL_DIFFUSE, LightDiffuse); glLightfv(GL_LIGHT1, GL_POSITION,LightPosition); glEnable(GL_LIGHT1); return TRUE; } void DrawGLScene(void) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glLoadIdentity(); glTranslatef(0.0f,0.0f,z); glRotatef(xrot,1.0f,0.0f,0.0f); glRotatef(yrot,0.0f,1.0f,0.0f); glBindTexture(GL_TEXTURE_2D, texture[filter]); glBegin(GL_QUADS); // Front Face glNormal3f( 0.0f, 0.0f, 1.0f); glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f); glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f); glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 1.0f); glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f); // Back Face glNormal3f( 0.0f, 0.0f,-1.0f); glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f); glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f); glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f); glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f); // Top Face glNormal3f( 0.0f, 1.0f, 0.0f); glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f); glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, 1.0f, 1.0f); glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, 1.0f, 1.0f); glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f); // Bottom Face glNormal3f( 0.0f,-1.0f, 0.0f); glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, -1.0f, -1.0f); glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, -1.0f, -1.0f); glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f); glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f); // Right face glNormal3f( 1.0f, 0.0f, 0.0f); glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f); glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f); glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 1.0f); glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f); // Left Face glNormal3f(-1.0f, 0.0f, 0.0f); glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f); glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f); glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f); glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f); glEnd(); xrot+=xspeed; yrot+=yspeed; glutSwapBuffers(); glFlush(); } void rotate() { glutPostRedisplay(); } void keyboard( unsigned char key, int x, int y ) { switch( key ) { case 'L': light=!light; if (!light) { glDisable(GL_LIGHTING); } else { glEnable(GL_LIGHTING); } glutPostRedisplay(); break; case 'W': xspeed+=0.01f; glutIdleFunc(rotate); break; case 'A': yspeed-=0.01f; glutIdleFunc(rotate); break; case 'S': yspeed+=0.01f; glutIdleFunc(rotate); break; case 'D': xspeed-=0.01f; glutIdleFunc(rotate); break; case 'Z': z-=0.01f; glutPostRedisplay(); break; case 'X': z+=0.01f; glutPostRedisplay(); break; case 'F': filter+=1; if (filter>2) { filter=0; } glutPostRedisplay(); break; case 'R': mat_specular[0] =1; mat_specular[1] =0; mat_specular[2] =0; mat_specular[3] =1; glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_specular); LightDiffuse[0]=1; LightDiffuse[1]=0; LightDiffuse[2]=0; LightDiffuse[3]=1; glLightfv(GL_LIGHT1, GL_DIFFUSE, LightDiffuse); glutPostRedisplay(); break; case 'G': mat_specular[0] =0.5f; mat_specular[1] =0; mat_specular[2] =0; mat_specular[3] =1; glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_specular); LightDiffuse[0]=1; LightDiffuse[1]=0; LightDiffuse[2]=0; LightDiffuse[3]=1; glLightfv(GL_LIGHT1, GL_DIFFUSE, LightDiffuse); glutPostRedisplay(); break; case 'Y': mat_specular[0] =1; mat_specular[1] =1; mat_specular[2] =0; mat_specular[3] =1; glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_specular); LightDiffuse[0]=1; LightDiffuse[1]=1; LightDiffuse[2]=0; LightDiffuse[3]=1; glLightfv(GL_LIGHT1, GL_DIFFUSE, LightDiffuse); glutPostRedisplay(); break; } } int main( int argc, char** argv ) { glutInit( &argc, argv ); glutInitDisplayMode( GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE ); glutInitWindowSize( 512, 512 ); glutInitWindowPosition( 100, 100 ); glutCreateWindow( "光照效果" ); InitGL(); glutDisplayFunc( DrawGLScene ); glutReshapeFunc( ReSizeGLScene ); glutKeyboardFunc( keyboard ); glutMainLoop(); return 0; }