OpenGL是图形硬件的一种软件接口。这个接口包含的函数超过700个(纳入OpenGL 3.0的函数大约有670个,另外50个函数位于OpenGL工具库中),这些函数可以用于指定物体和操作,创建交互式的三维应用程序。
OpenGL的设计目标就是作为一种流线型的、独立于硬件的接口,在许多不同的硬件平台上实现。为了实现这个目标,OpenGL并未包含用于执行窗口任务或者获取用户输入之类的函数。反之,必须通过具体的窗口系统来控制OpenGL应用程序所使用的特定硬件。类似地,OpenGL并没有提供用于描述三维物体模型的高级函数。这类函数可能允许指定相对较为复杂的形状,例如汽车、身体的某个部位、飞机或分子等。在OpenGL中,程序员必须根据一些为数不多的基本几何图元(如点、直线和多边形)来创建所需要的模型。
程序员可以在OpenGL的基础之上,创建提供这些特性的高级函数库。OpenGL工具库(GLU)提供了许多建模功能,例如二次曲面以及NURBS曲线和表面。GLU是所有OpenGL实现的一个标准组成部分。
1.线框模型(wireframe model)
2.深度提示(depth-cued),大气效果(合称为雾)来实现深度提示
3.抗锯齿(antialiased),像素(pixel)
4.单调着色(flat-shading)
5.平滑着色(smooth-shading)
6..阴影(shadow)和纹理(texture)效果,纹理贴图(texture mapping)允许把一幅二维图像应用到一个三维物体上。
7.运动模糊(motion-blurred)
8.图像实际上只不过是三维物体模型的一张快照而已。
9.雾,用它来模拟空气中的烟尘。
10.景深效果(depth-of-field effect),它模拟了照相机无法对场景中的所有物体进行聚焦的现象。
OpenGL对场景中的图像进行渲染时所执行的主要图形操作:
1) 根据几何图元创建形状,从而建立物体的数学描述。
2) 在三维空间中排列物体,并选择观察复合场景的有利视角。
3) 计算所有物体的颜色。
获取颜色
方法:
可以由应用程序明确指定;
可以根据特定的光照条件确定;
可以通过把纹理贴到物体的表面而获得;
或者是上述三种操作的混合产物;
操作:
可能使用着色器来执行,这样可以显式地控制所有的颜色计算;
可能使用OpenGL的预编程算法在其内部执行(我们常用术语固定功能的管线来表示后者)。
4) 把物体的数学描述以及与物体相关的颜色信息转换为屏幕上的像素。这个过程叫做光栅化(rasterization)。
术语:
渲染(rendering)是计算机根据模型创建图像的过程;
模型(model)是根据几何图元创建的,也称为物体(object);几何图元包括点、直线和多边形等,它们是通过顶点(vertex)指定的。
最终完成了渲染的图像是由在屏幕上绘制的像素组成的。在内存中,和像素有关的信息(例如像素的颜色)组织成位平面(bitplane)的形式。
位平面是一块内存区域,保存了屏幕上每个像素的1个位的信息。例如,它指定了一个特定像素的颜色中红色成分的强度。位平面又可以组织成帧缓冲区(framebuffer)的形式,后者保存了图形硬件为了控制屏幕上所有像素的颜色和强度所需要的全部信息。
glClearColor(0.0,0.0,0.0,0.0)函数确定了窗口将清除成什么颜色;
glClear(GL_COLOR_BUFFER_BIT)函数实际完成清除窗口的任务;
glColor3f()函数确定了绘制物体时所使用的颜色,所有绘制的物体都将使用这种颜色,除非再次调用这个函数更改绘图颜色。
glFlush()函数保证了绘图命令将实际执行,而不是存储在缓冲区中等待其他的OpenGL命令。
窗口管理
GLUT通过几个函数执行初始化窗口所需要的任务:
glutInit (int *argc, char **argv) 对GLUT进行初始化,并处理所有的命令行参数(对于X系统,这将是类似-display和-geometry的选项)。
glutInit()应该在调用其他任何GLUT函数之前调用。
glutInitDisplayMode (unsigned int mode) 指定了是使用RGBA模式还是颜色索引模式。另外还可以指定是使用单缓冲还是使用双缓冲窗口。如果想使用颜色索引模式,就需要把一些颜色加载到颜色映射表中,这个任务可以用glutSetColor()完成。最后,还可以使用这个函数表示希望窗口拥有相关联的深度、模板、多重采样和/或累积缓冲区。例如,如果需要一个双缓冲、RGBA颜色模式以及带有一个深度缓冲区的窗口, 可以调用glutInitDisplay Mode(GLUT_ DOUBLE |GLUT_RGBA | GLUT_DEPTH)。 glutInitWindowPosition (int x, int y) 指定了窗口左上角的屏幕位置。
glutInitWindowSize (int width, int size) 指定了窗口的大小(以像素为单位)。
glutInitContextVersion(int majorVersion, int minorVersion)声明了要使用OpenGL的哪个版本。
glutInitContextFlags(int flags)声明了想要使用的OpenGL渲染环境的类型。对于常规的OpenGL操作,可以在自己的程序中省略这一调用,然而,如果想要使用向前兼容的OpenGL渲染环境,需要调用这一函数。
int glutCreateWindow (char *string)创建了一个支持OpenGL渲染环境的窗口。这个函数返回一个唯一的标识符,标识了这个窗口。注意:在调用glutMainLoop()函数之前,这个窗口并没有显示。 显示回调函数 glutDisplayFunc (void (*func)(void)) 是读者所看到的第一个也是最为重要的事件回调函数。每当GLUT确定一个窗口的内容需要重新显示时,通过glutDisplayFunc()注册的那个回调函数就会被执行。因此,应该把重绘场景所需要的所有代码都放在这个显示回调函数里。 如果程序修改了窗口的内容,有时候可能需要调用glutPostRedisplay(),这个函数将会指示调用已注册的显示回调函数。
glutMainLoop()事件处理循环开始启动,已注册的显示回调函数被触发。
处理输入事件
可以使用下面这些函数注册一些回调函数,当指定的事件发生时,这些函数便会被调用:
glutReshapeFunc(void(*func)int w, int h))表示当窗口的大小发生改变时应该采取什么行动。
glutKeyboardFunc (void(*func)(unsigned char key, int x, int y))和glutMouseFunc(void(*func)(intbutton, int state, int x, int y))允许把键盘上的一个键或鼠标上的一个按钮与一个函数相关联,当这个键或按钮被按下或释放时,这个函数就会调用。
glutMotionFunc(void(*func)(int x, int y))注册了一个函数,当按下一个鼠标按钮移动鼠标时,这个函数就会调用。
空闲处理
可以在glutIdleFunc(void(*func)(void))回调函数中指定一个函数,如果不存在其他尚未完成的事件(例如,当事件循环处于空闲的时候),就执行这个函数。这个回调函数接受一个函数指针作为它的唯一参数。如果向它传递NULL(0),就相当于禁用这个函数。
GLUT包含了几个函数,用于绘制下面这些三维物体:
圆锥体
二十面体
茶壶
立方体
八面体
四面体
十二面体
球体
圆环面