OpenGL 光照和材料属性

首先是光照的设置,光照分为三类环境光 散射光 镜面光,根据此时的理解,记录下今天所掌握的知识,先设置3个数组后面会用到
GLfloat amb[] = {0.3f,0.3f,0.3f,1.0f};//环境光成分
GLfloat dif[] = {0.7f,0.7f,0.7f,1.0f};//散射光成分
GLfloat spe[] = {1.0f,1.0f,1.0f,1.0f};//镜面光成分
环境光是从物体的各个方向照射物体的,他产生的效果和关闭光照效果几乎相同,由于在关闭光照效果的时候,物体老是可见的并均匀着色,与他们的旋转和观察角度无关,若打开光照效果glEnable(GL_LIGHTING)而不指定环境光,这时默认的环境光是(0.2,0.2,0.2,1.0),这是很是微弱的光,画面上的物体会很是的暗淡,这时咱们指定一个本身的第一个光源light0,先给他设置环境光glLightfv(GL_LIGHT0,GL_AMBIENT,amb),amb是开始定义的表示环境光成分的数组
散射光是一种有特定方向的光,在物体表面是均匀的反射的,也能够理解成漫反射光,和下面学习的经面光有些类似,若以散射光照射一个球体做为例子,正对着散射光方向的表面是亮的,背对着光线方向的表面是暗淡的,在光线掠过的侧面的亮度是介于二者之间的,这和在一个黑屋子里用手电筒照射一个篮球的效果很类似,这时给上面的光源light0指定一种散射光glLightfv(GL_LIGHT0,GL_DIFFUSE,dif),dif是开始定义的表示散射光成分的数组
最后是镜面光,这种光比较好理解,和上面的散射光同样,他也是有必定的方向,但在物体表面的反射是很强烈的,能够理解为镜面反射光,他会在物体边面造成一个亮点(光斑),在生活中强光照射在比较平整的表面就是这种效果,如在阳光照射下表面无锈迹的铁球,再给上面的光源light0加上镜面光成分,flLightfv(GL_LIGHT0,GL_SPECULAR,spe),spe是开始定义的表示镜面光成分的数组
在特定的光源设置好之后这时就能够启用这用个光源,glEnable(GL_LIGHT0);
如下就是设置并启用自定义光源的代码
glEnable(GL_LIGHTING);//启动光照效果
GLfloat amb[] = {0.3f,0.3f,0.3f,1.0f};//环境光成分
GLfloat dif[] = {0.7f,0.7f,0.7f,1.0f};//散射光成分
GLfloat spe[] = {1.0f,1.0f,1.0f,1.0f};//镜面光成分数组

glLightfv(GL_LIGHT0,GL_AMBIENT,amb); //添加环境光成分
glLightfv(GL_LIGHT0,GL_DIFFUSE,dif); //添加散射光成分
glLightfv(GL_LIGHT0,GL_SPECULAR,spe);//给自定义光源light0添加镜面光成分函数

glEnable(GL_LIGHT0);     //启用自定义的光源oop

光照定义完成后,还要定义物体的表面的材料属性,材料的属性对最后的效果影响也是巨大的,由于最终在屏幕上显示的效果是光源发出的光通过材料反射后才能最终肯定的,材料的属性设置和光源的设置有些相似,用到的函数glMaterialfv(GL_FRONT_AND_BACK,GL_AMBIENT_AND_DIFFUSE,amb)第一个参数指定了是哪一个表面须要被渲染,第二个参数是哪一个材料属性将要被设置,第三个参数是指定哪一种颜色的光会被反射(用了上面的一个数组),通常状况下材料对环境光和对散射光的反射率是相同的,因此上面的参数用了GL_AMBIENT_AND_DIFFUSE。
上面的光源设置中用到了镜面光,若此时在材料属性中不设置镜面反射效果,则上面的镜面光也就没什么做用,镜面反射的设置和光源的镜面光设置相似glMaterialfv(GL_FRONT_AND_BACK,GL_SPECULAR,spe),若绘制的物体想要有光泽那么这个设置是必须的(例如光滑的大理石表面),若绘制的物体的表面没有光泽那么这个属性就不用设置(例如粗糙的石板表面),在镜面反射设置后还有一个问题须要解决,那就是高强度的镜面光和强烈的镜面反射效果会致使物体将以几乎接近白色的效果出现,如若想要在物体表面造成一个亮斑,还须要一个函数glMateriali(GL_FRONT_AND_BACK,GL_SHININESS,45);中间的一个参数是镜面指数,他指定了镜面反射加亮的大小和集中性,若是最后一个参数设置为0那表示不聚焦,也就是整个表面均匀加亮,若设置为128表示最大程度的聚焦,也就是光斑点最小的状况。
一下是材料属性设置的代码
glMaterialfv(GL_FRONT_AND_BACK,GL_AMBIENT,amb);//材料对环境光的反射状况
glMaterialfv(GL_FRONT_AND_BACK,GL_DIFFUSE,dif);//散射光的反射状况
glMaterialfv(GL_FRONT_AND_BACK,GL_SPECULAR,spe);//镜面光的反射状况
glMateriali(GL_FRONT_AND_BACK,GL_SHININESS,45);//镜面光的聚焦状况学习

这样就能够渲染出比原来更为真实的三位物体,但还有一点不足 ,就是当物体的颜色常常发生变化时,那么必须每次进行材料反射属性的更改,将调用一次glMaterialfv(),那将是件很麻烦的工做,这里能够用到一个方法,也是之后最经常使用到的方法,叫作颜色追踪。若使用了这种方法,能够在之后的渲染中经过调用glColor来设置材料的属性,方法以下
glEnable(GL_COLOR_MATERIAL);         //启用颜色追踪
glColorMaterial(GL_FRONT_AND_BACK,FL_AMBIENT_AND_DIFFUSE); //正面和反面,环境光和散射光
设置好后,之后就能够经过调用glColor来设置材料的反射属性了。
如下是今天程序的完整代码和makefilespa


