基于图形之光照与材质

1.颜色
• 设置颜色的函数
– glColor3f(…);
– glColor4f(…);
– 指定着色模式
– 纯色(恒定着色)
– 多种颜色(平滑着色)
– 设置着色模式函数:glShadeModel(…);

• 功能:
– 设置当前颜色
• 参数:
– r:红色分量的值
– g:绿色分量的值
– b:蓝色分量的值
• 返回值:无
• 备注:
– r、g、b的值的范围在区间〔0,1〕内
– 0.0强度最小
– 1.0强度最大

• void glColor4f(GLfloat r, GLfloat g, GLfloat b, GLfloat alpha);
• 功能:
– 设置当前颜色
• 参数:
– r:红色分量的值
– g:绿色分量的值
– b:蓝色分量的值
– alpha:alpha分量的值,用作混合
• 返回值:无
• 备注:
r、g、b、alpha的值的范围在区间〔0,1〕内

指定着色模式
void glShadeModel(GLenum mode);
功能:指定着色模式
参数:
mode:着色模式
返回值:无
备注:
mode可以取下列值:
GL_FLAT 恒定着色
GL_SMOOTH 平滑着色

基于图形之光照与材质_第1张图片

#include 
#include 
GLfloat step = 0.0f;
void display()
{
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glTranslatef(0.0f, 0.0f, -200.0f);
glPushMatrix();
glRotatef(step, 1.0f, 0.0f, 0.0f);

//绘制三棱锥的三个棱面,他们的颜色分别为红、绿、蓝
glBegin(GL_TRIANGLE_FAN);
    glVertex3f(0.0, 0.0, 80.0);//高度
    glVertex3f(0.0, 50.0, 0.0);
	glColor3f(1.0,0.0,0.0);
	glVertex3f(50.0, -50.0, 0.0);
	glColor3f(0.0,1.0,0.0);
	glVertex3f(-50.0, -50.0, 0.0);
	glColor3f(0.0,0.0,1.0);
	glVertex3f(0.0, 50.0, 0.0);


glEnd();

//绘制三棱锥的底面,其颜色为黄色
glBegin(GL_TRIANGLE_FAN);
	glVertex3f(0.0, 50.0, 0.0);
	glVertex3f(50.0, -50.0, 0.0);
	glColor3f(1.0,1.0,0.0);
	glVertex3f(-50.0, -50.0, 0.0);
glEnd();
glPopMatrix();

glutSwapBuffers();
}

void animation(void)
{
    step += 1.0f;//翻转速度
    step = (GLfloat)((int)step % 360);//翻转角度
    glutPostRedisplay();
}

void resize(int width, int height)
{
    float ar = (float) width / (float) height;
    glViewport(0, 0, width, height);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity() ;
    gluPerspective(45.0, ar, 1.0, 500.0);
    glMatrixMode(GL_MODELVIEW);
}

int main( int argc, char ** argv )
{
glutInit( &argc, argv );
glutInitDisplayMode( GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowPosition( 100, 100 );
glutInitWindowSize( 1000, 1000 );//画布大小
glutCreateWindow( "OpenGL Examples!" );
glutDisplayFunc( display );
glutIdleFunc(animation);
glutReshapeFunc(resize);
glEnable(GL_DEPTH_TEST);
glShadeModel(GL_SMOOTH);//平滑着色

//glShadeModel(GL_SMOOTH);
glutMainLoop();
return 0;
}

2.启用光源
要在OpenGL环境中使用光照,需要告诉OpenGL系统启用光源
启用光源分为两步
开启光源1,开启光源2, …………
开启光照渲染
开启光源i
glEnable(GL_LIGHTi); //i是从0到7之间的整数
开启光照渲染
glEnable(GL_LIGHTING);

#include 
#include 

GLfloat step = 0.0f;

void display()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glColor3f( 1, 0, 0 );//颜色
glPushMatrix();
    glTranslated(0,0,-3);
    glRotated(60,30,-15,0);
    glRotated(step,0,0,1);
    glutSolidSphere(1,128,128);
glPopMatrix();

glutSwapBuffers();
}

void resize(int width, int height)
{
    float ar = (float) width / (float) height;
    glViewport(0, 0, width, height);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glFrustum(-ar, ar, -1.0, 1.0, 2.0, 100.0);
    glMatrixMode(GL_MODELVIEW);
}

void SpecialKeys(int key, int x, int y)
{
if(key == GLUT_KEY_UP)
    step -= 5.0f;
if(key == GLUT_KEY_DOWN)
    step += 5.0f;

step = (GLfloat)((int)step % 360);
glutPostRedisplay();
}

