随感而发

杂七杂八

统计

留言簿(13)

阅读排行榜

评论排行榜

OpenGL学习笔记【6】——初学光照

今天学习了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(130,30);//利用库函数绘制一个半径为1的球体。
    glPopMatrix();            //弹出矩阵。

    glutSwapBuffers();            
//交换缓冲区。显示图形
}


//初始化
void init (void
{
    glClearColor (
0.50.50.50.0);    //清理颜色,为黑色,(也可认为是背景颜色)
    GLfloat light_param[] = 1110.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, 01000);    //设置投影矩阵
    glMatrixMode(GL_MODELVIEW);        //设置矩阵模式为视图矩阵(模型)
    glLoadIdentity();                //变为单位矩阵
}


void Keyboard(unsigned char key, int x, int y)
{
    
if (key == '1')
    
{
        GLfloat light_param[] 
= 5.05.0-1.0,1.0 };
        glLightfv(GL_LIGHT0, GL_POSITION, light_param);
    }

    
else if (key == '2')
    
{
        GLfloat light_param[] 
= 0.00.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 (
250250);            //窗口大小
    glutInitWindowPosition (100100);        //窗口位置
    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_LIGHT0GL_POSITIONlight_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没有这么学好。不过没有关系,我会一直努力下去的。加油。。


posted on 2009-04-28 00:28 shongbee2 阅读(4537) 评论(3)  编辑 收藏 引用 所属分类: OpenGL

评论

# re: OpenGL学习笔记【6】——初学光照 2009-04-28 21:49 Leaf

嗯,加油哦,我们计算机图形学用的就是OPENGL,要是觉得难理解的话,可以参考一下 计算机图形学第三版 绿色的那本。
了解原理再学这个,你会发现很轻松~~  回复  更多评论   

# re: OpenGL学习笔记【6】——初学光照 2009-04-28 22:29 shongbee2

@Leaf
计算机图形学第三版我,我记住了。谢谢您。。
我一定会去看的。  回复  更多评论   

# re: OpenGL学习笔记【6】——初学光照 2010-03-18 18:23 bill

版主加油~  回复  更多评论   


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理