opengl消隐与光照

1.      设置材料的颜色

OpenGL的光照模型根据材料反射的红、绿和蓝光的比例来模拟它的颜色。和光一样,材料也具有不同的环境、散射和镜面颜色,它们决定了材料对红、绿和蓝光的反射率。材料的环境反射属性与每种入射光的环境光成分组合,散射反射属性与入射光的散射成分组合,镜面反射属性和入射光的镜面成分组合。环境和散射属性定义了材料的颜色,它们一般很相似。

              使用的函数是glMaterial*():

void glMaterial{if} (GLenumface, GLenumpname, GLfloatparam);

void glMaterial{if}v (GLenumface, GLenumpname, constGLfloat *params);

       face可以是GL_FRONT,GL_BACK或GL_FRONT_AND BACK,表示物体的哪些面应该接受光照。pname表示设置的特定材料属性。param提供了具体的属性值。

       我们设置桌面和四条桌腿的材料如下:

void Draw_Table() // This function draws a triangle with RGB colors

{

    //定义变量

    GLfloat specular[] = { 0.6f,0.6f,0.6f,1.0f };

    GLfloat color1[] = { 0.85f,0.65f,0.2f,1.0f };//金黄色

    GLfloat color2[] = { 1.0f,0.0f,0.0f };

    GLfloat color3[] = { 0.0f,1.0f,0.0f };

    GLfloat color4[] = { 1.0f,1.0f,0.0f };

    GLfloat color5[] = { 0.0f,1.0f,1.0f };

    GLfloat color6[] = { 0.0f,0.0f,1.0f };

    //茶壶

    glPushMatrix();

    glMaterialfv(GL_FRONT, GL_SPECULAR, specular);//设置镜面颜色

    glMateriali(GL_FRONT, GL_SHININESS, 50);//设置镜面指数

    glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, color1);//材料的环境和散射颜色

    glTranslatef(0, 0, 4+1);

    glRotatef(90, 1, 0, 0);

    glutSolidTeapot(1);

    glPopMatrix();

    //桌面

    glPushMatrix();

    glMaterialfv(GL_FRONT, GL_SPECULAR, color2);//设置镜面颜色

    glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, color2);//材料的环境和散射颜色

    glTranslatef(0, 0, 3.5);

    glScalef(5, 4, 1);

    glutSolidCube(1.0);

    glPopMatrix();

    //四条腿

    glPushMatrix();

    glMaterialfv(GL_FRONT, GL_SPECULAR, color3);//设置镜面颜色

    glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, color3);//材料的环境和散射颜色

    glTranslatef(1.5, 1, 1.5);

    Draw_Leg();

    glPopMatrix();

 

    glPushMatrix();

    glMaterialfv(GL_FRONT, GL_SPECULAR, color4);//设置镜面颜色

    glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, color4);//材料的环境和散射颜色

    glTranslatef(-1.5, 1, 1.5);

    Draw_Leg();

    glPopMatrix();

 

    glPushMatrix();

    glMaterialfv(GL_FRONT, GL_SPECULAR, color5);//设置镜面颜色

    glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, color5);//材料的环境和散射颜色

    glTranslatef(1.5, -1, 1.5);

    Draw_Leg();

    glPopMatrix();

 

    glPushMatrix();

    glMaterialfv(GL_FRONT, GL_SPECULAR, color6);//设置镜面颜色

    glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, color6);//材料的环境和散射颜色

    glTranslatef(-1.5, -1, 1.5);

    Draw_Leg();

    glPopMatrix();

}

 

2.      光源位置及颜色设置

首先使用定义全局变量来控制光源的颜色和位置:

bool light_flag = false;//环境光颜色

GLfloat color[] = { 1.0, 1.0, 1.0, 1.0 }; // 定义颜色  

//环境光位置

GLfloat light_x = 0.0f;

GLfloat light_y = 0.0f;

GLfloat light_z = 0.0f;

              在redraw函数中对光源进行设置:

GLfloat white[] = { 1.0, 1.0, 1.0, 1.0 };//定义环境光颜色:白色

GLfloat light_pos[] = { 5.0 + light_x,5.0 + light_y,5.0 + light_z,1 };