void SetupRC()
{
glClearColor(0,0,0,1);
glEnable(GL_DEPTH_TEST);//启动光源

GLfloat light_ambient[]  = { 0.0f, 0.0f, 0.0f, 1.0f };
GLfloat light_diffuse[]  = { 1.0f, 1.0f, 1.0f, 1.0f };
GLfloat light_specular[] = { 1.0f, 1.0f, 1.0f, 1.0f };
GLfloat light_position[] = { 2.0f, 5.0f, 5.0f, 0.0f };

GLfloat mat_ambient[]    = { 0.7f, 0.7f, 0.7f, 1.0f };
GLfloat mat_diffuse[]    = { 0.8f, 0.8f, 0.8f, 1.0f };
GLfloat mat_specular[]   = { 1.0f, 1.0f, 1.0f, 1.0f };
GLfloat high_shininess[] = { 100.0f };

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);

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, high_shininess);

glEnable(GL_LIGHT0);//不要忘了
glEnable(GL_COLOR_MATERIAL);//不要忘了
glEnable(GL_LIGHTING);//不要忘了

}

int main( int argc, char ** argv )
{
glutInit( &argc, argv );
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
glutInitWindowPosition( 100, 100 );
glutInitWindowSize( 400, 400 );
glutCreateWindow( "OpenGL Examples!" );
glutSpecialFunc(SpecialKeys);
glutDisplayFunc( display );
glutReshapeFunc(resize);
SetupRC();
glutMainLoop();
return 0;
}

3.禁用光源
禁用光源分为两种情况
禁用指定光源
禁用光照渲染(禁用所有光源)

禁用光源i
glDisable(GL_LIGHTi); //i是从0到7之间的整数

禁用光照渲染
glDisable(GL_LIGHTING);

4.光源属性
光源的属性:
颜色 位置 方向
其他属性:
衰减 聚光灯 多光源
设置光源属性的函数
glLightfv(…)
glLightf(…)

4.1定义光源
void glLight{i f}{v}(GLenum light, GLenum pname, TYPE param);
功能:设置光源参数
参数:
light:指定一个光源
pname: 指定光源参数
param: 光源参数的具体设定值
返回值:无

基于图形之光照与材质_第2张图片
4.2颜色
环境光颜色
散射光颜色
镜面反射光颜色
例:
GLfloat LightAmbient[]={0.5f,0.5f,0.5f,1.0f};
GLfloat LightDiffuse[]={1.0f,1.0f,1.0f,1.0f};
GLfloat LightSpecular[]={0.5f,0.5f,0.5f,1.0f};
glLightfv(GL_LIGHT0,GL_AMBIENT, LightAmbient);
glLightfv(GL_LIGHT0,GL_DIFFUSE, LightDiffuse);
glLightfv(GL_LIGHT0,GL_SPECULAR, LightSpecular);
4.3位置
定向(directional)光源,如太阳
位置(x, y, z, w)中w为0,则光源为定向光源
定位(positional)光源,如台灯
位置(x, y, z, w)中w不为0,则光源为定位光源
聚光灯
聚光灯是一种定位光源,需要指定其位置
截止角,GL_SPOT_CUTOFF
GL_SPOT_CUTOFF默认值180
除默认值外,它的取值范围[0.0, 90.0]
例:glLightf(GL_LIGHT0, GL_SPOT_CUTOFF, 45.0);

聚光灯方向, GL_SPOT_DIRECTION (轴线方向)
默认方向(0.0, 0.0, -1.0)
GLfloat spot_direction[] = {-1.0, -1.0, 0.0};
glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, spot_direction);
聚光指数, GL_SPOT_EXPONENT
默认为0.0,轴线处光强最大
聚光指数越大,光源的聚焦效果越高
glLightf(GL_LIGHT1, GL_SPOT_EXPONENT, 5.0)
多光源
OpenGL至少允许在场景中使用8个光源(甚至更多)
GL_LIGHT0, GL_LIGHT1, GL_LIGHT2, ……,GL_LIGHT7
使用多个光源将会降低性能

#include 
#include 

GLfloat step = 0.0f;

void display()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushMatrix();
    glTranslated(0,step,-4.5f);
    glutSolidSphere(1,128,128);
glPopMatrix();

glutSwapBuffers();
}

void resize(int width, int height)
{
    float ar = (float) width / (float) height;
    glViewport(0, 0, width, height);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glFrustum(-ar, ar, -1.0, 1.0, 2.0, 100.0);
    glMatrixMode(GL_MODELVIEW);
}

void SpecialKeys(int key, int x, int y)
{
if(key == GLUT_KEY_UP)
    step += 0.5f;
if(key == GLUT_KEY_DOWN)
    step -= 0.5f;

glutPostRedisplay();
}

