颜色、光照、材料属性(openGL)

0.颜色函数

a.颜色坐标系工具


b.颜色设置与着色oop

void colortriangle()
{
	glClear(GL_COLOR_BUFFER_BIT);
	glShadeModel(GL_SMOOTH);
	glBegin(GL_TRIANGLES);
		/************************************颜色设置及着色**************************************************
			一、void glColorXt(red, green, blue, alpha);
				其中x表明参数个数,能够是3个值表明rgb颜色,或者使4个值分别表明rgba。alpha成分用来表明透明度。
				t表明参数的类型,能够是b,d,f,i,s,ub,ui,us对应的类型是byte,double,float,integer,short,unsigned byte, unsigned integer,unsigned short。
				glColor3f指定各个颜色成分的强度值的范围为0.0到1.0之间。
				glColor3ub则能够指定各个颜色成分的强度值的范围在0-255之间。
			二、着色分为两种
				GL_FLAT:图元是点(画的是线什么的状况下),使用最后一个点的颜色做为线(其余图)颜色
				GL_SMOOTH:图元是点(画的是线什么的状况下),均衡,颜色渐变(两顶点间) 
		****************************************************************************************************/ 
		glColor3ub((GLubyte)255,(GLubyte)0,(GLubyte)0);							//ub:unsign byte
		glVertex3f(0.0f,100.0f,0.0f);
		glColor3ub((GLubyte)0,(GLubyte)255,(GLubyte)0);
		glVertex3f(100.0f,-35.0f,0.0f);
		glColor3ub((GLubyte)0,(GLubyte)0,(GLubyte)255);
		glVertex3f(-100.0f,-35.0f,0.0f);
	glEnd();
	glFlush();
}


c.看到的颜色是光照颜色和材料属性综合的结果性能

若光源颜色为( LR , LG , LB ),材质颜色为( MR , MG , MB ),最终颜色为( LR*MR , LG*MG , LB*MB )。(B1+B2)*MB )。所以,材料的颜色成分决定了入射光被反射的百分比。

栗子:光源颜色为(0.5, 0.5, 0.5),材料的颜色为(0.5, 1.0, 0.5)那么最终的颜色是(0.5*0.5, 0.5*1.0, 0.5*0.5) = (0.25, 0.5, 0.25) 。测试

1.光照ui

咱们观察到的实物的颜色除了,实物自己的颜色外,还包括实物的材质和光照对观察的影响。spa

a.光照类型3d

环境光、散射光、镜面光的强度都会衰减(这也是为何在设置光照的同事还要设置光照位置的一个缘由),只有发射光和全局环境光的强度没有衰减。code

环境光:orm

环境光没有特定的方向。环境光的光线充满着整个场景。场景中的物体都被环境光从各个方向照射着。环境光的特色是:照射在物体上的光来自周围各个方向,又均匀地向各个方向反射。

全局环境光栗子

//明亮的白光
GLfloat ambientLight[] = {1.0f, 1.0f, 1.0f, 1.0f};
//开启光照
glEnable(GL_LIGHTING);
//设置全局环境光为白光
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambientLight);

漫反射光:

漫放射光是一组来自特定方向,具备方向性的光。根据入射光线的角度在表面上均匀地向各个方向反射。漫反射的特色是:光源来自一个方向,反射光均匀地射向各个方向。漫反射光采用点光源照射物体。点光源是位于空间某个位置的一个点,向周围全部的方向上辐射等光强的光。在点光源的照射下,物体表面的不一样部分亮度不一样,亮度的大小依赖于它的朝向以及它与点光源之间的距离。

镜面光:

镜面光与漫反射光同样是具备方向性的。高强度的镜面光会在被照射的物体的表面上造成亮点。对于理想的高光泽度反射面,反射角等于入射角时,光线才会被反射,即只有在等于入射角的反射角方向上,观察者才能看到反射光。对于这种理想的反射面,镜面反射的光强要比环境光和漫反射的光强高出不少倍,这时,若是观察者正好处在P点的镜面反射方向上,就会看到一个比周围亮得多的高光点。

b.光照与法线

做用于定义:

物体的法线向量决定了它相对于光源的方向(区别于材料颜色属性定义时使用的多边形正面和反面;这个法线定义方向,是光照用的)。对于物体的每一个顶点,opengl使用法线判断这个顶点从每一个光源接受的光线数量。

为每一个顶点定义法线向量:

OpenGL中,既能够为每一个多边形只指定一条法线(多边形各顶点的法线方向相同),也能够为每一个多边形指定多条法线(多边形顶点的法线方向有不一样)。在OpenGL中,除了顶点以外,不能为多边形其余地方分配法线。

法线向量:

物体的法线向量定义了它的表面在空间中的朝向,即,定义了表面相对于光源的方向。由于OpenGL是使用法线向量来肯定一个物体表面的某个顶点所接受的光照的。若是不想使用OpenGL的光照功能,就能够免去为顶点指定法线向量这个步骤。GLUT工具库中某些模型的法线向量已经内部给定好啦,如glutWireCube()等,所绘制的模型各个顶点的法线向量已经系统给出了,又如绘制一个球Sphere等。

指定法线向量:

glNormal*()函数是把当前法线向量这个状态量设置为这个函数的参数所指示的向量值。后续顶点glVertex*()的法线向量将默认为此时法线向量状态量所保存的向量值。一般,顶点常具备不一样的法线向量,所以常须要交替调用这两个函数。

在一个表面的顶点上,将会有两条向量垂直于这个表面,这两条向量指向相反的方向,而指向外侧的向量才为当前表面的法线向量。法线向量只表示方向,不表示大小(即与长度无关)。理论上能够为顶点指定任意大小的法线向量,但在OpenGL执行光照操做时,会将顶点的法线向量规范化(单位化),而这样必然会下降程序的性能,因此通常应由咱们本身提供各个顶点的规范化法线向量。
若是只是对模型进行移动、旋转操做,法线向量的长度将不会发生变化,而若是对模型进行缩放操做,长度则将变化。若是须要OpenGL对法线向量进行规范化,就须要启用这个功能,glEnable(GL_NORMALIZE),默认这个功能是关闭的。
若是所进行的缩放是均匀缩放,则可使用glEnable(GL_RESCALE_NORMAL),这样性能相比较GL_NORMALIZE更优。默认状况下,GL_RESCALE_NORMAL也是被禁用的。

2.材料

a.材料属性

当咱们使用光照时,咱们经过材料的反射属性来描述它的颜色,咱们为三种光源指定材料相应的反射属性。一个材料可能会很好的反射镜面光,却吸取了大多数的漫反射和环境光。

b.材料的属性设置

1)在指定的多边形前调用glMaterial函数。

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

参数:face:正面仍是反面应用材料属性设置;pname:材料属性;param,参数


//灰色的材料属性
GLfloat gray[] = {0.75f, 0.75f, 0.75f, 1.0f};

glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, gray);
glBegin(GL_TRIANGLES);
    glVertex3f(-15.0f, 0.0f, 30.0f);
    glVertex3f(0.0f, 15.0f, 30.0f);
    glVertex3f(0.0f, 0.0f, -56.0f);
glEnd();
2)材料的颜色追踪

开启GL_COLOR_MATERIAL;设置追踪面和追踪的材料属性glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);;以后就能够经过glColor来设置颜色了

//开启颜色追踪
glEnable(GL_COLOR_MATERIAL);
//设置颜色追踪的材料属性以及多边形的面
glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);

//设置颜色
glColor3f(0.75f, 0.75f, 0.75f);
glBegin(GL_TRIANGLES);
    glVertex3f(-15.0f, 0.0f, 30.0f);
    glVertex3f(0.0f, 15.0f, 30.0f);
    glVertex3f(0.0f, 0.0f, -56.0f);
glEnd();
3.综合栗子

a.综合栗子1-----材料颜色属性:

#include "grapg.h"

static GLfloat xRot=0.0f;
static GLfloat yRot=0.0f;
void setuprc_000()
{
	GLfloat ambientLight[]={0.5f,0.5f,0.5f,1.0f};
	glEnable(GL_DEPTH_TEST);													//开启深度测试 
	glEnable(GL_CULL_FACE);														//开启隐藏面,由于后面设置了材料的颜色追踪,只追踪正面,因此要先剔除反面,在把反面用正面的方式画上去 
	glFrontFace(GL_CCW);														//设置逆时针为正面
	
	glEnable(GL_COLOR_MATERIAL);												//开启材料的颜色追踪
	glEnable(GL_LIGHTING);														//开启光照
	glLightModelfv(GL_LIGHT_MODEL_AMBIENT,ambientLight);						//设置全局环境光
	glColorMaterial(GL_FRONT,GL_AMBIENT_AND_DIFFUSE);							//设置材料的颜色追踪 
	
	glClearColor(0.0f,0.0f,0.0f,1.0f); 
}

