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

0.颜色

a.颜色坐标系

颜色、光照、材料属性(openGL)_第1张图片

b.颜色设置与着色

void colortriangle()
{
	glClear(GL_COLOR_BUFFER_BIT);
	glShadeModel(GL_SMOOTH);
	glBegin(GL_TRIANGLES);
		/************************************颜色设置及着色**************************************************
			1、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之间。
			2、着色分为两种
				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();
} 

颜色、光照、材料属性(openGL)_第2张图片

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.光照

我们观察到的实物的颜色除了,实物本身的颜色外,还包括实物的材质和光照对观察的影响。

a.光照类型

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

环境光:

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

全局环境光栗子

//明亮的白光
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,参数

颜色、光照、材料属性(openGL)_第3张图片

//灰色的材料属性
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;
} 
颜色、光照、材料属性(openGL)_第4张图片 颜色、光照、材料属性(openGL)_第5张图片
b.综合栗子2------光照与法线设置:

#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;
} 


 
    

颜色、光照、材料属性(openGL)_第6张图片








你可能感兴趣的:(计算机图形学,图像处理,计算机视觉)