void SetupRC()
{
GLfloat mat_ambient[]= { 0.2f, 0.2f, 0.2f, 1.0f };
	GLfloat mat_diffuse[]= { 0.8f, 0.8f, 0.8f, 1.0f };
	GLfloat mat_specular[] = { 1.0f, 1.0f, 1.0f, 1.0f };
	GLfloat mat_shininess[] = { 50.0f };
	GLfloat light0_diffuse[]= { 0.0f, 0.0f, 1.0f, 1.0f};
	GLfloat light0_position[] = { 1.0f, 1.0f, 1.0f, 0.0f };
	GLfloat light1_ambient[]= { 0.2f, 0.2f, 0.2f, 1.0f };
	GLfloat light1_diffuse[]= { 1.0f, 0.0f, 0.0f, 1.0f };
	GLfloat light1_specular[] = { 1.0f, 0.6f, 0.6f, 1.0f };
	GLfloat light1_position[] = { -3.0f, -3.0f, 3.0f, 1.0f };
	GLfloat spot_direction[]={ 1.0f, 1.0f, -1.0f};

	//定义材质属性
	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);

	//light0为漫反射的蓝色点光源
	glLightfv(GL_LIGHT0, GL_DIFFUSE, light0_diffuse);
	glLightfv(GL_LIGHT0, GL_POSITION,light0_position);

	//light1为红色聚光光源
	glLightfv(GL_LIGHT1, GL_AMBIENT, light1_ambient);
	glLightfv(GL_LIGHT1, GL_DIFFUSE, light1_diffuse);
	glLightfv(GL_LIGHT1, GL_SPECULAR,light1_specular);
	glLightfv(GL_LIGHT1, GL_POSITION,light1_position);
	glLightf (GL_LIGHT1, GL_SPOT_CUTOFF, 30.0);
	glLightfv(GL_LIGHT1, GL_SPOT_DIRECTION,spot_direction);

	glEnable(GL_LIGHTING);
	glEnable(GL_LIGHT0);
	glEnable(GL_LIGHT1);
	glEnable(GL_DEPTH_TEST);

	glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
}

int main( int argc, char ** argv )
{
glutInit( &argc, argv );
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
glutInitWindowPosition( 100, 100 );
glutInitWindowSize( 400, 400 );
glutCreateWindow( "OpenGL Examples!" );
glutSpecialFunc(SpecialKeys);
glutDisplayFunc( display );
glutReshapeFunc(resize);
SetupRC();
glutMainLoop();
return 0;
}

3.创建光源
void glLightf(GLenum light, GLint pname,
GLfloat param);
功能:
设置光源属性
参数:
light: 指定光源(第几盏灯)
pname:设置光源的属性
param: pname的值,是一个浮点数
返回值:无
备注:
light可取下列值:
GL_LIGHT0, GL_LIGHT1, … GL_LIGHT7
pname可取下列值:
GL_SPOT_EXPONENT //聚光指数(默认0.0)
GL_SPOT_CUTOFF //聚光截止角(默认180.0)
GL_CONSTANT_ATTENUATION //固定衰减因子(默认1.0)
GL_LINEAR_ATTENUATION //线性衰减因子(默认0.0)
GL_QUADRATIC_ATTENUATION //二次衰减因子(默认0.0)
例:
GLfloat LightSpotExponent = 10.0f; //聚光指数
GLfloat LightSpotCutoff = 20.0f; //聚光角度
glLightf( GL_LIGHT1,GL_SPOT_EXPONENT, LightSpotExponent );
glLightf( GL_LIGHT1, GL_SPOT_CUTOFF, LightSpotCutoff );

4.4控制光源的位置和方向
可以通过模型视点变换来改变光源的位置和方向
三种常见的光源变换
①光源位置固定
②光源绕静止的物体旋转
③光源随视点一起移动
光源位置固定
必须在视点变换或模型变换后,再次设置光源的位置

例:光源位置固定

void display(void)
	{
		//清屏
		//……
		//移动视点及绘图
		//……
		//重置光源的位置
	glLoadIdentity(); 
	GLfloat  light_position[] = { 1.0, 1.0, 1.0, 1.0 }; 
     glLightfv(GL_LIGHT0, GL_POSITION, light_position);
	}

例:光源绕静止物体旋转


    GLfloat  light_position[] = { 0.0, 0.0, 1.5, 1.0 };
	glClear(GL_COLOR_BUFFER_BIT| GL_DEPTH_BUFFER_BIT);
	glPushMatrix();
		glTranslatef(0.0, 0.0, -5.0); 
	glPushMatrix();
  	glRotated(xRot, 1.0, 0.0, 0.0);
  	glLightfv(GL_LIGHT0, GL_POSITION, light_position);
	glPopMatrix();
		glutSolidTorus (0.275, 0.85, 50, 50);
	glPopMatrix();

实例:

#include 
#include 
GLfloat step = 0.0f;
void display()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glLoadIdentity();//重置当前指定的矩阵为单位矩阵
glColor3f( 1, 1, 0 );
glTranslated(0,0,-30);
glutSolidSphere(5,32,32);//画个球
glPopMatrix();

/*glColor3f(0,0,1);
glPushMatrix();//堆栈
glRotated(10,0,0,1);
glRotated(step,0,1,0);
glTranslated(0,0,20);
glutSolidSphere(3,32,32);
glPopMatrix();
*/
GLfloat  light_position[] = { 0.0, 0.0, 0.5, 1.0 };
//glClear(GL_COLOR_BUFFER_BIT| GL_DEPTH_BUFFER_BIT);
glColor3f(0,0,1);
glPushMatrix();//堆栈
glRotated(10,0,0,1);
glLightfv(GL_LIGHT0, GL_POSITION, light_position);
glRotated(step,0,1,0);
glTranslated(0,0,10);//转悠的半径
glutSolidSphere(3,32,32);//画个球
glPopMatrix();




glutSwapBuffers();
}

void resize(int width, int height)
{
    float ar = (float) width / (float) height;

    glViewport(0, 0, width, height);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity() ;
    glFrustum(-ar, ar, -1.0, 1.0, 2.0, 100.0);
    glMatrixMode(GL_MODELVIEW);
}

void NormalKeys(unsigned char key, int x, int y)
{
switch(key)
{
    case '1':
      step += 5.0f;
      break;
    case '2':
      step -= 5.0f;
      break;
    default:
      break;
}

step = (GLfloat)((int)step % 360);
glutPostRedisplay();
}


void SetupRC()
{
glClearColor(0,0,0,1);
glEnable(GL_DEPTH_TEST);//启动光源
GLfloat light_ambient[]  = { 0.0f, 0.0f, 0.0f, 1.0f };
GLfloat light_diffuse[]  = { 1.0f, 1.0f, 1.0f, 1.0f };
GLfloat light_specular[] = { 1.0f, 1.0f, 1.0f, 1.0f };
GLfloat light_position[] = { 2.0f, 5.0f, 5.0f, 0.0f };


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);

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_LIGHT0);
glEnable(GL_COLOR_MATERIAL);
glEnable(GL_LIGHTING);
}

int main( int argc, char ** argv )
{
glutInit( &argc, argv );
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
glutInitWindowPosition( 100, 100 );
glutInitWindowSize( 400, 400 );
glutCreateWindow( "OpenGL Examples!" );
glutKeyboardFunc(NormalKeys);
glutDisplayFunc( display );
glutReshapeFunc(resize);
SetupRC();
glutMainLoop();
return 0;
}

光源随物体一起旋转

#include 
#include 
GLfloat step = 0.0f;
GLfloat stepp = 0.0f;
void display()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
 GLfloat position[] = { 0.0, 0.0, 1.5, 1.0 };
 glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
 glPushMatrix ();
 gluLookAt (0.0, 0.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
 glPushMatrix ();
 glRotated ((GLdouble)stepp , 1.0, 0.0, 0.0);
 glRotated ((GLdouble) step, 0.0, 1.0, 0.0);
 glTranslated (0.0, 0.0, 1.5);
 glLightfv (GL_LIGHT0, GL_POSITION, position);
 glutSolidSphere (0.05,50,50);
 glutSolidTorus (0.275, 0.85, 80, 150);
 glPopMatrix ();
 glPopMatrix();




glutSwapBuffers();
}

void resize(int width, int height)
{
    float ar = (float) width / (float) height;

    glViewport(0, 0, width, height);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity() ;
    glFrustum(-ar, ar, -1.0, 1.0, 2.0, 100.0);
    glMatrixMode(GL_MODELVIEW);
}

void NormalKeys(unsigned char key, int x, int y)
{
switch(key)
{
    case '1':
      step += 5.0f;
      stepp += 7.0f;
      break;
    case '2':
      step -= 5.0f;
      stepp += 7.0f;
      break;
    default:
      break;
}

step = (GLfloat)((int)step % 360);
glutPostRedisplay();
}


void SetupRC()
{
glClearColor(0,0,0,1);
glEnable(GL_DEPTH_TEST);//启动光源
GLfloat light_ambient[]  = { 0.0f, 0.0f, 0.0f, 1.0f };
GLfloat light_diffuse[]  = { 1.0f, 1.0f, 1.0f, 1.0f };
GLfloat light_specular[] = { 1.0f, 1.0f, 1.0f, 1.0f };
GLfloat light_position[] = { 2.0f, 5.0f, 5.0f, 0.0f };


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);

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_LIGHT0);
glEnable(GL_COLOR_MATERIAL);
glEnable(GL_LIGHTING);
}

