1.颜色
• 设置颜色的函数
– glColor3f(…);
– glColor4f(…);
– 指定着色模式
– 纯色(恒定着色)
– 多种颜色(平滑着色)
– 设置着色模式函数:glShadeModel(…);
• 功能:
– 设置当前颜色
• 参数:
– r:红色分量的值
– g:绿色分量的值
– b:蓝色分量的值
• 返回值:无
• 备注:
– r、g、b的值的范围在区间〔0,1〕内
– 0.0强度最小
– 1.0强度最大
• void glColor4f(GLfloat r, GLfloat g, GLfloat b, GLfloat alpha);
• 功能:
– 设置当前颜色
• 参数:
– r:红色分量的值
– g:绿色分量的值
– b:蓝色分量的值
– alpha:alpha分量的值,用作混合
• 返回值:无
• 备注:
r、g、b、alpha的值的范围在区间〔0,1〕内
指定着色模式
void glShadeModel(GLenum mode);
功能:指定着色模式
参数:
mode:着色模式
返回值:无
备注:
mode可以取下列值:
GL_FLAT 恒定着色
GL_SMOOTH 平滑着色
#include
#include
GLfloat step = 0.0f;
void display()
{
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glTranslatef(0.0f, 0.0f, -200.0f);
glPushMatrix();
glRotatef(step, 1.0f, 0.0f, 0.0f);
//绘制三棱锥的三个棱面,他们的颜色分别为红、绿、蓝
glBegin(GL_TRIANGLE_FAN);
glVertex3f(0.0, 0.0, 80.0);//高度
glVertex3f(0.0, 50.0, 0.0);
glColor3f(1.0,0.0,0.0);
glVertex3f(50.0, -50.0, 0.0);
glColor3f(0.0,1.0,0.0);
glVertex3f(-50.0, -50.0, 0.0);
glColor3f(0.0,0.0,1.0);
glVertex3f(0.0, 50.0, 0.0);
glEnd();
//绘制三棱锥的底面,其颜色为黄色
glBegin(GL_TRIANGLE_FAN);
glVertex3f(0.0, 50.0, 0.0);
glVertex3f(50.0, -50.0, 0.0);
glColor3f(1.0,1.0,0.0);
glVertex3f(-50.0, -50.0, 0.0);
glEnd();
glPopMatrix();
glutSwapBuffers();
}
void animation(void)
{
step += 1.0f;//翻转速度
step = (GLfloat)((int)step % 360);//翻转角度
glutPostRedisplay();
}
void resize(int width, int height)
{
float ar = (float) width / (float) height;
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity() ;
gluPerspective(45.0, ar, 1.0, 500.0);
glMatrixMode(GL_MODELVIEW);
}
int main( int argc, char ** argv )
{
glutInit( &argc, argv );
glutInitDisplayMode( GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowPosition( 100, 100 );
glutInitWindowSize( 1000, 1000 );//画布大小
glutCreateWindow( "OpenGL Examples!" );
glutDisplayFunc( display );
glutIdleFunc(animation);
glutReshapeFunc(resize);
glEnable(GL_DEPTH_TEST);
glShadeModel(GL_SMOOTH);//平滑着色
//glShadeModel(GL_SMOOTH);
glutMainLoop();
return 0;
}
2.启用光源
要在OpenGL环境中使用光照,需要告诉OpenGL系统启用光源
启用光源分为两步
开启光源1,开启光源2, …………
开启光照渲染
开启光源i
glEnable(GL_LIGHTi); //i是从0到7之间的整数
开启光照渲染
glEnable(GL_LIGHTING);
#include
#include
GLfloat step = 0.0f;
void display()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glColor3f( 1, 0, 0 );//颜色
glPushMatrix();
glTranslated(0,0,-3);
glRotated(60,30,-15,0);
glRotated(step,0,0,1);
glutSolidSphere(1,128,128);
glPopMatrix();
glutSwapBuffers();
}
void resize(int width, int height)
{
float ar = (float) width / (float) height;
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glFrustum(-ar, ar, -1.0, 1.0, 2.0, 100.0);
glMatrixMode(GL_MODELVIEW);
}
void SpecialKeys(int key, int x, int y)
{
if(key == GLUT_KEY_UP)
step -= 5.0f;
if(key == GLUT_KEY_DOWN)
step += 5.0f;
step = (GLfloat)((int)step % 360);
glutPostRedisplay();
}
void SetupRC()
{
glClearColor(0,0,0,1);
glEnable(GL_DEPTH_TEST);//启动光源
GLfloat light_ambient[] = { 0.0f, 0.0f, 0.0f, 1.0f };
GLfloat light_diffuse[] = { 1.0f, 1.0f, 1.0f, 1.0f };
GLfloat light_specular[] = { 1.0f, 1.0f, 1.0f, 1.0f };
GLfloat light_position[] = { 2.0f, 5.0f, 5.0f, 0.0f };
GLfloat mat_ambient[] = { 0.7f, 0.7f, 0.7f, 1.0f };
GLfloat mat_diffuse[] = { 0.8f, 0.8f, 0.8f, 1.0f };
GLfloat mat_specular[] = { 1.0f, 1.0f, 1.0f, 1.0f };
GLfloat high_shininess[] = { 100.0f };
glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient);
glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse);
glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular);
glLightfv(GL_LIGHT0, GL_POSITION, light_position);
glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient);
glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
glMaterialfv(GL_FRONT, GL_SHININESS, high_shininess);
glEnable(GL_LIGHT0);//不要忘了
glEnable(GL_COLOR_MATERIAL);//不要忘了
glEnable(GL_LIGHTING);//不要忘了
}
int main( int argc, char ** argv )
{
glutInit( &argc, argv );
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
glutInitWindowPosition( 100, 100 );
glutInitWindowSize( 400, 400 );
glutCreateWindow( "OpenGL Examples!" );
glutSpecialFunc(SpecialKeys);
glutDisplayFunc( display );
glutReshapeFunc(resize);
SetupRC();
glutMainLoop();
return 0;
}
3.禁用光源
禁用光源分为两种情况
禁用指定光源
禁用光照渲染(禁用所有光源)
禁用光源i
glDisable(GL_LIGHTi); //i是从0到7之间的整数
禁用光照渲染
glDisable(GL_LIGHTING);
4.光源属性
光源的属性:
颜色 位置 方向
其他属性:
衰减 聚光灯 多光源
设置光源属性的函数
glLightfv(…)
glLightf(…)
4.1定义光源
void glLight{i f}{v}(GLenum light, GLenum pname, TYPE param);
功能:设置光源参数
参数:
light:指定一个光源
pname: 指定光源参数
param: 光源参数的具体设定值
返回值:无
4.2颜色
环境光颜色
散射光颜色
镜面反射光颜色
例:
GLfloat LightAmbient[]={0.5f,0.5f,0.5f,1.0f};
GLfloat LightDiffuse[]={1.0f,1.0f,1.0f,1.0f};
GLfloat LightSpecular[]={0.5f,0.5f,0.5f,1.0f};
glLightfv(GL_LIGHT0,GL_AMBIENT, LightAmbient);
glLightfv(GL_LIGHT0,GL_DIFFUSE, LightDiffuse);
glLightfv(GL_LIGHT0,GL_SPECULAR, LightSpecular);
4.3位置
定向(directional)光源,如太阳
位置(x, y, z, w)中w为0,则光源为定向光源
定位(positional)光源,如台灯
位置(x, y, z, w)中w不为0,则光源为定位光源
聚光灯
聚光灯是一种定位光源,需要指定其位置
截止角,GL_SPOT_CUTOFF
GL_SPOT_CUTOFF默认值180
除默认值外,它的取值范围[0.0, 90.0]
例:glLightf(GL_LIGHT0, GL_SPOT_CUTOFF, 45.0);
聚光灯方向, GL_SPOT_DIRECTION (轴线方向)
默认方向(0.0, 0.0, -1.0)
GLfloat spot_direction[] = {-1.0, -1.0, 0.0};
glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, spot_direction);
聚光指数, GL_SPOT_EXPONENT
默认为0.0,轴线处光强最大
聚光指数越大,光源的聚焦效果越高
glLightf(GL_LIGHT1, GL_SPOT_EXPONENT, 5.0)
多光源
OpenGL至少允许在场景中使用8个光源(甚至更多)
GL_LIGHT0, GL_LIGHT1, GL_LIGHT2, ……,GL_LIGHT7
使用多个光源将会降低性能
#include
#include
GLfloat step = 0.0f;
void display()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushMatrix();
glTranslated(0,step,-4.5f);
glutSolidSphere(1,128,128);
glPopMatrix();
glutSwapBuffers();
}
void resize(int width, int height)
{
float ar = (float) width / (float) height;
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glFrustum(-ar, ar, -1.0, 1.0, 2.0, 100.0);
glMatrixMode(GL_MODELVIEW);
}
void SpecialKeys(int key, int x, int y)
{
if(key == GLUT_KEY_UP)
step += 0.5f;
if(key == GLUT_KEY_DOWN)
step -= 0.5f;
glutPostRedisplay();
}
void SetupRC()
{
GLfloat mat_ambient[]= { 0.2f, 0.2f, 0.2f, 1.0f };
GLfloat mat_diffuse[]= { 0.8f, 0.8f, 0.8f, 1.0f };
GLfloat mat_specular[] = { 1.0f, 1.0f, 1.0f, 1.0f };
GLfloat mat_shininess[] = { 50.0f };
GLfloat light0_diffuse[]= { 0.0f, 0.0f, 1.0f, 1.0f};
GLfloat light0_position[] = { 1.0f, 1.0f, 1.0f, 0.0f };
GLfloat light1_ambient[]= { 0.2f, 0.2f, 0.2f, 1.0f };
GLfloat light1_diffuse[]= { 1.0f, 0.0f, 0.0f, 1.0f };
GLfloat light1_specular[] = { 1.0f, 0.6f, 0.6f, 1.0f };
GLfloat light1_position[] = { -3.0f, -3.0f, 3.0f, 1.0f };
GLfloat spot_direction[]={ 1.0f, 1.0f, -1.0f};
//定义材质属性
glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient);
glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
glMaterialfv(GL_FRONT, GL_SHININESS,mat_shininess);
//light0为漫反射的蓝色点光源
glLightfv(GL_LIGHT0, GL_DIFFUSE, light0_diffuse);
glLightfv(GL_LIGHT0, GL_POSITION,light0_position);
//light1为红色聚光光源
glLightfv(GL_LIGHT1, GL_AMBIENT, light1_ambient);
glLightfv(GL_LIGHT1, GL_DIFFUSE, light1_diffuse);
glLightfv(GL_LIGHT1, GL_SPECULAR,light1_specular);
glLightfv(GL_LIGHT1, GL_POSITION,light1_position);
glLightf (GL_LIGHT1, GL_SPOT_CUTOFF, 30.0);
glLightfv(GL_LIGHT1, GL_SPOT_DIRECTION,spot_direction);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_LIGHT1);
glEnable(GL_DEPTH_TEST);
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
}
int main( int argc, char ** argv )
{
glutInit( &argc, argv );
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
glutInitWindowPosition( 100, 100 );
glutInitWindowSize( 400, 400 );
glutCreateWindow( "OpenGL Examples!" );
glutSpecialFunc(SpecialKeys);
glutDisplayFunc( display );
glutReshapeFunc(resize);
SetupRC();
glutMainLoop();
return 0;
}
3.创建光源
void glLightf(GLenum light, GLint pname,
GLfloat param);
功能:
设置光源属性
参数:
light: 指定光源(第几盏灯)
pname:设置光源的属性
param: pname的值,是一个浮点数
返回值:无
备注:
light可取下列值:
GL_LIGHT0, GL_LIGHT1, … GL_LIGHT7
pname可取下列值:
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)
例:
GLfloat LightSpotExponent = 10.0f; //聚光指数
GLfloat LightSpotCutoff = 20.0f; //聚光角度
glLightf( GL_LIGHT1,GL_SPOT_EXPONENT, LightSpotExponent );
glLightf( GL_LIGHT1, GL_SPOT_CUTOFF, LightSpotCutoff );
4.4控制光源的位置和方向
可以通过模型视点变换来改变光源的位置和方向
三种常见的光源变换
①光源位置固定
②光源绕静止的物体旋转
③光源随视点一起移动
光源位置固定
必须在视点变换或模型变换后,再次设置光源的位置
例:光源位置固定
void display(void)
{
//清屏
//……
//移动视点及绘图
//……
//重置光源的位置
glLoadIdentity();
GLfloat light_position[] = { 1.0, 1.0, 1.0, 1.0 };
glLightfv(GL_LIGHT0, GL_POSITION, light_position);
}
例:光源绕静止物体旋转
GLfloat light_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(xRot, 1.0, 0.0, 0.0);
glLightfv(GL_LIGHT0, GL_POSITION, light_position);
glPopMatrix();
glutSolidTorus (0.275, 0.85, 50, 50);
glPopMatrix();
实例:
#include
#include
GLfloat step = 0.0f;
void display()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();//重置当前指定的矩阵为单位矩阵
glColor3f( 1, 1, 0 );
glTranslated(0,0,-30);
glutSolidSphere(5,32,32);//画个球
glPopMatrix();
/*glColor3f(0,0,1);
glPushMatrix();//堆栈
glRotated(10,0,0,1);
glRotated(step,0,1,0);
glTranslated(0,0,20);
glutSolidSphere(3,32,32);
glPopMatrix();
*/
GLfloat light_position[] = { 0.0, 0.0, 0.5, 1.0 };
//glClear(GL_COLOR_BUFFER_BIT| GL_DEPTH_BUFFER_BIT);
glColor3f(0,0,1);
glPushMatrix();//堆栈
glRotated(10,0,0,1);
glLightfv(GL_LIGHT0, GL_POSITION, light_position);
glRotated(step,0,1,0);
glTranslated(0,0,10);//转悠的半径
glutSolidSphere(3,32,32);//画个球
glPopMatrix();
glutSwapBuffers();
}
void resize(int width, int height)
{
float ar = (float) width / (float) height;
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity() ;
glFrustum(-ar, ar, -1.0, 1.0, 2.0, 100.0);
glMatrixMode(GL_MODELVIEW);
}
void NormalKeys(unsigned char key, int x, int y)
{
switch(key)
{
case '1':
step += 5.0f;
break;
case '2':
step -= 5.0f;
break;
default:
break;
}
step = (GLfloat)((int)step % 360);
glutPostRedisplay();
}
void SetupRC()
{
glClearColor(0,0,0,1);
glEnable(GL_DEPTH_TEST);//启动光源
GLfloat light_ambient[] = { 0.0f, 0.0f, 0.0f, 1.0f };
GLfloat light_diffuse[] = { 1.0f, 1.0f, 1.0f, 1.0f };
GLfloat light_specular[] = { 1.0f, 1.0f, 1.0f, 1.0f };
GLfloat light_position[] = { 2.0f, 5.0f, 5.0f, 0.0f };
glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient);
glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse);
glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular);
glLightfv(GL_LIGHT0, GL_POSITION, light_position);
glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient);
glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse);
glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular);
glLightfv(GL_LIGHT0, GL_POSITION, light_position);
glEnable(GL_LIGHT0);
glEnable(GL_COLOR_MATERIAL);
glEnable(GL_LIGHTING);
}
int main( int argc, char ** argv )
{
glutInit( &argc, argv );
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
glutInitWindowPosition( 100, 100 );
glutInitWindowSize( 400, 400 );
glutCreateWindow( "OpenGL Examples!" );
glutKeyboardFunc(NormalKeys);
glutDisplayFunc( display );
glutReshapeFunc(resize);
SetupRC();
glutMainLoop();
return 0;
}
光源随物体一起旋转
#include
#include
GLfloat step = 0.0f;
GLfloat stepp = 0.0f;
void display()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
GLfloat position[] = { 0.0, 0.0, 1.5, 1.0 };
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushMatrix ();
gluLookAt (0.0, 0.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
glPushMatrix ();
glRotated ((GLdouble)stepp , 1.0, 0.0, 0.0);
glRotated ((GLdouble) step, 0.0, 1.0, 0.0);
glTranslated (0.0, 0.0, 1.5);
glLightfv (GL_LIGHT0, GL_POSITION, position);
glutSolidSphere (0.05,50,50);
glutSolidTorus (0.275, 0.85, 80, 150);
glPopMatrix ();
glPopMatrix();
glutSwapBuffers();
}
void resize(int width, int height)
{
float ar = (float) width / (float) height;
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity() ;
glFrustum(-ar, ar, -1.0, 1.0, 2.0, 100.0);
glMatrixMode(GL_MODELVIEW);
}
void NormalKeys(unsigned char key, int x, int y)
{
switch(key)
{
case '1':
step += 5.0f;
stepp += 7.0f;
break;
case '2':
step -= 5.0f;
stepp += 7.0f;
break;
default:
break;
}
step = (GLfloat)((int)step % 360);
glutPostRedisplay();
}
void SetupRC()
{
glClearColor(0,0,0,1);
glEnable(GL_DEPTH_TEST);//启动光源
GLfloat light_ambient[] = { 0.0f, 0.0f, 0.0f, 1.0f };
GLfloat light_diffuse[] = { 1.0f, 1.0f, 1.0f, 1.0f };
GLfloat light_specular[] = { 1.0f, 1.0f, 1.0f, 1.0f };
GLfloat light_position[] = { 2.0f, 5.0f, 5.0f, 0.0f };
glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient);
glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse);
glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular);
glLightfv(GL_LIGHT0, GL_POSITION, light_position);
glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient);
glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse);
glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular);
glLightfv(GL_LIGHT0, GL_POSITION, light_position);
glEnable(GL_LIGHT0);
glEnable(GL_COLOR_MATERIAL);
glEnable(GL_LIGHTING);
}
int main( int argc, char ** argv )
{
glutInit( &argc, argv );
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
glutInitWindowPosition( 100, 100 );
glutInitWindowSize( 400, 400 );
glutCreateWindow( "OpenGL Examples!" );
glutKeyboardFunc(NormalKeys);
glutDisplayFunc( display );
glutReshapeFunc(resize);
SetupRC();
glutMainLoop();
return 0;
}
实例2,诡异的光
#include
#include
GLfloat step = 0.0f;
GLfloat stepp = 0.0f;
void display()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
GLfloat position[] = { 0.0, 0.0, 1.5, 1.0 };
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushMatrix ();
gluLookAt (0.0, 0.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
glPushMatrix ();
glRotated ((GLdouble)stepp , 1.0, 0.0, 0.0);
glRotated ((GLdouble) step, 0.0, 1.0, 0.0);
glTranslated (0.0, 0.0, 1.5);
glLightfv (GL_LIGHT0, GL_POSITION, position);
glutSolidSphere (0.05,50,50);
glutSolidTorus (0.275, 0.85, 80, 150);
glPopMatrix ();
glPopMatrix();
glutSwapBuffers();
}
void resize(int width, int height)
{
float ar = (float) width / (float) height;
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity() ;
glFrustum(-ar, ar, -1.0, 1.0, 2.0, 100.0);
glMatrixMode(GL_MODELVIEW);
}
void NormalKeys(unsigned char key, int x, int y)
{
switch(key)
{
case '1':
step += 5.0f;
stepp += 7.0f;
break;
case '2':
step -= 5.0f;
stepp += 7.0f;
break;
default:
break;
}
step = (GLfloat)((int)step % 360);
glutPostRedisplay();
}
void SetupRC()
{
glClearColor(0,0,0,1);
glEnable(GL_DEPTH_TEST);//启动光源
GLfloat mat_ambient[]= { 0.2f, 0.2f, 0.2f, 1.0f };
GLfloat mat_diffuse[]= { 0.8f, 0.8f, 0.8f, 1.0f };
GLfloat mat_specular[] = { 1.0f, 1.0f, 1.0f, 1.0f };
GLfloat mat_shininess[] = { 50.0f };
GLfloat light0_diffuse[]= { 0.0f, 0.0f, 1.0f, 1.0f};
GLfloat light0_position[] = { 1.0f, 1.0f, 1.0f, 0.0f };
GLfloat light1_ambient[]= { 0.2f, 0.2f, 0.2f, 1.0f };
GLfloat light1_diffuse[]= { 1.0f, 0.0f, 0.0f, 1.0f };
GLfloat light1_specular[] = { 1.0f, 0.6f, 0.6f, 1.0f };
GLfloat light1_position[] = { -3.0f, -3.0f, 3.0f, 1.0f };
GLfloat spot_direction[]={ 1.0f, 1.0f, -1.0f};
//light0为漫反射的蓝色点光源
glLightfv(GL_LIGHT0, GL_DIFFUSE, light0_diffuse);
glLightfv(GL_LIGHT0, GL_POSITION,light0_position);
//light1为红色聚光光源
glLightfv(GL_LIGHT1, GL_AMBIENT, light1_ambient);
glLightfv(GL_LIGHT1, GL_DIFFUSE, light1_diffuse);
glLightfv(GL_LIGHT1, GL_SPECULAR,light1_specular);
glLightfv(GL_LIGHT1, GL_POSITION,light1_position);
glLightf (GL_LIGHT1, GL_SPOT_CUTOFF, 30.0);
glLightfv(GL_LIGHT1, GL_SPOT_DIRECTION,spot_direction);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_LIGHT1);
glEnable(GL_DEPTH_TEST);
glEnable(GL_LIGHT0);
glEnable(GL_COLOR_MATERIAL);
glEnable(GL_LIGHTING);
}
int main( int argc, char ** argv )
{
glutInit( &argc, argv );
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
glutInitWindowPosition( 100, 100 );
glutInitWindowSize( 400, 400 );
glutCreateWindow( "OpenGL Examples!" );
glutKeyboardFunc(NormalKeys);
glutDisplayFunc( display );
glutReshapeFunc(resize);
SetupRC();
glutMainLoop();
return 0;
}
5.选择光照模型
OpenGL光照模型包括4项内容
全局环境光强度
观察点靠近场景还是位于无穷远处
单面光照或双面光照
镜面反射颜色是否独立于环境颜色、散射颜色(OpenGL 1.4)
选择光照模型的函数
glLightModelfv(…);
glLightModeli(…);
void glLightModelfv(GLenum pname, GLfloat* param);
功能:
选择光照模型
参数:
pname: 光照模型的类型
param: 该类型值的数组地址
返回值:无
备注:
pname可以取值为:
GL_LIGHT_MODEL_AMBIENT 整个场景的RGBA强度(0.2, 0.2, 0.2, 1.0)
环境光
经过多次反射而来的光称为环境光,无法确定其最初的方向,但当特定的光源关闭后,它们将消失。
全局环境光
每个光源都能对场景提供环境光。此外,还有一个环境光,它不来自任何特定的光源,称之为全局环境光。这也就是为什么我们不加任何自定义光源,也能看见绘制的物体的原因。
例:设置全局环境光颜色
GLfloat lmodel_ambient[] = { 0.2, 0.2, 0.2, 1.0 };
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient);
void glLightModeli(GLenum pname, GLint param);
功能:
选择光照模型
参数:
pname: 光照模型的类型
param: 该类型的值
返回值:无
备注:
pname可以取值为:
GL_LIGHT_MODEL_LOCAL_VIEWER //观察点是否无穷远(GL_FALSE)
GL_LIGHT_MODEL_TWO_SIDE //单面还是双面光照(GL_FALSE )
观察点靠近物体还是无穷远
在视点无穷远的情况下,场景中任何顶点到视点的方向都是同一常数。
否则,则不然,但效果会更加真实
例:设置观察点无穷远
glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE);
单面光照或双面光照
多边形的正面和背面是否都需要光照
例:指定双面光照
glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
6.设置材质属性
启用光照时,物体顶点的颜色信息将被忽略
启用光照时,物体顶点的颜色取决于光源的颜色和物体材质的颜色.
设置材质属性
void glMaterialfv(GLenum face, GLenum pname, GLfloat* param);
功能:指定材质属性
参数:
face: 指定正面或背面的材质
pname: 指定要设置哪种材质属性
param: 属性值的数组地址
返回值:无
备注:
face可取如下值:
GL_FRONT
GL_BACK
GL_FRONT_AND_BACK
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)
例:散射和环境光反射
GLfloat mat_amb_diff[] = { 0.1, 0.5, 0.8, 1.0 };
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, mat_amb_diff);
例:镜面反射材质
GLfloat mat_specular[] = { 1.0, 1.0, 1.0, 1.0 };
GLfloat low_shininess[] = { 5.0 };
glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
glMaterialfv(GL_FRONT, GL_SHININESS, low_shininess);
例:发射光颜色
GLfloat mat_emission[] = {0.3, 0.2, 0.2, 0.0};
glMaterialfv(GL_FRONT, GL_EMISSION, mat_emission);
#include
#include
GLfloat diffuseMaterial[4] = { 0.5, 0.5, 0.5, 1.0 };
// 初始化材质特性、光源、光照模型和深度缓冲
void init(void)
{
GLfloat mat_specular[] = { 1.0, 1.0, 1.0, 1.0 };
GLfloat light_position[] = { 1.0, 1.0, 1.0, 0.0 };
glClearColor (0.0, 0.0, 0.0, 0.0);
glShadeModel (GL_SMOOTH);
glEnable(GL_DEPTH_TEST);
glMaterialfv(GL_FRONT, GL_DIFFUSE, diffuseMaterial);
glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
glMaterialf(GL_FRONT, GL_SHININESS, 25.0);
glLightfv(GL_LIGHT0, GL_POSITION, light_position);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glColorMaterial(GL_FRONT, GL_DIFFUSE);
glEnable(GL_COLOR_MATERIAL);
}
void display()
{
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glTranslated(0,0,-4);
glutSolidSphere(1.0, 32, 32);
glutSwapBuffers();
}
void resize(int width, int height)
{
float ar = (float) width / (float) height;
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity() ;
gluPerspective(45.0, ar, 1.0, 100.0);
glMatrixMode(GL_MODELVIEW);
}
void normalKeys(unsigned char key, int x, int y)
{
switch (key)
{
case '1':
diffuseMaterial[0] += 0.1;
if (diffuseMaterial[0] > 1.0)
diffuseMaterial[0] = 0.0;
break;
case '2':
diffuseMaterial[1] += 0.1;
if (diffuseMaterial[1] > 1.0)
diffuseMaterial[1] = 0.0;
break;
case '3':
diffuseMaterial[2] += 0.1;
if (diffuseMaterial[2] > 1.0)
diffuseMaterial[2] = 0.0;
break;
}
glColor4fv(diffuseMaterial);
glutPostRedisplay();
}
int main( int argc, char ** argv )
{
glutInit( &argc, argv );
glutInitDisplayMode( GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowPosition( 300, 200 );
glutInitWindowSize( 400, 400 );
glutCreateWindow( "OpenGL Examples!" );
init();
glutDisplayFunc( display );
glutReshapeFunc(resize);
glutKeyboardFunc(normalKeys);
glutMainLoop();
return 0;
}
实例2:
#include
#include
GLfloat nr=200.0;
void init(void)
{
GLfloat ambient[] = { 0.0, 0.0, 0.0, 1.0 };
GLfloat diffuse[] = { 1.0, 1.0, 1.0, 1.0 };
GLfloat position[] = { 0.0, 3.0, 2.0, 0.0 };
GLfloat lmodel_ambient[] = { 0.4, 0.4, 0.4, 1.0 };
GLfloat local_view[] = { 0.0 };
glClearColor(0.0, 0.1, 0.1, 0.0);
glEnable(GL_DEPTH_TEST);
glShadeModel(GL_SMOOTH);
glLightfv(GL_LIGHT0, GL_AMBIENT, ambient);
glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse);
glLightfv(GL_LIGHT0, GL_POSITION, position);
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient);
glLightModelfv(GL_LIGHT_MODEL_LOCAL_VIEWER, local_view);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
}
void display(void)
{
GLfloat no_mat[] = { 0.0, 0.0, 0.0, 1.0 };
GLfloat mat_ambient[] = { 0.7, 0.7, 0.7, 1.0 };
GLfloat mat_ambient_color[] = { 1.0, 0.0, 0.0, 1.0 };
GLfloat mat_diffuse[] = { 0.1, 0.5, 0.8, 1.0 };
GLfloat mat_specular[] = { 1.0, 1.0, 1.0, 1.0 };
GLfloat no_shininess[] = { 0.0 };
GLfloat low_shininess[] = { 5.0 };
GLfloat high_shininess[] = { 200.0 };
GLfloat mat_emission[] = {0.3, 0.2, 0.2, 0.0};
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
/* draw sphere in first row, first column
* diffuse reflection only; no ambient or specular
*/
glPushMatrix();
glTranslatef (-3.75, 3.0, 0.0);
glMaterialfv(GL_FRONT, GL_AMBIENT, no_mat);
glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
glMaterialfv(GL_FRONT, GL_SPECULAR, no_mat);
glMaterialfv(GL_FRONT, GL_SHININESS, no_shininess);
glMaterialfv(GL_FRONT, GL_EMISSION, no_mat);
glutSolidSphere(1.0, nr, nr);
//glutSolidTeapot(1.0);
glPopMatrix();
/* draw sphere in first row, second column
* diffuse and specular reflection; low shininess; no ambient
*/
glPushMatrix();
glTranslatef (-1.25, 3.0, 0.0);
glMaterialfv(GL_FRONT, GL_AMBIENT, no_mat);
glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
glMaterialfv(GL_FRONT, GL_SHININESS, low_shininess);
glMaterialfv(GL_FRONT, GL_EMISSION, no_mat);
glutSolidSphere(1.0, nr, nr);
glPopMatrix();
/* draw sphere in first row, third column
* diffuse and specular reflection; high shininess; no ambient
*/
glPushMatrix();
glTranslatef (1.25, 3.0, 0.0);
glMaterialfv(GL_FRONT, GL_AMBIENT, no_mat);
glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
glMaterialfv(GL_FRONT, GL_SHININESS, high_shininess);
glMaterialfv(GL_FRONT, GL_EMISSION, no_mat);
glutSolidSphere(1.0, nr, nr);
glPopMatrix();
/* draw sphere in first row, fourth column
* diffuse reflection; emission; no ambient or specular reflection
*/
glPushMatrix();
glTranslatef (3.75, 3.0, 0.0);
glMaterialfv(GL_FRONT, GL_AMBIENT, no_mat);
glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
glMaterialfv(GL_FRONT, GL_SPECULAR, no_mat);
glMaterialfv(GL_FRONT, GL_SHININESS, no_shininess);
glMaterialfv(GL_FRONT, GL_EMISSION, mat_emission);
glutSolidSphere(1.0, nr, nr);
glPopMatrix();
/* draw sphere in second row, first column
* ambient and diffuse reflection; no specular
*/
glPushMatrix();
glTranslatef (-3.75, 0.0, 0.0);
glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient);
glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
glMaterialfv(GL_FRONT, GL_SPECULAR, no_mat);
glMaterialfv(GL_FRONT, GL_SHININESS, no_shininess);
glMaterialfv(GL_FRONT, GL_EMISSION, no_mat);
glutSolidSphere(1.0, nr, nr);
glPopMatrix();
/* draw sphere in second row, second column
* ambient, diffuse and specular reflection; low shininess
*/
glPushMatrix();
glTranslatef (-1.25, 0.0, 0.0);
glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient);
glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
glMaterialfv(GL_FRONT, GL_SHININESS, low_shininess);
glMaterialfv(GL_FRONT, GL_EMISSION, no_mat);
glutSolidSphere(1.0, nr, nr);
glPopMatrix();
/* draw sphere in second row, third column
* ambient, diffuse and specular reflection; high shininess
*/
glPushMatrix();
glTranslatef (1.25, 0.0, 0.0);
glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient);
glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
glMaterialfv(GL_FRONT, GL_SHININESS, high_shininess);
glMaterialfv(GL_FRONT, GL_EMISSION, no_mat);
glutSolidSphere(1.0, nr, nr);
glPopMatrix();
/* draw sphere in second row, fourth column
* ambient and diffuse reflection; emission; no specular
*/
glPushMatrix();
glTranslatef (3.75, 0.0, 0.0);
glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient);
glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
glMaterialfv(GL_FRONT, GL_SPECULAR, no_mat);
glMaterialfv(GL_FRONT, GL_SHININESS, no_shininess);
glMaterialfv(GL_FRONT, GL_EMISSION, mat_emission);
glutSolidSphere(1.0, nr, nr);
glPopMatrix();
/* draw sphere in third row, first column
* colored ambient and diffuse reflection; no specular
*/
glPushMatrix();
glTranslatef (-3.75, -3.0, 0.0);
glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient_color);
glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
glMaterialfv(GL_FRONT, GL_SPECULAR, no_mat);
glMaterialfv(GL_FRONT, GL_SHININESS, no_shininess);
glMaterialfv(GL_FRONT, GL_EMISSION, no_mat);
glutSolidSphere(1.0, nr, nr);
glPopMatrix();
/* draw sphere in third row, second column
* colored ambient, diffuse and specular reflection; low shininess
*/
glPushMatrix();
glTranslatef (-1.25, -3.0, 0.0);
glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient_color);
glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
glMaterialfv(GL_FRONT, GL_SHININESS, low_shininess);
glMaterialfv(GL_FRONT, GL_EMISSION, no_mat);
glutSolidSphere(1.0, nr, nr);
glPopMatrix();
/* draw sphere in third row, third column
* colored ambient, diffuse and specular reflection; high shininess
*/
glPushMatrix();
glTranslatef (1.25, -3.0, 0.0);
glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient_color);
glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
glMaterialfv(GL_FRONT, GL_SHININESS, high_shininess);
glMaterialfv(GL_FRONT, GL_EMISSION, no_mat);
glutSolidSphere(1.0, nr, nr);
glPopMatrix();
/* draw sphere in third row, fourth column
* colored ambient and diffuse reflection; emission; no specular
*/
glPushMatrix();
glTranslatef (3.75, -3.0, 0.0);
glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient_color);
glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
glMaterialfv(GL_FRONT, GL_SPECULAR, no_mat);
glMaterialfv(GL_FRONT, GL_SHININESS, no_shininess);
glMaterialfv(GL_FRONT, GL_EMISSION, mat_emission);
glutSolidSphere(1.0, nr, nr);
glPopMatrix();
glutSwapBuffers();
}
void resize(int width, int height)
{
float ar = (float) width / (float) height;
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
//glFrustum(-ar, ar, -1.0, 1.0, 2.0, 100.0);
glOrtho (-5, 5, -5, 5, -20.0, 20.0);
glMatrixMode(GL_MODELVIEW);
}
int main(int argc, char** argv)
{
glutInit( &argc, argv );
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
glutInitWindowPosition( 300, 200 );
glutInitWindowSize( 600, 600 );
glutCreateWindow( "OpenGL Examples!" );
init();
glutDisplayFunc( display );
glutReshapeFunc(resize);
glutMainLoop();
return 0;
}