void aircraft()
{	
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	glPushMatrix();
		glRotatef(xRot, 1.0f, 0.0f, 0.0f);
    	glRotatef(yRot, 0.0f, 1.0f, 0.0f);

    	glBegin(GL_TRIANGLES);
    	//机头
    		glColor3f(1.0f, 1.0f, 1.0f);
      		glVertex3f(-15.0f, 0.0f, 30.0f);
      		glVertex3f(15.0f, 0.0f, 30.0f);
      		glVertex3f(0.0f, 0.0f, 60.0f);

      		glColor3f(0.0f, 0.0f, 0.0f);
      		glVertex3f(-15.0f, 0.0f, 30.0f);
      		glVertex3f(0.0f, 0.0f, 60.0f);
      		glVertex3f(0.0f, 15.0f, 30.0f);

      		glColor3f(1.0f, 0.0f, 0.0f);
      		glVertex3f(0.0f, 0.0f, 60.0f);
      		glVertex3f(15.0f, 0.0f, 30.0f);
      		glVertex3f(0.0f, 15.0f, 30.0f);
      //机身
      		glColor3f(0.0f, 1.0f, 0.0f);
      		glVertex3f(-15.0f, 0.0f, 30.0f);
      		glVertex3f(0.0f, 15.0f, 30.0f);
      		glVertex3f(0.0f, 0.0f, -53.0f);

      		glColor3f(1.0f, 1.0f, 0.0f);
      		glVertex3f(0.0f, 15.0f, 30.0f);
      		glVertex3f(15.0f, 0.0f, 30.0f);
      		glVertex3f(0.0f, 0.0f, -53.0f);

      		glColor3f(0.5f, 0.5f, 0.3f);
      		glVertex3f(15.0f, 0.0f, 30.0f);
      		glVertex3f(-15.0f, 0.0f, 30.0f);
      		glVertex3f(0.0f, 0.0f, -53.0f);

      //机尾巴
      		glColor3f(0.3f, 1.0f, 0.2f);
      		glVertex3f(0.0f, 0.0f, -53.0f);
      		glVertex3f(0.0f, 0.0f, -70.0f);
      		glVertex3f(0.0f, 15.0f, -70.0f);

      		glColor3f(0.7f, 0.5f, 0.3f);
      		glVertex3f(-15.0f, 0.0f, -70.0f);
      		glVertex3f(0.0f, 0.0f, -53.0f);
      		glVertex3f(0.0f, 0.0f, -70.0f);

      		glColor3f(0.2f, 0.2f, 0.8f);
      		glVertex3f(15.0f, 0.0f, -70.0f);
      		glVertex3f(0.0f, 0.0f, -70.0f);
      		glVertex3f(0.0f, 0.0f, -53.0f);

      //因为背面被消除,背面再画一次
      		glColor3f(0.3f, 1.0f, 0.2f);
      		glVertex3f(0.0f, 0.0f, -70.0f);
      		glVertex3f(0.0f, 0.0f, -53.0f);
      		glVertex3f(0.0f, 15.0f, -70.0f);
      
      		glColor3f(0.7f, 0.5f, 0.3f);
      		glVertex3f(0.0f, 0.0f, -53.0f);
      		glVertex3f(-15.0f, 0.0f, -70.0f);
      		glVertex3f(0.0f, 0.0f, -70.0f);

      		glColor3f(0.2f, 0.2f, 0.8f);
      		glVertex3f(0.0f, 0.0f, -70.0f);
      		glVertex3f(15.0f, 0.0f, -70.0f);
      		glVertex3f(0.0f, 0.0f, -53.0f);

      // 左翼 
      		glColor3ub(128,128,128);
      		glVertex3f(0.0f,2.0f,27.0f);
      		glVertex3f(-60.0f, 2.0f, -8.0f);
      		glVertex3f(60.0f, 2.0f, -8.0f);

      		glColor3ub(64,64,64);
      		glVertex3f(60.0f, 2.0f, -8.0f);
      		glVertex3f(0.0f, 7.0f, -8.0f);
      		glVertex3f(0.0f,2.0f,27.0f);

      		glColor3ub(192,192,192);
      		glVertex3f(60.0f, 2.0f, -8.0f);
      		glVertex3f(-60.0f, 2.0f, -8.0f);
      		glVertex3f(0.0f,7.0f,-8.0f);

      //右翼 
      		glColor3ub(64,64,64);
      		glVertex3f(0.0f,2.0f,27.0f);
      		glVertex3f(0.0f, 7.0f, -8.0f);
      		glVertex3f(-60.0f, 2.0f, -8.0f);
    	glEnd();
  	glPopMatrix();
  	glutSwapBuffers();	
}