int main( int argc, char ** argv )
{
glutInit( &argc, argv );
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
glutInitWindowPosition( 100, 100 );
glutInitWindowSize( 400, 400 );
glutCreateWindow( "OpenGL Examples!" );
glutKeyboardFunc(NormalKeys);
glutDisplayFunc( display );
glutReshapeFunc(resize);
SetupRC();
glutMainLoop();
return 0;
}

实例2,诡异的光

#include 
#include 
GLfloat step = 0.0f;
GLfloat stepp = 0.0f;
void display()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
 GLfloat position[] = { 0.0, 0.0, 1.5, 1.0 };
 glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
 glPushMatrix ();
 gluLookAt (0.0, 0.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
 glPushMatrix ();
 glRotated ((GLdouble)stepp , 1.0, 0.0, 0.0);
 glRotated ((GLdouble) step, 0.0, 1.0, 0.0);
 glTranslated (0.0, 0.0, 1.5);
 glLightfv (GL_LIGHT0, GL_POSITION, position);
 glutSolidSphere (0.05,50,50);
 glutSolidTorus (0.275, 0.85, 80, 150);
 glPopMatrix ();
 glPopMatrix();




glutSwapBuffers();
}

void resize(int width, int height)
{
    float ar = (float) width / (float) height;

    glViewport(0, 0, width, height);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity() ;
    glFrustum(-ar, ar, -1.0, 1.0, 2.0, 100.0);
    glMatrixMode(GL_MODELVIEW);
}

void NormalKeys(unsigned char key, int x, int y)
{
switch(key)
{
    case '1':
      step += 5.0f;
      stepp += 7.0f;
      break;
    case '2':
      step -= 5.0f;
      stepp += 7.0f;
      break;
    default:
      break;
}

step = (GLfloat)((int)step % 360);
glutPostRedisplay();
}


void SetupRC()
{
glClearColor(0,0,0,1);
glEnable(GL_DEPTH_TEST);//启动光源
GLfloat mat_ambient[]= { 0.2f, 0.2f, 0.2f, 1.0f };
GLfloat mat_diffuse[]= { 0.8f, 0.8f, 0.8f, 1.0f };
GLfloat mat_specular[] = { 1.0f, 1.0f, 1.0f, 1.0f };
GLfloat mat_shininess[] = { 50.0f };
GLfloat light0_diffuse[]= { 0.0f, 0.0f, 1.0f, 1.0f};
GLfloat light0_position[] = { 1.0f, 1.0f, 1.0f, 0.0f };
GLfloat light1_ambient[]= { 0.2f, 0.2f, 0.2f, 1.0f };
GLfloat light1_diffuse[]= { 1.0f, 0.0f, 0.0f, 1.0f };
GLfloat light1_specular[] = { 1.0f, 0.6f, 0.6f, 1.0f };
GLfloat light1_position[] = { -3.0f, -3.0f, 3.0f, 1.0f };
GLfloat spot_direction[]={ 1.0f, 1.0f, -1.0f};

//light0为漫反射的蓝色点光源
glLightfv(GL_LIGHT0, GL_DIFFUSE, light0_diffuse);
glLightfv(GL_LIGHT0, GL_POSITION,light0_position);

//light1为红色聚光光源
glLightfv(GL_LIGHT1, GL_AMBIENT, light1_ambient);
glLightfv(GL_LIGHT1, GL_DIFFUSE, light1_diffuse);
glLightfv(GL_LIGHT1, GL_SPECULAR,light1_specular);
glLightfv(GL_LIGHT1, GL_POSITION,light1_position);
glLightf (GL_LIGHT1, GL_SPOT_CUTOFF, 30.0);
glLightfv(GL_LIGHT1, GL_SPOT_DIRECTION,spot_direction);

glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_LIGHT1);
glEnable(GL_DEPTH_TEST);



glEnable(GL_LIGHT0);
glEnable(GL_COLOR_MATERIAL);
glEnable(GL_LIGHTING);


}

int main( int argc, char ** argv )
{
glutInit( &argc, argv );
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
glutInitWindowPosition( 100, 100 );
glutInitWindowSize( 400, 400 );
glutCreateWindow( "OpenGL Examples!" );
glutKeyboardFunc(NormalKeys);
glutDisplayFunc( display );
glutReshapeFunc(resize);
SetupRC();
glutMainLoop();
return 0;
}

5.选择光照模型
OpenGL光照模型包括4项内容
全局环境光强度
观察点靠近场景还是位于无穷远处
单面光照或双面光照
镜面反射颜色是否独立于环境颜色、散射颜色(OpenGL 1.4)

选择光照模型的函数
glLightModelfv(…);
glLightModeli(…);