//是否改变光照颜色

    if (light_flag)

        color[1] = color[3] = 0.0f;

    else

        color[1] = color[3] = 1.0f;

glLightfv(GL_LIGHT0, GL_POSITION, light_pos);//0号光源的位置

    glLightfv(GL_LIGHT0, GL_SMOOTH, white);//设置环境光颜色

    glLightfv(GL_LIGHT0, GL_DIFFUSE, white);                     //设置漫射光成分 

    glLightfv(GL_LIGHT0, GL_AMBIENT, color);   //设置第0号光源多次反射后的光照颜色(环境光颜色)

    glEnable(GL_LIGHT0);//开启0号光源

 

3.      聚光灯

可以对位置性光源的形状加以限制,使它的发射范围限于一个椎体之内,就像一个聚光灯一样。为了创建聚光灯,需要确定光锥的发射范围。为了指定光锥轴和光锥边缘之间的角度,可以使用GL_SPOT_CUTOFF参数。光锥的最大角度是这个值的两倍。

定义全局变量控制聚光灯方向和照射角度:

//聚光灯

GLfloat spot_x = 0.0f;

GLfloat spot_y = 0.0f;

GLfloat spot_z = 0.0f;

GLfloat Angle = 5.0f;//聚光灯角度

              在redraw中设置聚光灯位置、颜色以及角度等等:

glLightfv(GL_LIGHT1, GL_AMBIENT, color);    //设置环境光成分

    glLightfv(GL_LIGHT1, GL_SPECULAR, white);                 //设置镜面光成分

    glLightfv(GL_LIGHT1, GL_DIFFUSE, white);                     //设置漫射光成分

 

    glLightfv(GL_LIGHT1, GL_POSITION, spot_pos);

    glLightf(GL_LIGHT1, GL_SPOT_CUTOFF, Angle);            //裁减角度

    glLightfv(GL_LIGHT1, GL_SPOT_DIRECTION, spot_angle);          //光源方向

    glLightf(GL_LIGHT1, GL_SPOT_EXPONENT, 2.);                    //聚集度

    glEnable(GL_LIGHT1);//开启1号光源


实验结果与分析:

opengl消隐与光照_第1张图片opengl消隐与光照_第2张图片opengl消隐与光照_第3张图片


main.cpp

// glutEx1.cpp : 定义控制台应用程序的入口点。
//


#include 
#include "glut.h"

float fTranslate;
float fRotate;
float fScale     = 1.0f;	// set inital scale value to 1.0f

bool bPersp = false;
bool bAnim = false;
bool bWire = false;
bool light_flag = false;//环境光颜色
GLfloat color[] = { 1.0, 1.0, 1.0, 1.0 }; // 定义颜色   
int wHeight = 0;
int wWidth = 0;
//环境光
GLfloat light_x = 0.0f;
GLfloat light_y = 0.0f;
GLfloat light_z = 0.0f;
//聚光灯
GLfloat spot_x = 0.0f;
GLfloat spot_y = 0.0f;
GLfloat spot_z = 0.0f;
GLfloat Angle = 5.0f;//聚光灯角度
void Draw_Leg();