void specialkeys(int key,int x,int y)
{
	if(key == GLUT_KEY_UP)
    	xRot-= 5.0f;
	if(key == GLUT_KEY_DOWN)
    	xRot += 5.0f;
	if(key == GLUT_KEY_LEFT)
    	yRot -= 5.0f;
	if(key == GLUT_KEY_RIGHT)
    	yRot += 5.0f;
  	if(key > 356.0f)
    	xRot = 0.0f;
  	if(key < -1.0f)
    	xRot = 355.0f;
  	if(key > 356.0f)
    	yRot = 0.0f;
	if(key < -1.0f)
    	yRot = 355.0f;
	glutPostRedisplay();//标记重绘 
} 

void reshape(int w,int h)						
{								
	GLfloat nRange = 100.0f; 
 	if (h == 0)   
 	{ 
	 	h = 1; 
 	}
 	glViewport(0, 0, w, h);
 	glMatrixMode(GL_PROJECTION);												//设置当前矩阵为投影矩阵  
	glLoadIdentity();															//将当前用户坐标系重置   
	GLfloat aspect = (GLfloat)w/(GLfloat)h; 
	if (w<=h)																	//设置投影    
	{ 
		glOrtho(-nRange, nRange, -nRange/aspect, nRange/aspect, -nRange, nRange);//参数为:x轴左、右;y轴下、上;z轴里、外 
	} 
	else 
	{
		glOrtho(-nRange*aspect, nRange*aspect, -nRange, nRange, -nRange, nRange);//从新定义了裁剪区域,但保持纵横比不变 
	}
	glMatrixMode(GL_MODELVIEW);													 //将当前矩阵设置为模型视图矩阵 
	glLoadIdentity(); 
}

int main_light_material()
{
  glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
  glutInitWindowSize(800,600);
  glutCreateWindow("test");
  glutReshapeFunc(reshape);
  glutSpecialFunc(specialkeys);
  glutDisplayFunc(aircraft);
  setuprc_000();
  glutMainLoop();
  return 0;
}
b.综合栗子2------光照与法线设置:

