OpenGL-渲染光照球体
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();
}
实例图片: