正式接触OPENGL也已经超过一年了,自我感觉已经入门了,在菜鸟中也是一只老鸟了。或者也可以自大地说OPENGL太简单了,就一个状态机而已。然而,这个状态机,我又知多少呢。
撇开平台的关系,OPENGL整个程序涉及了那些函数呢。有点忘了,赶紧整理了一下。
首先,我们先不是面向对象编程,还是面向过程的。虽然面向对象编程很流行了,不过对于理解最简单的OPENGL,用它就太麻烦了。
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH);
glutInitWindowSize(800, 600);
glutCreateWindow("3D Effects Demo");
glutReshapeFunc(ChangeSize);
glutKeyboardFunc(KeyPressFunc);
glutDisplayFunc(RenderScene);
SetupRC();
glutMainLoop();
glDeleteTextures(4,textures);
return0;
}
这几个函数接触过OPENGL的人应该都会有印象的。但是习惯了MFC之后,很多函数没有用过了,也已经忘得差不多了。还是把各个函数整理下吧。
glutInit这个函数,我从来没有去改变过他,顾名思义,知道它是初始化的,就不管它了。
glutInitDisplayMode显然是用来设置显示模式的,正常情况下和上面设置的一样,双缓冲、使用RGBA颜色模式、使用深度缓存。当然想用其它缓存的时候应该也要设置这个函数。至于可否在程序运行过程中改变设置,我就不知道了。
glutInitWindowSize,显然只是用来设置窗口大小的,没其它的作用了。
glutCreateWindow,创建一个窗口,仅有一个参数记录窗口的显示标题。
glutReshapeFunc
void glutReshapeFunc(void (*func)(int width, int height));
用户可以自己写一个函数,然后接收两个参数之后,做一定的工作。通常是为了避免在窗口大小变化的过程中显示的内容扭曲失真。
glutKeyboardFunc
void glutKeyboardFunc(void (*func)(unsigned char key, int x, int y));
用户可以自定义一个键盘响应函数,它有三个参数,第一个用来接收键盘按键的ASCII值,后两个是鼠标在屏幕上的位置。
当然在glut库里面还有一个响应鼠标事件的函数glutMouseFunc,void glutMouseFunc(void (*func)(int button, int state, int x, int y))。还有鼠标移动事件等等的响应函数。
glutDisplayFunc,void glutDisplayFunc(void (*func)(void));
这个函数就不用解释了吧,在里面随便写就好了。
SetupRC,用户在里面自己对纹理啊什么做设置的函数,稍微大点的程序都会有的。
glutMainLoop这个函数的作用当然是启动整个过程了,至于它底层是怎么运行的,没有去查过,我想也没这个必要。
除了以Func结尾的这几个函数所调用的函数和SetupRC需要用户自己写以外,其他的东西相对来说很固定了。
下面具体说一下 void glutReshapeFunc(void (*func)(int width, int height));
通常情况,个人觉得,用户在这里自定义的函数做的工作主要有两个,投影变换和视口变换。
{
glViewport(0,0,(GLsizei)w,(GLsizei)h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glFrustum(-1.0,1.0,-1.0,1.0,1.5,20.0);
glMatrixMode(GL_MODELVIEW);
}
glViewport属于视口变换,void glViewport(GLint x, GLint y, GLsizei width, GLsizei height); (x,y)参数指定了视口左下角,width 和 height 表示这个视口矩阵的宽度和高度。实际上用于视口变化的函数就两个,除了这个之外,就是glDepthRange,这个我很少用,具体的影响到底是怎样,我也没察觉出来。个人觉得可以暂时忽略。
其他的都是和变换有关了。glMatrixMode,void glMatrixMode(GLenum mode); 他有三种模式可以选择,GL_MODELVIEW,GL_PROJECTION,GL_TEXTURE。在改变投影的时候,参数显然是GL_PROJECTION。glLoadIndentity()这个函数在各种变换下都是可用的,主要就是把当前的Matrix设置为单位矩阵,即初始状态。只为投影变换设计的函数,这里是glFrustum,void glFrustum(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble near, GLdouble far),用来设定六个平行截头,即六个面。这个函数的使用,个人觉得比较难,它应该要与gluLookAt这类函数配合使用,所以通常情况下,人们更经常使用gluPerspective来进行投影变换。void gluPerspective(GLdouble fovy, GLdouble aspect, GLdouble near, GLdouble far),fovy是yz平面上视野的角度,它的值必须在[0.0,180.0]的范围之内。aspect是这个平截头体的纵横比,也就是它的宽度除以高度。
这个函数被调用完毕之后,当然,我们要把矩阵的模式设置成GL_MODELVIEW。然后就可以显示我们自己“画”的那些内容了。
“画”就在glutDisplayFunc,void glutDisplayFunc(void (*func)(void)) 自定义的函数中,这里就是RenderScene
{
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1.0f,1.0f,1.0f);
glLoadIdentity();
gluLookAt(0.0,0.0,5.0,0.0,0.0,0.0,0.0,1.0,0.0);
glScalef(1.0f,2.0f,1.0f);
glutWireCube(1.0);
glutSwapBuffers();
}
glClear这个函数用来在每次重画之前,把上一次画的东西去掉。然后在GL_MODELVIEW模式下画自己想要的东西,这个这里就不多说了,内容太多了,以后有空再整理整理。
程序在实际中的初始运行顺序,main入口->SetupRc->changeSize->RenderScene。