欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

OpenGL-渲染光照球体

程序员文章站 2022-06-10 23:48:10
...

3.光照

注意:

a. OpenGL至少会支持8个光源,即GL_LIGHT0到GL_LIGHT7。但是开启过多的光源会导致程序运行速度下降。

b. GL_AMBIENT、GL_DIFFUSE、GL_SPECULAR这三种属性是光源和材质所共有的,如果某光源发出的光线照射到某材质的表面,则最终的漫反射强度由两个GL_DIFFUSE属性共同决定,最终的镜面反射强度由两个GL_SPECULAR属性共同决定。

三步走:

2.1 设置光照模型:glLightModelfv();//指定全局环境光,物体才能基本可见,否则就是一片黑色

GLfloat lmodel_ambient[]={0.2,0.2,0.2,1.0};//微弱环境光,使物体可见
glLightModelfv(GL_LIGHT_MODEL_AMBIENT,lmodel_ambient); //指定全局的环境光,物体才能可见

2.2 glLight*();//设置光源属性:位置、颜色、散射、镜面、

GLfloat light_position[]={1.0,1.0,1.0,0.0};//1.0表示光源为点坐标x,y,z
GLfloat white_light[]={1.0,1.0,1.0,1.0};    //光源的颜色
glLightfv(GL_LIGHT0,GL_POSITION,light_position);//光源编号-7,光源特性,参数数据
glLightfv(GL_LIGHT0,GL_DIFFUSE,white_light);  glLightfv(GL_LIGHT0,GL_SPECULAR,white_light);

2.3 glMaterial*();//设置材质的属性:镜面、强度、

GLfloat mat_specular[]={1.0,1.0,1.0,1.0};
GLfloat mat_shininess[]={128.0};
glMaterialfv(GL_FRONT,GL_SPECULAR,mat_specular);//指定当前材质属性 镜面反射颜色
glMaterialfv(GL_FRONT,GL_SHININESS,mat_shininess);//镜面反射指数

注意:除了采用glMaterial设置材质以外,还可以使用glColorMaterial(GLenum face, GLenum mode)设置材质属性;

face的取值: GL_FRONT 、GL_BACK、GL_FRONT_AND_BACK 
mode的取值: GL_AMBIENT 、GL_DIFFUSE、 GL_AMBIENT_AND_DIFFUSE 、GL_SPECULAR GL_EMISSION、

在想要使用这个函数时,要启用glEnable(GL_COLOR_MATERIAL)函数。 
在绘图时使用glColor*()来实时改变材质颜色,或用glMaterial()来实时改变材质成分 
使用完毕,要用glDisable(GL_COLOR_MATERIAL)来关闭这种材质模式。

例如: 
glColorMaterial(GL_FRONT,GL_DIFFUSE); 
glEnable(GL_COLOR_MATERIAL);
 

glColor3f(0.3,0.5,0.7);
 
//
画一些物体: 
...
 
glColor3f(0.0,1.0,0.0);
 
//
再画另一些物体: 
...
 
glDisable(GL_COLOR_MATERIAL);
 

说明: 
当需要改变场景中大部分的单个材质时,最好调用glColorMaterial() 
当修改不只一个材质参数,最好调用glMaterial*()

代码实例如下:

void init()
{
	//光源light0
	GLfloat mat_specular[]={1.0,1.0,1.0,1.0};
	GLfloat mat_shininess[]={128.0};

	GLfloat light_position[]={1.0,1.0,1.0,0.0};//1.0表示光源为点坐标x,y,z
	GLfloat white_light[]={1.0,1.0,1.0,1.0};   //光源的颜色
	GLfloat lmodel_ambient[]={0.2,0.2,0.2,1.0};//微弱环境光,使物体可见
	glClearColor(0.0,0.0,0.0,1.0);
	glShadeModel(GL_SMOOTH);//GL_SMOOTH

	//glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);
	glMaterialfv(GL_FRONT,GL_SPECULAR,mat_specular);//指定当前材质属性 镜面反射颜色
	glMaterialfv(GL_FRONT,GL_SHININESS,mat_shininess); //镜面反射指数

	glLightfv(GL_LIGHT0,GL_POSITION,light_position);//光源编号-7,光源特性,参数数据
	glLightfv(GL_LIGHT0,GL_DIFFUSE,white_light);  
	glLightfv(GL_LIGHT0,GL_SPECULAR,white_light); 
	glLightModelfv(GL_LIGHT_MODEL_AMBIENT,lmodel_ambient); //指定全局的环境光,物体才能可见//*/

	glEnable(GL_LIGHTING);  
	glEnable(GL_LIGHT0); 
	glEnable(GL_DEPTH_TEST);  
}
void display()
{
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	glutSolidSphere(1.0,300,16);//半径,南北经线,纬线
	glFlush();
}
void reshape(int w,int h)
{
	glViewport(0,0,(GLsizei)w,(GLsizei)h);//使像素矩阵占据整个新窗口
	glMatrixMode(GL_PROJECTION);//设置当前矩阵为投影矩阵
	glLoadIdentity();

	float nowRange = 1.5;
	GLfloat nRange =(GLfloat)nowRange;

	if (w <= h) //改变窗口大小,图形形状不变
		glOrtho (-nRange, nRange, -nRange*h/w, nRange*h/w,-nRange, nRange);
	else 
		glOrtho (-nRange*w/h, nRange*w/h, -nRange, nRange, -nRange, nRange);

	glMatrixMode(GL_MODELVIEW);//模型矩阵,告诉我们当前矩阵
	glLoadIdentity();
}

实例图片:

OpenGL-渲染光照球体