今天学习了OpenGL的光照,我觉得我以前学习OpenGL的方法有写不对,试着改变一下。换一本书。坚持,我不想就这么放弃。。
OpenGL光照就使用OpenGL的函数给世界带来光,他的具体什么数学知识,光线的原理啊,什么的,我现在都不知道。以后再去了解一下,毕竟这些都是数学家做的事情,我没有那么厉害全部搞定,只能用现成的东西:OpenGL提供的函数来实现光照。
首先奉上源代码:按键盘1,2,3,4,5,6,7来控制光的属性:
#pragma comment(lib, "glaux.lib")
#include "gl\glaux.h"
#include <gl\glut.h>
void display(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // 清楚颜色数据和深度数据(清屏)
glColor3f(1.0,1.0,1.0);
glLoadIdentity(); //初始变换矩阵为单位矩阵
glPushMatrix(); //压入变换矩阵那
glTranslated(0,0,-5); //平移0,0,-5向Z负方向平移5个单位
glutSolidSphere(1, 30,30);//利用库函数绘制一个半径为1的球体。
glPopMatrix(); //弹出矩阵。
glutSwapBuffers(); //交换缓冲区。显示图形
}
//初始化
void init (void)
{
glClearColor (0.5, 0.5, 0.5, 0.0); //清理颜色,为黑色,(也可认为是背景颜色)
GLfloat light_param[] = { 1, 1, 1, 0.0 }; //初始化光参数。
glLightfv(GL_LIGHT0, GL_AMBIENT, light_param); //设置光为环境光。
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glCullFace(GL_BACK);
glEnable(GL_CULL_FACE);
glDepthFunc(GL_LEQUAL);
glEnable(GL_DEPTH_TEST);
}
//当窗口大小改变时,会调用这个函数
void reshape(GLsizei w,GLsizei h)
{
//这里小说明一下:矩阵模式是不同的,他们各自有一个矩阵。投影相关
//只能用投影矩阵。(只是目前情况下哦,等我学多了可能就知道为什么了。)
glViewport(0,0,w,h); //设置视口
glMatrixMode(GL_PROJECTION); //设置矩阵模式为投影变换矩阵,
glLoadIdentity(); //变为单位矩阵
gluPerspective(60, (GLfloat)w / h, 0, 1000); //设置投影矩阵
glMatrixMode(GL_MODELVIEW); //设置矩阵模式为视图矩阵(模型)
glLoadIdentity(); //变为单位矩阵
}
void Keyboard(unsigned char key, int x, int y)
{
if (key == '1')
{
GLfloat light_param[] = { 5.0, 5.0, -1.0,1.0 };
glLightfv(GL_LIGHT0, GL_POSITION, light_param);
}
else if (key == '2')
{
GLfloat light_param[] = { 0.0, 0.0, -1.0,1.0 };
glLightfv(GL_LIGHT0, GL_POSITION, light_param);
}
else if (key == '3')
{
GLfloat light_ambient[4] = {0.8,0.8,0.8,1.0};
glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient);
}
else if (key == '4')
{
GLfloat light_ambient[4] = {0.8,0.8,0.0,1.0};
glLightfv(GL_LIGHT0, GL_DIFFUSE, light_ambient);
}
else if (key == '5')
{
GLfloat light_ambient[4] = {0.0,0.0,0.8,1.0};
glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient);
}
else if (key == '6')
{
GLfloat light_ambient[4] = {1.0,0.0,1.0,1.0};
glLightfv(GL_LIGHT0, GL_SPECULAR, light_ambient);
}
else if (key == '7')
{
GLfloat light_ambient[4] = {1.0,0.0,0.0,1.0};
glLightfv(GL_LIGHT1, GL_DIFFUSE, light_ambient);
glEnable(GL_LIGHT1);
}
glutPostRedisplay();
}
int main(int argc, char** argv)
{
glutInit(&argc, argv); //Opnegl初始化
glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGBA); //设置显示模式为双缓冲,RGEBA
glutInitWindowSize (250, 250); //窗口大小
glutInitWindowPosition (100, 100); //窗口位置
glutCreateWindow ("hello"); //创建一个标题为hello的窗口
init (); //初始化资源,这里一定要在创建窗口以后,不然会无效。
glutDisplayFunc(display); //窗口大小改变时的回调
glutReshapeFunc(reshape); //绘制图形时的回调
glutKeyboardFunc(Keyboard);
glutMainLoop(); //主循环。
return 0;
}
OpenGL有五种光,环境光,点光源,漫反射光,镜面反射光,聚光源。OpenGL可以使用GL_LIGHT0-GL_LIGHT7七 盏光。
每种关具体的参数请看书上的表:
pname 参数名
|
缺省值
|
说明
|
GL_AMBIENT
|
(0.0, 0.0, 0.0, 1.0)
|
RGBA模式下环境光
|
GL_DIFFUSE
|
(1.0, 1.0, 1.0, 1.0)
|
RGBA模式下漫反射光
|
GL_SPECULAR
|
(1.0,1.0,1.0,1.0)
|
RGBA模式下镜面光
|
GL_POSITION
|
(0.0,0.0,1.0,0.0)
|
光源位置齐次坐标(x,y,z,w)
|
GL_SPOT_DIRECTION
|
(0.0,0.0,-1.0)
|
点光源聚光方向矢量(x,y,z)
|
GL_SPOT_EXPONENT
|
0.0
|
点光源聚光指数
|
GL_SPOT_CUTOFF
|
180.0
|
点光源聚光截止角
|
GL_CONSTANT_ATTENUATION
|
1.0
|
常数衰减因子
|
GL_LINER_ATTENUATION
|
0.0
|
线性衰减因子
|
GL_QUADRATIC_ATTENUATION
|
0.0
|
平方衰减因子
|
表10-1 函数glLight*()参数pname说明
设置光源:
我们先对启用关照才能使用光源,启用光照的函数是:
glEnable(GL_LIGHTING);
然后我们可以使用:
glEnable(GL_LIGHT0);
来启用GL_LIGHT0这个光。
基本知识就学了这么多,然后是使用它的过程,
glEnable(GL_LIGHTING);
GLfloat light_param[] = { 5.0, 5.0, -1.0,1.0 };
glLightfv(GL_LIGHT0, GL_POSITION, light_param);
glEnable(GL_LIGHT0);
放在程序的init函数里面,因为这是初始化的一部分。
他的意思就是启用光照,设置GL_LIGHT0的属性为点光源,他为位置是:[5.0,5.0,-1.0,1.0]对应的其次坐标。我也不知道他具体做什么,现在就当做是他的坐标吧。
这次加了一个键盘监听的处理函数。可以响应键盘按键了,在这个程序中用1,2,3,4等键可以切换灯光。
这次学习的疑惑:
点光源:就是从一点发出的光源,向四周扩散,就相当于一个火把,一个灯泡类型的光。所以他的位置就决定了他的照射的状态。但是奇怪我怎么设置它的光的属性啊,例如我想用一个红色的点光源怎么办?继续学习。他的位置书上说是一个其次坐标,有什么用了,我也不知道。
其他光源的的参数就是个颜色分量的强度,1.0是最强的,0是没有,所以通过个子分量的强度来达到光的效果。不过在我眼里就是颜色的问题。0.5,0.5,0.5就是灰色,1.0,0,0就是红色。呵呵。不过不知道他第四个参数有什么用。什么试了也没有反应,感觉没有效果。
感觉每个GL_LIGHT0都能过设置所有的光源效果,而且是可以叠加的,就是我可以只用GL_LIGHT0可以实现环境光,漫反射光,点光源等。所以要小心,如果你开始设置glLightfv(GL_LIGHT0, GL_POSITION, XXX)的话,然后在重新设置环境光,这里GL_LIGHT0会有两种都有。所以在使用的时候要小心一些。呵呵。
光的衰减还没有学会,继续努力。
感觉OpenGL没有这么学好。不过没有关系,我会一直努力下去的。加油。。