void glLightModelfv(GLenum pname, GLfloat* param);
功能:
选择光照模型
参数:
pname: 光照模型的类型
param: 该类型值的数组地址
返回值:无
备注:
pname可以取值为:
GL_LIGHT_MODEL_AMBIENT 整个场景的RGBA强度(0.2, 0.2, 0.2, 1.0)

环境光
经过多次反射而来的光称为环境光,无法确定其最初的方向,但当特定的光源关闭后,它们将消失。
全局环境光
每个光源都能对场景提供环境光。此外,还有一个环境光,它不来自任何特定的光源,称之为全局环境光。这也就是为什么我们不加任何自定义光源,也能看见绘制的物体的原因。
例:设置全局环境光颜色
GLfloat lmodel_ambient[] = { 0.2, 0.2, 0.2, 1.0 };
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient);

void glLightModeli(GLenum pname, GLint param);
功能:
选择光照模型
参数:
pname: 光照模型的类型
param: 该类型的值
返回值:无
备注:
pname可以取值为:
GL_LIGHT_MODEL_LOCAL_VIEWER //观察点是否无穷远(GL_FALSE)
GL_LIGHT_MODEL_TWO_SIDE //单面还是双面光照(GL_FALSE )

观察点靠近物体还是无穷远
在视点无穷远的情况下,场景中任何顶点到视点的方向都是同一常数。
否则,则不然,但效果会更加真实
例:设置观察点无穷远
glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE);

单面光照或双面光照
多边形的正面和背面是否都需要光照
例:指定双面光照
glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);

6.设置材质属性
启用光照时,物体顶点的颜色信息将被忽略
启用光照时,物体顶点的颜色取决于光源的颜色和物体材质的颜色.

设置材质属性
void glMaterialfv(GLenum face, GLenum pname, GLfloat* param);
功能:指定材质属性
参数:
face: 指定正面或背面的材质
pname: 指定要设置哪种材质属性
param: 属性值的数组地址
返回值:无

备注:
face可取如下值:
GL_FRONT
GL_BACK
GL_FRONT_AND_BACK
pname可取如下值:
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_SHININESS (0.0)
GL_EMISSION (0.0, 0.0, 0.1, 1.0)

基于图形之光照与材质_第3张图片
例:散射和环境光反射
GLfloat mat_amb_diff[] = { 0.1, 0.5, 0.8, 1.0 };
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, mat_amb_diff);

例:镜面反射材质
GLfloat mat_specular[] = { 1.0, 1.0, 1.0, 1.0 };
GLfloat low_shininess[] = { 5.0 };
glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
glMaterialfv(GL_FRONT, GL_SHININESS, low_shininess);

例:发射光颜色
GLfloat mat_emission[] = {0.3, 0.2, 0.2, 0.0};
glMaterialfv(GL_FRONT, GL_EMISSION, mat_emission);

#include 
#include 

GLfloat diffuseMaterial[4] = { 0.5, 0.5, 0.5, 1.0 };

//  初始化材质特性、光源、光照模型和深度缓冲
void init(void)
{
   GLfloat mat_specular[] = { 1.0, 1.0, 1.0, 1.0 };
   GLfloat light_position[] = { 1.0, 1.0, 1.0, 0.0 };

   glClearColor (0.0, 0.0, 0.0, 0.0);
   glShadeModel (GL_SMOOTH);
   glEnable(GL_DEPTH_TEST);
   glMaterialfv(GL_FRONT, GL_DIFFUSE, diffuseMaterial);
   glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
   glMaterialf(GL_FRONT, GL_SHININESS, 25.0);
   glLightfv(GL_LIGHT0, GL_POSITION, light_position);
   glEnable(GL_LIGHTING);
   glEnable(GL_LIGHT0);

   glColorMaterial(GL_FRONT, GL_DIFFUSE);
   glEnable(GL_COLOR_MATERIAL);
}

void display()
{
   glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
   glLoadIdentity();
   glTranslated(0,0,-4);
   glutSolidSphere(1.0, 32, 32);
   glutSwapBuffers();
}

void resize(int width, int height)
{
    float ar = (float) width / (float) height;
    glViewport(0, 0, width, height);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity() ;
    gluPerspective(45.0, ar, 1.0, 100.0);
    glMatrixMode(GL_MODELVIEW);
}

void normalKeys(unsigned char key, int x, int y)
{
switch (key)
{
  case '1':
    diffuseMaterial[0] += 0.1;
    if (diffuseMaterial[0] > 1.0)
      diffuseMaterial[0] = 0.0;
    break;
  case '2':
    diffuseMaterial[1] += 0.1;
    if (diffuseMaterial[1] > 1.0)
      diffuseMaterial[1] = 0.0;
    break;
  case '3':
    diffuseMaterial[2] += 0.1;
    if (diffuseMaterial[2] > 1.0)
      diffuseMaterial[2] = 0.0;
    break;
}
glColor4fv(diffuseMaterial);
glutPostRedisplay();
}