void Draw_Table() // This function draws a triangle with RGB colors
{
	//定义变量
	GLfloat specular[] = { 0.6f,0.6f,0.6f,1.0f };
	GLfloat color1[] = { 0.85f,0.65f,0.2f,1.0f };//金黄色
	GLfloat color2[] = { 1.0f,0.0f,0.0f };
	GLfloat color3[] = { 0.0f,1.0f,0.0f };
	GLfloat color4[] = { 1.0f,1.0f,0.0f };
	GLfloat color5[] = { 0.0f,1.0f,1.0f };
	GLfloat color6[] = { 0.0f,0.0f,1.0f };
	//茶壶
	glPushMatrix();
	glMaterialfv(GL_FRONT, GL_SPECULAR, specular);//设置镜面颜色
	glMateriali(GL_FRONT, GL_SHININESS, 50);//设置镜面指数
	glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, color1);//材料的环境和散射颜色
	glTranslatef(0, 0, 4+1);
	glRotatef(90, 1, 0, 0);
	glutSolidTeapot(1);
	glPopMatrix();
	//桌面
	glPushMatrix();
	glMaterialfv(GL_FRONT, GL_SPECULAR, color2);//设置镜面颜色
	glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, color2);//材料的环境和散射颜色
	glTranslatef(0, 0, 3.5);
	glScalef(5, 4, 1);
	glutSolidCube(1.0);
	glPopMatrix();
	//四条腿
	glPushMatrix();
	glMaterialfv(GL_FRONT, GL_SPECULAR, color3);//设置镜面颜色
	glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, color3);//材料的环境和散射颜色
	glTranslatef(1.5, 1, 1.5);
	Draw_Leg();
	glPopMatrix();

	glPushMatrix();
	glMaterialfv(GL_FRONT, GL_SPECULAR, color4);//设置镜面颜色
	glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, color4);//材料的环境和散射颜色
	glTranslatef(-1.5, 1, 1.5);
	Draw_Leg();
	glPopMatrix();

	glPushMatrix();
	glMaterialfv(GL_FRONT, GL_SPECULAR, color5);//设置镜面颜色
	glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, color5);//材料的环境和散射颜色
	glTranslatef(1.5, -1, 1.5);
	Draw_Leg();
	glPopMatrix();

	glPushMatrix();
	glMaterialfv(GL_FRONT, GL_SPECULAR, color6);//设置镜面颜色
	glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, color6);//材料的环境和散射颜色
	glTranslatef(-1.5, -1, 1.5);
	Draw_Leg();
	glPopMatrix();

}

void Draw_Leg()
{
	glScalef(1, 1, 3);
	glutSolidCube(1.0);
}

void updateView(int width, int height)
{
	glViewport(0,0,width,height);						// Reset The Current Viewport

	glMatrixMode(GL_PROJECTION);						// Select The Projection Matrix
	glLoadIdentity();									// Reset The Projection Matrix

	float whRatio = (GLfloat)width/(GLfloat)height;
	if (bPersp) {
		gluPerspective(45.0f, whRatio,0.1f,100.0f);
		//glFrustum(-3, 3, -3, 3, 3,100);
	} else {
		glOrtho(-3 ,3, -3, 3,-100,100);
	}

	glMatrixMode(GL_MODELVIEW);							// Select The Modelview Matrix
}

void reshape(int width, int height)
{
	if (height==0)										// Prevent A Divide By Zero By
	{
		height=1;										// Making Height Equal One
	}

	wHeight = height;
	wWidth = width;

	updateView(wHeight, wWidth);
}

void idle()
{
	glutPostRedisplay();
}

float eye[] = {0, 0, 8};
float center[] = {0, 0, 0};

void key(unsigned char k, int x, int y)
{
	switch(k)
	{
	case 27://ESC
	case 'q': {exit(0); break; }//quit
	case 'p': {bPersp = !bPersp; break; }//显示模式

	case ' ': {bAnim = !bAnim; break;}//旋转
	case 'o': {bWire = !bWire; break;}//线框

	case 'd': {//右
		eye[0] -= 0.2f;
		center[0] -= 0.2f;
		break;
			  }
	case 'a': {//左
		eye[0] += 0.2f;
		center[0] += 0.2f;
		break;
			  }
	case 'w': {//上
		eye[1] -= 0.2f;
		center[1] -= 0.2f;
		break;
			  }
	case 's': {//下
		eye[1] += 0.2f;
		center[1] += 0.2f;
		break;
			  }
	case 'z': {//前
		eye[2] -= 0.2f;
		center[2] -= 0.2f;
		break;
			  }
	case 'c': {//后
		eye[2] += 0.2f;
		center[2] += 0.2f;
		break;
			  }
	case 'j': {//环境光左
		light_x += 0.2f;
		break;
	}
	case 'l': {//环境光右
		light_x -= 0.2f;
		break;
	}
	case 'i': {//环境光上
		light_y += 0.2f;
		break;
	}
	case 'k': {//环境光下
		light_y -= 0.2f;
		break;
	}
	case 'n': {//环境光前
		light_z += 0.2f;
		break;
	}
	case ',': {//环境光后
		light_z -= 0.2f;
		break;
	}
	case 'u': {//环境光颜色切换
		light_flag = !light_flag;
		break;
	}
	case 'f': {//聚光灯左移
		spot_x -= 0.05f;
		break;
	}
	case 'h': {
		spot_x += 0.05f;
		break;
	}
	case 't': {
		spot_y -= 0.05f;
		break;
	}
	case 'g': {
		spot_y += 0.05f;
		break;
	}
	case 'v': {//聚光灯前移
		spot_z += 0.05f;
		break;
	}
	case 'b': {//聚光灯后移
		spot_z -= 0.05f;
		break;
	}
	case 'r': {//角度变大
		if (Angle <= 89.0f)
			Angle += 0.2f;
		break;
	}
	case 'y': {
		if (Angle >= 1.0f)
			Angle -= 0.2f;
		break;
	}
}

	updateView(wHeight, wWidth);
}