<pre name="code" class="cpp">#include "grapg.h"
static GLfloat xRot=0.0f;
static GLfloat yRot=0.0f;
void countnormal(GLfloat normal[],GLfloat p1[],GLfloat p2[],GLfloat p3[])		//叉乘计算平面法线向量 
{
	GLfloat v1[]={0.0f,0.0f,0.0f};
	GLfloat v2[]={0.0f,0.0f,0.0f};	
	v1[0]=p2[0]-p1[0];
	v1[1]=p2[1]-p1[1];
	v1[2]=p2[2]-p1[2];
	v2[0]=p3[0]-p1[0];
	v2[1]=p3[1]-p1[1];
	v2[2]=p3[2]-p1[2];
	normal[0]=v1[1]*v2[2]-v1[2]*v2[1];
	normal[1]=v1[2]*v2[0]-v1[0]*v2[2];
	normal[2]=v1[0]*v2[1]-v1[1]*v2[0];
}
void aircraft_001()
{
	GLfloat normal[]={0.0f,0.0f,0.0f};
	GLfloat p1[]={0.0f,0.0f,0.0f};
	GLfloat p2[]={0.0f,0.0f,0.0f};
	GLfloat p3[]={0.0f,0.0f,0.0f};

	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	glPushMatrix();
		glRotatef(xRot, 1.0f, 0.0f, 0.0f);
    	glRotatef(yRot, 0.0f, 1.0f, 0.0f);
		glColor3ub(128,128,128);
    	glBegin(GL_TRIANGLES);
    	//机头
    		p1[0]=-15.0f;p1[1]=0.0f;p1[2]=30.0f;
    		p2[0]=15.0f;p2[1]=0.0f;p2[2]=30.0f;
    		p3[0]=0.0f;p3[1]=0.0f;p3[2]=60.0f;
    		countnormal(normal,p1,p2,p3);
    		glNormal3f(normal[0],normal[1],normal[2]);							//由于此处均是三角形,为平面,因此指定一个法线向量就行 
      		glVertex3f(p1[0],p1[1],p1[2]);
      		glVertex3f(p2[0],p2[1],p2[2]);
      		glVertex3f(p3[0],p3[1],p3[2]);

      		p1[0]=-15.0f;p1[1]=0.0f;p1[2]=30.0f;
    		p2[0]=0.0f;p2[1]=0.0f;p2[2]=60.0f;
    		p3[0]=0.0f;p3[1]=15.0f;p3[2]=30.0f;
    		countnormal(normal,p1,p2,p3);
    		glNormal3f(normal[0],normal[1],normal[2]);
      		glVertex3f(p1[0],p1[1],p1[2]);
      		glVertex3f(p2[0],p2[1],p2[2]);
      		glVertex3f(p3[0],p3[1],p3[2]);

      		p1[0]=0.0f;p1[1]=0.0f;p1[2]=60.0f;
    		p2[0]=15.0f;p2[1]=0.0f;p2[2]=30.0f;
    		p3[0]=0.0f;p3[1]=15.0f;p3[2]=30.0f;
    		countnormal(normal,p1,p2,p3);
    		glNormal3f(normal[0],normal[1],normal[2]);
      		glVertex3f(p1[0],p1[1],p1[2]);
      		glVertex3f(p2[0],p2[1],p2[2]);
      		glVertex3f(p3[0],p3[1],p3[2]);
      //机身
      		p1[0]=-15.0f;p1[1]=0.0f;p1[2]=30.0f;
    		p2[0]=0.0f;p2[1]=15.0f;p2[2]=30.0f;
    		p3[0]=0.0f;p3[1]=0.0f;p3[2]=-53.0f;
    		countnormal(normal,p1,p2,p3);
    		glNormal3f(normal[0],normal[1],normal[2]);
      		glVertex3f(p1[0],p1[1],p1[2]);
      		glVertex3f(p2[0],p2[1],p2[2]);
      		glVertex3f(p3[0],p3[1],p3[2]);

      		p1[0]=0.0f;p1[1]=15.0f;p1[2]=30.0f;
    		p2[0]=15.0f;p2[1]=0.0f;p2[2]=30.0f;
    		p3[0]=0.0f;p3[1]=0.0f;p3[2]=-53.0f;
    		countnormal(normal,p1,p2,p3);
    		glNormal3f(normal[0],normal[1],normal[2]);
      		glVertex3f(p1[0],p1[1],p1[2]);
      		glVertex3f(p2[0],p2[1],p2[2]);
      		glVertex3f(p3[0],p3[1],p3[2]);

      		p1[0]=15.0f;p1[1]=0.0f;p1[2]=30.0f;
    		p2[0]=-15.0f;p2[1]=0.0f;p2[2]=30.0f;
    		p3[0]=0.0f;p3[1]=0.0f;p3[2]=-53.0f;
    		countnormal(normal,p1,p2,p3);
    		glNormal3f(normal[0],normal[1],normal[2]);
      		glVertex3f(p1[0],p1[1],p1[2]);
      		glVertex3f(p2[0],p2[1],p2[2]);
      		glVertex3f(p3[0],p3[1],p3[2]);

      //机尾巴
      		p1[0]=0.0f;p1[1]=0.0f;p1[2]=-53.0f;
    		p2[0]=0.0f;p2[1]=0.0f;p2[2]=-70.0f;
    		p3[0]=0.0f;p3[1]=15.0f;p3[2]=-70.0f;
    		countnormal(normal,p1,p2,p3);
    		glNormal3f(normal[0],normal[1],normal[2]);
      		glVertex3f(p1[0],p1[1],p1[2]);
      		glVertex3f(p2[0],p2[1],p2[2]);
      		glVertex3f(p3[0],p3[1],p3[2]);

      		p1[0]=-15.0f;p1[1]=0.0f;p1[2]=-70.0f;
    		p2[0]=0.0f;p2[1]=0.0f;p2[2]=-53.0f;
    		p3[0]=0.0f;p3[1]=0.0f;p3[2]=-70.0f;
    		countnormal(normal,p1,p2,p3);
    		glNormal3f(normal[0],normal[1],normal[2]);
      		glVertex3f(p1[0],p1[1],p1[2]);
      		glVertex3f(p2[0],p2[1],p2[2]);
      		glVertex3f(p3[0],p3[1],p3[2]);

      		p1[0]=15.0f;p1[1]=0.0f;p1[2]=-70.0f;
    		p2[0]=0.0f;p2[1]=0.0f;p2[2]=-70.0f;
    		p3[0]=0.0f;p3[1]=0.0f;p3[2]=-53.0f;
    		countnormal(normal,p1,p2,p3);
    		glNormal3f(normal[0],normal[1],normal[2]);
      		glVertex3f(p1[0],p1[1],p1[2]);
      		glVertex3f(p2[0],p2[1],p2[2]);
      		glVertex3f(p3[0],p3[1],p3[2]);

      //因为背面被消除,背面再画一次
      		p1[0]=0.0f;p1[1]=0.0f;p1[2]=-70.0f;
    		p2[0]=0.0f;p2[1]=0.0f;p2[2]=-53.0f;
    		p3[0]=0.0f;p3[1]=15.0f;p3[2]=-70.0f;
    		countnormal(normal,p1,p2,p3);
    		glNormal3f(normal[0],normal[1],normal[2]);
      		glVertex3f(p1[0],p1[1],p1[2]);
      		glVertex3f(p2[0],p2[1],p2[2]);
      		glVertex3f(p3[0],p3[1],p3[2]);
      
      		p1[0]=0.0f;p1[1]=0.0f;p1[2]=-53.0f;
    		p2[0]=-15.0f;p2[1]=0.0f;p2[2]=-70.0f;
    		p3[0]=0.0f;p3[1]=0.0f;p3[2]=-70.0f;
    		countnormal(normal,p1,p2,p3);
    		glNormal3f(normal[0],normal[1],normal[2]);
      		glVertex3f(p1[0],p1[1],p1[2]);
      		glVertex3f(p2[0],p2[1],p2[2]);
      		glVertex3f(p3[0],p3[1],p3[2]);

      		p1[0]=0.0f;p1[1]=0.0f;p1[2]=-70.0f;
    		p2[0]=15.0f;p2[1]=0.0f;p2[2]=-70.0f;
    		p3[0]=0.0f;p3[1]=0.0f;p3[2]=-53.0f;
    		countnormal(normal,p1,p2,p3);
    		glNormal3f(normal[0],normal[1],normal[2]);
      		glVertex3f(p1[0],p1[1],p1[2]);
      		glVertex3f(p2[0],p2[1],p2[2]);
      		glVertex3f(p3[0],p3[1],p3[2]);

      // 左翼 
      		p1[0]=0.0f;p1[1]=2.0f;p1[2]=27.0f;
    		p2[0]=-60.0f;p2[1]=2.0f;p2[2]=-8.0f;
    		p3[0]=60.0f;p3[1]=2.0f;p3[2]=-8.0f;
    		countnormal(normal,p1,p2,p3);
    		glNormal3f(normal[0],normal[1],normal[2]);
      		glVertex3f(p1[0],p1[1],p1[2]);
      		glVertex3f(p2[0],p2[1],p2[2]);
      		glVertex3f(p3[0],p3[1],p3[2]);

      		p1[0]=60.0f;p1[1]=2.0f;p1[2]=-8.0f;
    		p2[0]=0.0f;p2[1]=7.0f;p2[2]=-8.0f;
    		p3[0]=0.0f;p3[1]=2.0f;p3[2]=27.0f;
    		countnormal(normal,p1,p2,p3);
    		glNormal3f(normal[0],normal[1],normal[2]);
      		glVertex3f(p1[0],p1[1],p1[2]);
      		glVertex3f(p2[0],p2[1],p2[2]);
      		glVertex3f(p3[0],p3[1],p3[2]);

      		p1[0]=60.0f;p1[1]=2.0f;p1[2]=-8.0f;
    		p2[0]=-60.0f;p2[1]=2.0f;p2[2]=-8.0f;
    		p3[0]=0.0f;p3[1]=7.0f;p3[2]=-8.0f;
    		countnormal(normal,p1,p2,p3);
    		glNormal3f(normal[0],normal[1],normal[2]);
      		glVertex3f(p1[0],p1[1],p1[2]);
      		glVertex3f(p2[0],p2[1],p2[2]);
      		glVertex3f(p3[0],p3[1],p3[2]);
      //右翼 
      		p1[0]=0.0f;p1[1]=2.0f;p1[2]=27.0f;
    		p2[0]=0.0f;p2[1]=7.0f;p2[2]=-8.0f;
    		p3[0]=-60.0f;p3[1]=2.0f;p3[2]=-8.0f;
    		countnormal(normal,p1,p2,p3);
    		glNormal3f(normal[0],normal[1],normal[2]);
      		glVertex3f(p1[0],p1[1],p1[2]);
      		glVertex3f(p2[0],p2[1],p2[2]);
      		glVertex3f(p3[0],p3[1],p3[2]);
      		glVertex3f(0.0f,2.0f,27.0f);
      		glVertex3f(0.0f, 7.0f, -8.0f);
      		glVertex3f(-60.0f, 2.0f, -8.0f);
    	glEnd();
  	glPopMatrix();
  	glutSwapBuffers();	
}