//文件名ball_light.c
//2008/2/14
//made by hsw
#include <GL/glx.h>
#include <GL/gl.h>
#include <GL/glut.h>orm

GLfloat position_x = -25.0f;
GLfloat position_y = 25.0f;
GLfloat change_x = 0.1f;
GLfloat change_y = 0.1f;
GLfloat Height = 100.0f;
GLfloat Width = 100.0f;it

GLfloat temp = 1.0f ;
void TimeFunction(void)
{
glutPostRedisplay();
glutTimerFunc(33,TimeFunction,1);io

}
void RenderScene(void)
{
static GLint angle_x = 0;
static GLint angle_y = 0;
static GLint angle_z = 0;
GLint temp_i,temp_j;
angle_x += 1;
angle_y += 2;
angle_z += 4;
 glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
 glColor3f(0.0f,0.95f,0.24f);
 glMatrixMode(GL_MODELVIEW);
 glLoadIdentity();gcc


glPushMatrix();
 glTranslatef(0.0f,0.0f,-50.0f);
 glRotatef(angle_x++,0.0f,1.0f,0.0f);
 glutSolidTorus(1,8,30,40);
 glColor3f(1.0f,0.0f,0.0f);
 glutSolidSphere(3.5f,40,40);
glPopMatrix();渲染

glPushMatrix();
 glTranslatef(0.0f,0.0f,-50.0f);
    glPushMatrix();
 glTranslatef(-30.0f,10.0f,0.0f);
 glColor3f(1.0f,0.0f,0.0f);
 glutSolidSphere(3.5f,40,40);
    glPopMatrix();

    glPushMatrix();
 glTranslatef(-30.0f,25.0f,0.0f);
 glColor3f(1.0f,0.0f,0.0f);
 glutSolidSphere(3.5f,40,40);
    glPopMatrix();

glPopMatrix();
glPushMatrix();
 glColor3f(1.0f,1.0f,0.0f);
 glTranslatef(30.0f,0.0f,-50.0f);
 glutSolidSphere(5.0f,40,40);
glPopMatrix();
 //glutSolidSphere(12.0f,40,40);
 //glutSolidTeapot(12.0f);
//如下是地面的绘制
//底色

glColor3f(1.0f,1.0f,1.0f);
glBegin(GL_TRIANGLE_FAN);
    glVertex3f(-1500.0f,-30.5f,0.0f);
    glVertex3f(-1500.0f,-30.5f,-2500.0f);
    glVertex3f(1500.0f,-30.5f,-2500.0f);
    glVertex3f(1500.0f,-30.5f,0.0f);
glEnd();

 glutSwapBuffers();
}
void SetupRC(void)
{
 GLfloat amb[] = {0.4f,0.4f,0.4f,1.0f};
 GLfloat dif[] = {6.0f,6.0f,6.0f,1.0f};
 GLfloat spe[] = {1.0f,1.0f,1.0f,1.0f};
 GLfloat pos[] = {-50.0f,50.0f,100.0f,1.0f};
 glClearColor(0.0f,0.0f,0.0f,1.0f);
 glEnable(GL_DEPTH_TEST);
 //glLightModelfv(GL_LIGHT_MODEL_AMBIENT,amb);
 glEnable(GL_LIGHTING);
 glLightfv(GL_LIGHT0,GL_AMBIENT,amb);
 //glLightfv(GL_LIGHT0,GL_DIFFUSE,dif);
 glLightfv(GL_LIGHT0,GL_SPECULAR,spe);
 glLightfv(GL_LIGHT0,GL_POSITION,pos);
//glLightf(GL_LIGHT0,GL_SPOT_CUTOFF,60.0f);
 glEnable(GL_LIGHT0);

 glEnable(GL_COLOR_MATERIAL);
 glColorMaterial(GL_FRONT_AND_BACK,GL_AMBIENT_AND_DIFFUSE);
 glMaterialfv(GL_FRONT_AND_BACK,GL_SPECULAR,spe);
 glMateriali(GL_FRONT_AND_BACK,GL_SHININESS,128);
}

void ChangeSize(GLsizei w,GLsizei h)
{
GLfloat aspectRatio;
if(h == 0)
 h = 1;
glViewport(0,0,w,h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
temp = aspectRatio = (GLfloat)w/(GLfloat)h;
    if(w <= h)
 //glOrtho(-100.0,100.0,-100/aspectRatio,100.0/aspectRatio,0.0,100.0);
 gluPerspective(60,temp,0.1f,1000.0f);
    else
 //glOrtho(-100.0*aspectRatio,100.0*aspectRatio,-100.0,100.0,0.0,100.0);
 gluPerspective(60,temp,0.1f,1000.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}

int main(int argc ,char *argv[])
{
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);

glutCreateWindow("Color Material");
glutDisplayFunc(RenderScene);
glutReshapeFunc(ChangeSize);
glutTimerFunc(33,TimeFunction,1);
SetupRC();
glutMainLoop();

return 0;
}
//代码结束
//////////////////////////////////////////////////////////////////////
如下是makefile

ball_light:ball_light.o gcc -o ball_light ball_light.o -lGL -lGLU -lglut -lmball_light.o:ball_light.c gcc -c ball_light.c

相关文章
相关标签/搜索