void redraw()
{
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	glLoadIdentity();									// Reset The Current Modelview Matrix

	gluLookAt(eye[0], eye[1], eye[2],
		center[0], center[1], center[2],
		0, 1, 0);				// 场景(0,0,0)的视点中心 (0,5,50),Y轴向上

	if (bWire) {
		glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
	}
	else {
		glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
	}
	glEnable(GL_DEPTH_TEST);//开启深度测试
	glEnable(GL_LIGHTING);//开启光照模式
	
	GLfloat white[] = { 1.0, 1.0, 1.0, 1.0 };//定义环境光颜色:白色
	GLfloat light_pos[] = { 5.0 + light_x,5.0 + light_y,5.0 + light_z,1 };
	//定义聚光灯位置
	GLfloat spot_pos[] = { 0.0f,5.0f,0.0f,1.0f };
	//定义聚光灯照射方向
	GLfloat spot_angle[] = { 0.0f + spot_x,-1.0f + spot_y,0.0f + spot_z };
	//是否改变光照颜色
	if (light_flag)
		color[1] = color[3] = 0.0f;
	else
		color[1] = color[3] = 1.0f;

		
	glLightfv(GL_LIGHT0, GL_POSITION, light_pos);//0号光源的位置
	glLightfv(GL_LIGHT0, GL_SMOOTH, white);//设置环境光颜色
	glLightfv(GL_LIGHT0, GL_DIFFUSE, white);                     //设置漫射光成分  
	glLightfv(GL_LIGHT0, GL_AMBIENT, color);   //设置第0号光源多次反射后的光照颜色(环境光颜色)
	glEnable(GL_LIGHT0);//开启0号光源

	glLightfv(GL_LIGHT1, GL_AMBIENT, color);    //设置环境光成分
	glLightfv(GL_LIGHT1, GL_SPECULAR, white);                 //设置镜面光成分
	glLightfv(GL_LIGHT1, GL_DIFFUSE, white);                     //设置漫射光成分

	glLightfv(GL_LIGHT1, GL_POSITION, spot_pos);
	glLightf(GL_LIGHT1, GL_SPOT_CUTOFF, Angle);            //裁减角度
	glLightfv(GL_LIGHT1, GL_SPOT_DIRECTION, spot_angle);          //光源方向
	glLightf(GL_LIGHT1, GL_SPOT_EXPONENT, 2.);                    //聚集度
	glEnable(GL_LIGHT1);//开启1号光源

	//	glTranslatef(0.0f, 0.0f,-6.0f);			// Place the triangle at Center
	glRotatef(fRotate, 0, 1.0f, 0);			// Rotate around Y axis
	glRotatef(-90, 1, 0, 0);
	glScalef(0.2, 0.2, 0.2);
	Draw_Table();						// Draw triangle

	if (bAnim) fRotate    += 0.5f;
	glutSwapBuffers();
}

int main (int argc,  char *argv[])
{
	glutInit(&argc, argv);
	glutInitDisplayMode(GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE);
	glutInitWindowSize(480,480);
	int windowHandle = glutCreateWindow("Simple GLUT App");

	glutDisplayFunc(redraw);
	glutReshapeFunc(reshape);	
	glutKeyboardFunc(key);
	glutIdleFunc(idle);

	glutMainLoop();
	return 0;
}

如有错误,请批评指正(*/ω╲*)





你可能感兴趣的:(计算机图形学)