int main( int argc, char ** argv )
{
glutInit( &argc, argv );
glutInitDisplayMode( GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowPosition( 300, 200 );
glutInitWindowSize( 400, 400 );
glutCreateWindow( "OpenGL Examples!" );
init();
glutDisplayFunc( display );
glutReshapeFunc(resize);
glutKeyboardFunc(normalKeys);
glutMainLoop();
return 0;
}

实例2:

#include 
#include 

GLfloat nr=200.0;

void init(void)
{
   GLfloat ambient[] = { 0.0, 0.0, 0.0, 1.0 };
   GLfloat diffuse[] = { 1.0, 1.0, 1.0, 1.0 };
   GLfloat position[] = { 0.0, 3.0, 2.0, 0.0 };
   GLfloat lmodel_ambient[] = { 0.4, 0.4, 0.4, 1.0 };
   GLfloat local_view[] = { 0.0 };

   glClearColor(0.0, 0.1, 0.1, 0.0);
   glEnable(GL_DEPTH_TEST);
   glShadeModel(GL_SMOOTH);

   glLightfv(GL_LIGHT0, GL_AMBIENT, ambient);
   glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse);
   glLightfv(GL_LIGHT0, GL_POSITION, position);
   glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient);
   glLightModelfv(GL_LIGHT_MODEL_LOCAL_VIEWER, local_view);

   glEnable(GL_LIGHTING);
   glEnable(GL_LIGHT0);
}

void display(void)
{
   GLfloat no_mat[] = { 0.0, 0.0, 0.0, 1.0 };
   GLfloat mat_ambient[] = { 0.7, 0.7, 0.7, 1.0 };
   GLfloat mat_ambient_color[] = { 1.0, 0.0, 0.0, 1.0 };
   GLfloat mat_diffuse[] = { 0.1, 0.5, 0.8, 1.0 };
   GLfloat mat_specular[] = { 1.0, 1.0, 1.0, 1.0 };
   GLfloat no_shininess[] = { 0.0 };
   GLfloat low_shininess[] = { 5.0 };
   GLfloat high_shininess[] = { 200.0 };
   GLfloat mat_emission[] = {0.3, 0.2, 0.2, 0.0};

   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);


/*  draw sphere in first row, first column
 *  diffuse reflection only; no ambient or specular
 */
   glPushMatrix();
   glTranslatef (-3.75, 3.0, 0.0);
   glMaterialfv(GL_FRONT, GL_AMBIENT, no_mat);
   glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
   glMaterialfv(GL_FRONT, GL_SPECULAR, no_mat);
   glMaterialfv(GL_FRONT, GL_SHININESS, no_shininess);
   glMaterialfv(GL_FRONT, GL_EMISSION, no_mat);
   glutSolidSphere(1.0, nr, nr);
 //glutSolidTeapot(1.0);
   glPopMatrix();

/*  draw sphere in first row, second column
 *  diffuse and specular reflection; low shininess; no ambient
 */
   glPushMatrix();
   glTranslatef (-1.25, 3.0, 0.0);
   glMaterialfv(GL_FRONT, GL_AMBIENT, no_mat);
   glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
   glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
   glMaterialfv(GL_FRONT, GL_SHININESS, low_shininess);
   glMaterialfv(GL_FRONT, GL_EMISSION, no_mat);
   glutSolidSphere(1.0, nr, nr);
   glPopMatrix();

/*  draw sphere in first row, third column
 *  diffuse and specular reflection; high shininess; no ambient
 */
   glPushMatrix();
   glTranslatef (1.25, 3.0, 0.0);
   glMaterialfv(GL_FRONT, GL_AMBIENT, no_mat);
   glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
   glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
   glMaterialfv(GL_FRONT, GL_SHININESS, high_shininess);
   glMaterialfv(GL_FRONT, GL_EMISSION, no_mat);
   glutSolidSphere(1.0, nr, nr);
   glPopMatrix();

/*  draw sphere in first row, fourth column
 *  diffuse reflection; emission; no ambient or specular reflection
 */
   glPushMatrix();
   glTranslatef (3.75, 3.0, 0.0);
   glMaterialfv(GL_FRONT, GL_AMBIENT, no_mat);
   glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
   glMaterialfv(GL_FRONT, GL_SPECULAR, no_mat);
   glMaterialfv(GL_FRONT, GL_SHININESS, no_shininess);
   glMaterialfv(GL_FRONT, GL_EMISSION, mat_emission);
   glutSolidSphere(1.0, nr, nr);
   glPopMatrix();

/*  draw sphere in second row, first column
 *  ambient and diffuse reflection; no specular
 */
   glPushMatrix();
   glTranslatef (-3.75, 0.0, 0.0);
   glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient);
   glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
   glMaterialfv(GL_FRONT, GL_SPECULAR, no_mat);
   glMaterialfv(GL_FRONT, GL_SHININESS, no_shininess);
   glMaterialfv(GL_FRONT, GL_EMISSION, no_mat);
   glutSolidSphere(1.0, nr, nr);
   glPopMatrix();

/*  draw sphere in second row, second column
 *  ambient, diffuse and specular reflection; low shininess
 */
   glPushMatrix();
   glTranslatef (-1.25, 0.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, low_shininess);
   glMaterialfv(GL_FRONT, GL_EMISSION, no_mat);
   glutSolidSphere(1.0, nr, nr);
   glPopMatrix();

/*  draw sphere in second row, third column
 *  ambient, diffuse and specular reflection; high shininess
 */
   glPushMatrix();
   glTranslatef (1.25, 0.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, high_shininess);
   glMaterialfv(GL_FRONT, GL_EMISSION, no_mat);
   glutSolidSphere(1.0, nr, nr);
   glPopMatrix();

/*  draw sphere in second row, fourth column
 *  ambient and diffuse reflection; emission; no specular
 */
   glPushMatrix();
   glTranslatef (3.75, 0.0, 0.0);
   glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient);
   glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
   glMaterialfv(GL_FRONT, GL_SPECULAR, no_mat);
   glMaterialfv(GL_FRONT, GL_SHININESS, no_shininess);
   glMaterialfv(GL_FRONT, GL_EMISSION, mat_emission);
   glutSolidSphere(1.0, nr, nr);
   glPopMatrix();

/*  draw sphere in third row, first column
 *  colored ambient and diffuse reflection; no specular
 */
   glPushMatrix();
   glTranslatef (-3.75, -3.0, 0.0);
   glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient_color);
   glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
   glMaterialfv(GL_FRONT, GL_SPECULAR, no_mat);
   glMaterialfv(GL_FRONT, GL_SHININESS, no_shininess);
   glMaterialfv(GL_FRONT, GL_EMISSION, no_mat);
   glutSolidSphere(1.0, nr, nr);
   glPopMatrix();

/*  draw sphere in third row, second column
 *  colored ambient, diffuse and specular reflection; low shininess
 */
   glPushMatrix();
   glTranslatef (-1.25, -3.0, 0.0);
   glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient_color);
   glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
   glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
   glMaterialfv(GL_FRONT, GL_SHININESS, low_shininess);
   glMaterialfv(GL_FRONT, GL_EMISSION, no_mat);
   glutSolidSphere(1.0, nr, nr);
   glPopMatrix();

/*  draw sphere in third row, third column
 *  colored ambient, diffuse and specular reflection; high shininess
 */
   glPushMatrix();
   glTranslatef (1.25, -3.0, 0.0);
   glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient_color);
   glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
   glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
   glMaterialfv(GL_FRONT, GL_SHININESS, high_shininess);
   glMaterialfv(GL_FRONT, GL_EMISSION, no_mat);
   glutSolidSphere(1.0, nr, nr);
   glPopMatrix();

/*  draw sphere in third row, fourth column
 *  colored ambient and diffuse reflection; emission; no specular
 */
   glPushMatrix();
   glTranslatef (3.75, -3.0, 0.0);
   glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient_color);
   glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
   glMaterialfv(GL_FRONT, GL_SPECULAR, no_mat);
   glMaterialfv(GL_FRONT, GL_SHININESS, no_shininess);
   glMaterialfv(GL_FRONT, GL_EMISSION, mat_emission);
   glutSolidSphere(1.0, nr, nr);
   glPopMatrix();

   glutSwapBuffers();
}

void resize(int width, int height)
{
    float ar = (float) width / (float) height;
    glViewport(0, 0, width, height);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    //glFrustum(-ar, ar, -1.0, 1.0, 2.0, 100.0);
    glOrtho (-5, 5, -5, 5, -20.0, 20.0);
    glMatrixMode(GL_MODELVIEW);
}

int main(int argc, char** argv)
{
   glutInit( &argc, argv );
   glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
   glutInitWindowPosition( 300, 200 );
   glutInitWindowSize( 600, 600 );
   glutCreateWindow( "OpenGL Examples!" );
   init();
   glutDisplayFunc( display );
   glutReshapeFunc(resize);
   glutMainLoop();
return 0;

}

你可能感兴趣的:(基于图形之光照与材质)