void setuprc_001()
{
	GLfloat ambientLight[]={0.3f,0.3f,0.3f,1.0f};								//环境光rgba
	GLfloat diffuseLight[]={0.7f,0.7f,0.7f,1.0f};								//漫射光 
	GLfloat specular[]={1.0f,1.0f,1.0f,1.0f};
	glEnable(GL_DEPTH_TEST);													//开启深度测试 
	glEnable(GL_CULL_FACE);														//开启隐藏面,由于后面设置了材料的颜色追踪,只追踪正面,因此要先剔除反面,在把反面用正面的方式画上去 
	glFrontFace(GL_CCW);														//设置逆时针为正面
	
	glEnable(GL_LIGHTING);														//开启光照
	glLightfv(GL_LIGHT0,GL_AMBIENT,ambientLight);								//设置光照 
	glLightfv(GL_LIGHT0,GL_DIFFUSE,diffuseLight);
	glLightfv(GL_LIGHT0,GL_SPECULAR,specular);
	glEnable(GL_LIGHT0);
	
	GLfloat specref[]={1.0f,1.0f,1.0f,1.0f};
	glEnable(GL_COLOR_MATERIAL);
	glColorMaterial(GL_FRONT,GL_AMBIENT_AND_DIFFUSE);							//设置材料的颜色追踪 
	glMaterialfv(GL_FRONT,GL_SPECULAR,specref);
	//GL_SHININESS属性。该属性只有一个值,称为“镜面指数”,取值范围是0到128。
	//该值越小,表示材质越粗糙,点光源发射的光线照射到上面,也能够产生较大的亮点。
	//该值越大,表示材质越相似于镜面,光源照射到上面后,产生较小的亮点。
	glMateriali(GL_FRONT,GL_SHININESS,128);
	
	glClearColor(0.0f,0.0f,1.0f,1.0f); 
	glEnable(GL_NORMALIZE);														//开启自动标准化法线向量 
}

void specialkeys_001(int key,int x,int y)
{
	if(key == GLUT_KEY_UP)
    	xRot-= 5.0f;
	if(key == GLUT_KEY_DOWN)
    	xRot += 5.0f;
	if(key == GLUT_KEY_LEFT)
    	yRot -= 5.0f;
	if(key == GLUT_KEY_RIGHT)
    	yRot += 5.0f;
  	if(key > 356.0f)
    	xRot = 0.0f;
  	if(key < -1.0f)
    	xRot = 355.0f;
  	if(key > 356.0f)
    	yRot = 0.0f;
	if(key < -1.0f)
    	yRot = 355.0f;
	glutPostRedisplay();														//标记重绘 
} 

void reshape_001(int w,int h)						
{								
	GLfloat faspect;
	GLfloat lightPos[] = { -50.f, 50.0f, 100.0f, 1.0f };
	if(h == 0)
    	h = 1;
  	glViewport(0, 0, w, h);														//视口大小设置 
  	glMatrixMode(GL_PROJECTION);												//设置投影 
  	glLoadIdentity();
 	faspect = (GLfloat) w / (GLfloat) h;
  	gluPerspective(45.0f, faspect, 1.0f, 225.0f);

  	glMatrixMode(GL_MODELVIEW);
  	glLoadIdentity();

  	glLightfv(GL_LIGHT0,GL_POSITION,lightPos);									//设置光源位置 
  	glTranslatef(0.0f, 0.0f, -150.0f);
}

int main_light_material()
{
  glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
  glutInitWindowSize(800,600);
  glutCreateWindow("test");
  glutReshapeFunc(reshape_001);
  glutSpecialFunc(specialkeys_001);
  glutDisplayFunc(aircraft_001);
  setuprc_001();
  glutMainLoop();
  return 0;
}