光照处理过程:
为所有顶点设置法线向量----
进行光照计算,面法线长度必须为1, 为确保面法线为1,需要使用参数GL_NORMALIZE(通用,计算量相对较大),GL_RESCAL_NORMAL(等比例放大缩小,使用有限制)调用glEnable();
设置光源----设置位置----
glLight();
启用光源----
glEnable(GL_LIGHT*);
可设置8个或8个以上光源,默认为黑色,增加光源增加系统负担。
选择光照模型----
glLightModel*();
指定物体材质属性----
glMaterialfv()
可以指定材质的环境颜色,散射颜色,光洁度
进行光照计算,面法线长度必须为1, 为确保面法线为1,需要使用参数GL_NORMALIZE(通用,计算量相对较大),GL_RESCAL_NORMAL(等比例放大缩小,使用有限制)调用glEnable();
设置光源----设置位置----
glLight();
启用光源----
glEnable(GL_LIGHT*);
可设置8个或8个以上光源,默认为黑色,增加光源增加系统负担。
选择光照模型----
glLightModel*();
指定物体材质属性----
glMaterialfv()
可以指定材质的环境颜色,散射颜色,光洁度
1.创建光源
glLight{if}[v](GLenum light, GLenum pname, TYPE (*)param)
GL_AMBIENT (0.0, 0.0, 0.0, 1.0) 环境光颜色
GL_DIFFUSE (1.0,1.0,1.0,1.0)或(0.0,0.0,0.0,1.0) 散射光颜色(LIGHT0默认为白色,其余为黑色)
GL_SPECULAR (1.0,1.0,1.0,1.0)或(0.0,0.0,0.0,1.0) 镜面反射光颜色(LIGHT0默认为白色,其余为黑色)
GL_POSITION (0.0,0.0,1.0,0.0) 光源位置
GL_SPOT_DIRECTION (0.0,0.0,-1.0) 聚光灯方向
GL_SPOT_EXPONENT (0.0) 聚光指数
GL_SPOT_CUTOFF 180.0 聚光截至角
GL_CONSTANT_ATTENUATION 1.0 固定衰减因子
GL_LINEAR_ATTENUATION 0.0 线性衰减因子
GL_QUADRATIC_ATTENUATION 0.0 二次衰减因子
GL_DIFFUSE (1.0,1.0,1.0,1.0)或(0.0,0.0,0.0,1.0) 散射光颜色(LIGHT0默认为白色,其余为黑色)
GL_SPECULAR (1.0,1.0,1.0,1.0)或(0.0,0.0,0.0,1.0) 镜面反射光颜色(LIGHT0默认为白色,其余为黑色)
GL_POSITION (0.0,0.0,1.0,0.0) 光源位置
GL_SPOT_DIRECTION (0.0,0.0,-1.0) 聚光灯方向
GL_SPOT_EXPONENT (0.0) 聚光指数
GL_SPOT_CUTOFF 180.0 聚光截至角
GL_CONSTANT_ATTENUATION 1.0 固定衰减因子
GL_LINEAR_ATTENUATION 0.0 线性衰减因子
GL_QUADRATIC_ATTENUATION 0.0 二次衰减因子
颜色
GL_DIFFUSE与看见的颜色关系最密切
GL_DIFFUSE与看见的颜色关系最密切
位置和衰减
GL_POSITION 的 param (x, y, z, w), 当w为0时为从无穷远照射,(x, y, z)为光照射方向
当w不为0时为定点光源,(x, y, z )表示在其次坐标中的位置
对于定点光源可以设置衰减
衰减系数 = 1/(kc+kl*d+kq*d*d)
GL_POSITION 的 param (x, y, z, w), 当w为0时为从无穷远照射,(x, y, z)为光照射方向
当w不为0时为定点光源,(x, y, z )表示在其次坐标中的位置
对于定点光源可以设置衰减
衰减系数 = 1/(kc+kl*d+kq*d*d)
聚光灯
GL_SPOT_DIRECTION、GL_SPOT_EXPONENT、GL_SPOT_CUTOFF分别设置聚光灯的方向、聚光指数、聚光灯、光锥半顶角。
还需要设置光源的位置。
GL_SPOT_DIRECTION、GL_SPOT_EXPONENT、GL_SPOT_CUTOFF分别设置聚光灯的方向、聚光指数、聚光灯、光锥半顶角。
还需要设置光源的位置。
光源位置和方向
1.光源位置固定
指定模型视点矩阵后设置光源位置,之后不进行更改
1.光源位置固定
指定模型视点矩阵后设置光源位置,之后不进行更改
例程light:
#include<windows.h>
#include<GL/glut.h>
#include<GL/glut.h>
void display()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glutSolidSphere(1.0, 20, 16);
glFlush();
}
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glutSolidSphere(1.0, 20, 16);
glFlush();
}
void init()
{
GLfloat mat_specular[] = {1.0, 1.0,0.0, 1.0};
GLfloat mat_shininess[] = {5.0};
GLfloat light_position[] = {1.0, 1.0, 1.0, 0.0};
GLfloat white_light[] = {1.0, 1.0, 1.0, 1.0};
GLfloat lmodel_ambient[] = {0.1, 0.1, 0.1, 1.0};
glClearColor(0.0, 0.0, 0.0, 0.0);
glShadeModel(GL_SMOOTH);
glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);
glLightfv(GL_LIGHT0, GL_POSITION, light_position);
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);
}
{
GLfloat mat_specular[] = {1.0, 1.0,0.0, 1.0};
GLfloat mat_shininess[] = {5.0};
GLfloat light_position[] = {1.0, 1.0, 1.0, 0.0};
GLfloat white_light[] = {1.0, 1.0, 1.0, 1.0};
GLfloat lmodel_ambient[] = {0.1, 0.1, 0.1, 1.0};
glClearColor(0.0, 0.0, 0.0, 0.0);
glShadeModel(GL_SMOOTH);
glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);
glLightfv(GL_LIGHT0, GL_POSITION, light_position);
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 reshape(int w, int h)
{
glViewport(0.0, 0.0,(GLsizei)w, (GLsizei)h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
if(w<=h)
glOrtho(-1.5, 1.5, -1.5*(GLfloat)h/(GLfloat)w, 1.5*(GLfloat)h/(GLfloat)w, -10.0, 10.0);
else
glOrtho(-1.5*(GLfloat)w/(GLfloat)h, 1.5*(GLfloat)w/(GLfloat)h, -1.5, 1.5, -10.0, 10.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
{
glViewport(0.0, 0.0,(GLsizei)w, (GLsizei)h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
if(w<=h)
glOrtho(-1.5, 1.5, -1.5*(GLfloat)h/(GLfloat)w, 1.5*(GLfloat)h/(GLfloat)w, -10.0, 10.0);
else
glOrtho(-1.5*(GLfloat)w/(GLfloat)h, 1.5*(GLfloat)w/(GLfloat)h, -1.5, 1.5, -10.0, 10.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
int main(int grac, char** agrv)
{
glutInit(&grac, agrv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(500, 500);
glutInitWindowPosition(100,100);
glutCreateWindow("Light");
init();
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutMainLoop();
return 0;
}
2.独立的移动光源
设置模型视点矩阵后对光源位置进行修改
{
glutInit(&grac, agrv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(500, 500);
glutInitWindowPosition(100,100);
glutCreateWindow("Light");
init();
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutMainLoop();
return 0;
}
2.独立的移动光源
设置模型视点矩阵后对光源位置进行修改
例程:moveLight
#include<windows.h>
#include<GL/glut.h>
static int spin = 0;
#include<GL/glut.h>
static int spin = 0;
void display()
{
GLfloat position[] = {0.0, 0.0, 1.5, 1.0};
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushMatrix();
glTranslatef(0.0, 0.0, -5.0);
glPushMatrix();
glRotated((GLdouble)spin, 1.0, 0.0, 0.0);
glLightfv(GL_LIGHT0, GL_POSITION, position);
glTranslated(0.0, 0.0, 1.5);
glDisable(GL_LIGHTING);
glColor3f(0.0, 1.0, 1.0);
glutWireCube(0.1);
glEnable(GL_LIGHTING);
glPopMatrix();
glutSolidTorus(0.275, 0.85, 8, 15);
glPopMatrix();
glFlush();
}
{
GLfloat position[] = {0.0, 0.0, 1.5, 1.0};
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushMatrix();
glTranslatef(0.0, 0.0, -5.0);
glPushMatrix();
glRotated((GLdouble)spin, 1.0, 0.0, 0.0);
glLightfv(GL_LIGHT0, GL_POSITION, position);
glTranslated(0.0, 0.0, 1.5);
glDisable(GL_LIGHTING);
glColor3f(0.0, 1.0, 1.0);
glutWireCube(0.1);
glEnable(GL_LIGHTING);
glPopMatrix();
glutSolidTorus(0.275, 0.85, 8, 15);
glPopMatrix();
glFlush();
}
void init()
{
glClearColor(0.0, 0.0, 0.0, 0.0);
glShadeModel(GL_SMOOTH);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_DEPTH_TEST);
}
{
glClearColor(0.0, 0.0, 0.0, 0.0);
glShadeModel(GL_SMOOTH);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_DEPTH_TEST);
}
void reshape(int w, int h)
{
glViewport(0.0, 0.0,(GLsizei)w, (GLsizei)h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(40.0, (GLfloat)w/(GLfloat)h, 1.0, 20.0);
glMatrixMode(GL_MODELVIEW);
glFlush();
}
{
glViewport(0.0, 0.0,(GLsizei)w, (GLsizei)h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(40.0, (GLfloat)w/(GLfloat)h, 1.0, 20.0);
glMatrixMode(GL_MODELVIEW);
glFlush();
}
void mouse(int button, int state, int x, int y)
{
switch(button)
{
case GLUT_LEFT_BUTTON:
if(state == GLUT_DOWN)
{
spin = (spin + 30)%360;
glutPostRedisplay();
}
break;
default:
break;
}
}
{
switch(button)
{
case GLUT_LEFT_BUTTON:
if(state == GLUT_DOWN)
{
spin = (spin + 30)%360;
glutPostRedisplay();
}
break;
default:
break;
}
}
int main(int grac, char** agrv)
{
glutInit(&grac, agrv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(500, 500);
glutInitWindowPosition(100,100);
glutCreateWindow("moveLight");
init();
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutMouseFunc(mouse);
glutMainLoop();
return 0;
}
3.随视点移动光源
先设置光源在设置视点变化矩阵,光源相对观察点的位置不变。
{
glutInit(&grac, agrv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(500, 500);
glutInitWindowPosition(100,100);
glutCreateWindow("moveLight");
init();
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutMouseFunc(mouse);
glutMainLoop();
return 0;
}
3.随视点移动光源
先设置光源在设置视点变化矩阵,光源相对观察点的位置不变。
例程:moveLight2
#include<windows.h>
#include<GL/glut.h>
static int spin = 0;
#include<GL/glut.h>
static int spin = 0;
void display()
{
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
//光源位置
glPushMatrix();
glDisable(GL_LIGHTING);
glTranslatef(0.0, 0.0, -4.0);
glColor3f(0.0, 1.0, 1.0);
glutWireCube(0.1);
glEnable(GL_LIGHTING);
glPopMatrix();
glPushMatrix();
//视口位置
glTranslatef(0.0, 0.0, -5.0);
glRotated((GLdouble)spin, 1.0, 0.0, 0.0);
//物体
glutSolidTorus(0.275, 0.85, 8, 15);
glPopMatrix();
glFlush();
}
//光源位置
glPushMatrix();
glDisable(GL_LIGHTING);
glTranslatef(0.0, 0.0, -4.0);
glColor3f(0.0, 1.0, 1.0);
glutWireCube(0.1);
glEnable(GL_LIGHTING);
glPopMatrix();
glPushMatrix();
//视口位置
glTranslatef(0.0, 0.0, -5.0);
glRotated((GLdouble)spin, 1.0, 0.0, 0.0);
//物体
glutSolidTorus(0.275, 0.85, 8, 15);
glPopMatrix();
glFlush();
}
void init()
{
glClearColor(0.0, 0.0, 0.0, 0.0);
glShadeModel(GL_SMOOTH);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_DEPTH_TEST);
}
{
glClearColor(0.0, 0.0, 0.0, 0.0);
glShadeModel(GL_SMOOTH);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_DEPTH_TEST);
}
void reshape(int w, int h)
{
GLfloat position[] = {0.0, 0.0, 0.0, -4.0};
glViewport(0.0, 0.0,(GLsizei)w, (GLsizei)h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(40.0, (GLfloat)w/(GLfloat)h, 1.0, 20.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glLightfv(GL_LIGHT0, GL_POSITION, position);
}
{
GLfloat position[] = {0.0, 0.0, 0.0, -4.0};
glViewport(0.0, 0.0,(GLsizei)w, (GLsizei)h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(40.0, (GLfloat)w/(GLfloat)h, 1.0, 20.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glLightfv(GL_LIGHT0, GL_POSITION, position);
}
void mouse(int button, int state, int x, int y)
{
switch(button)
{
case GLUT_LEFT_BUTTON:
if(state == GLUT_DOWN)
{
spin = (spin + 30)%360;
glutPostRedisplay();
}
break;
default:
break;
}
}
{
switch(button)
{
case GLUT_LEFT_BUTTON:
if(state == GLUT_DOWN)
{
spin = (spin + 30)%360;
glutPostRedisplay();
}
break;
default:
break;
}
}
int main(int grac, char** agrv)
{
glutInit(&grac, agrv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(500, 500);
glutInitWindowPosition(100,100);
glutCreateWindow("moveLight");
init();
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutMouseFunc(mouse);
glutMainLoop();
return 0;
}
{
glutInit(&grac, agrv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(500, 500);
glutInitWindowPosition(100,100);
glutCreateWindow("moveLight");
init();
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutMouseFunc(mouse);
glutMainLoop();
return 0;
}
2.选择光照模型
glLightModel{if}(GLenum pname, TYPE param);
GL_LIGHT_MODEL_AMBIENT (0.2, 0.2, 0.2, 1.0) 环境光的RGBA值
GL_LIGHT_MODEL_LOCAL_VIEWER 0.0或GL_FALSE 如何计算镜面反射角
GL_LIGHT_MODEL_TWO_SIDE 0.0或GL_FALSE 单面或双面光照
GL_LIGHT_MODEL_COLOR_CONTROL GL_SINGLE_GCOLOR 镜面反射颜色计算是否独立于环境颜色、散射颜色,在纹理之后计算
GL_LIGHT_MODEL_LOCAL_VIEWER 0.0或GL_FALSE 如何计算镜面反射角
GL_LIGHT_MODEL_TWO_SIDE 0.0或GL_FALSE 单面或双面光照
GL_LIGHT_MODEL_COLOR_CONTROL GL_SINGLE_GCOLOR 镜面反射颜色计算是否独立于环境颜色、散射颜色,在纹理之后计算
3.设置材质属性
glMaterial{if}(GLenum face, GLenum pname, TYPE param)
glMaterial{if}v(GLenum face, GLenum pname, TYPE* param)
face可以是GL_FRONT、GL_BACK、GL_FRONT_AND_BACK.
当pname为GL_SHININESS才能使用非向量函数
pname
GL_AMBIENT (0.2, 0.2, 0.2, 1.0) 材质的环境颜色
GL_DIFFUSE (0.8, 0.8, 0.8, 1.0) 材质的散射颜色
GL_AMBIENT_AND_DIFFUSE 材质的环境颜色和散射颜色
GL_SPECULAR (0.0, 0.0, 0.0, 1.0) 材质的镜面反射颜色
GL_SHININESS 0.0 镜面反射指数、光泽度
GL_EMISSION (0.0, 0.0, 0.1, 1.0) 材质的发光颜色
GL_COLOR_INDEXES (0, 1, 1) 环境颜色索引、散射索引、镜面反射索引
glMaterial{if}v(GLenum face, GLenum pname, TYPE* param)
face可以是GL_FRONT、GL_BACK、GL_FRONT_AND_BACK.
当pname为GL_SHININESS才能使用非向量函数
pname
GL_AMBIENT (0.2, 0.2, 0.2, 1.0) 材质的环境颜色
GL_DIFFUSE (0.8, 0.8, 0.8, 1.0) 材质的散射颜色
GL_AMBIENT_AND_DIFFUSE 材质的环境颜色和散射颜色
GL_SPECULAR (0.0, 0.0, 0.0, 1.0) 材质的镜面反射颜色
GL_SHININESS 0.0 镜面反射指数、光泽度
GL_EMISSION (0.0, 0.0, 0.1, 1.0) 材质的发光颜色
GL_COLOR_INDEXES (0, 1, 1) 环境颜色索引、散射索引、镜面反射索引
4.颜色材质模式
glColorMaterial(GLenum face, GLenum mode);
设置face表面的材质属性mode总是为当前颜色。
用glColor修改当前颜色后,材质的相应属性会发生改变。
face可以是GL_FRONT、GL_BACK、GL_FRONT_AND_BACK
mode可以是GL_AMBIENT、GL_DIFFUSE、GL_SPECULAR、GL_AMBIENT_AND_DIFFUSE、GL_EMISSION
设置face表面的材质属性mode总是为当前颜色。
用glColor修改当前颜色后,材质的相应属性会发生改变。
face可以是GL_FRONT、GL_BACK、GL_FRONT_AND_BACK
mode可以是GL_AMBIENT、GL_DIFFUSE、GL_SPECULAR、GL_AMBIENT_AND_DIFFUSE、GL_EMISSION
修改场景中大部分顶点的同一种材质属性是,应使用glColorMaterial()
需要修改多种材质时要用glMaterial*();