参考:
1.《计算机图形学(第四版)》Donald Hearn等著
2. https://blog.csdn.net/yqxx/article/details/382519
OpenGL被设计成与硬件无关的,因此包括输入输出函数等的许多操作并不包括在其基本库中,它们被包含在为OpenGL开发的辅助库中。
基本库(核心库)
OpenGL基本库(也称为OpenGL核心库),其中的函数均以 gl 开头,比如:glBegin, glClear等。
有些函数要求参数用符号常量赋值,这些常量均以大写GL开头,单词均采用大写形式,与GL用下划线_隔开,比如:GL_2D, GL_RGB。
OpenGL采用专门的内置数据类型名称来描述数据类型,避免数据类型在不同机器上的差异,比如:GLbyte, GLshort。
相关库
除了OpenGL基本库外,还有一些处理专门操作的附加库。
OpenGL实用函数(OpenGL Utility, GLU)
核心库提供的绘图命令有限,所有的复杂绘图都需要从点线面开始,为减轻工作,GLU库封装了openGL函数,通过调用核心库函数,封装了一些较复杂的的操作,为开发者提供相对简单的方法。该函数由glu.dll负责解释执行,主要包括了一下几种:
- 辅助纹理贴图函数,如gluScaleImage(), gluBuild1Dmipmaps(), gluBuild2Dmipmaps()
- 投影变换函数和坐标转换函数,如gluPerspective(), gluOrtho2D(), gluLookAt(),拾取投影视景体函数gluPickMatrix(), 投影矩阵计算gluProject(), gluUnProject()
- 多边形镶嵌工具,如gluNewTess(), gluDeleteTess(), gluTessCallback(), gluBeginPolygon(), gluTessVertex(), gluNextContour(), gluEndPolygon()
- 二次曲面绘制工具,如gluNewQuadric(), gluSphere(), gluCylinder(), gluDisk(), gluPartialDisk(), gluDeleteQuadric(),可绘制球面,柱面,锥面,圆环面
- 非均匀有理B样条工具,主要用来定义和绘制Nurbs曲线和曲面,如gluNewNurbsRenderer(), gluNurbsCurve(), gluBeginSurface(), gluEndSurface(), gluBeginCurve(), gluNurbsProperty()
- 错误反馈工具,获取出错字符串函数gluErrorString()
OpenGL使用函数工具包(OpenGL Utility Toolkit, GLUT)
glut提供了与任意屏幕窗口系统进行交互的函数库,glut库函数以glut为前缀,在该库中也包含了描述与绘制二次和样条曲线及曲面的方法。由于GLUT是一个与其他依赖于设备的窗口系统之间的接口,因此我们可以利用它将程序写成与设备无关的。此部分函数由glut.dll负责解释执行。主要包括以下函数:
- 窗口操作函数。如窗口初始化,窗口大小,窗口位置等函数。glutInit(), glutInitDisplayMode(), glutInitWindowSize(), glutInitWindowPosition()等
- 回调函数。如响应刷新消息,键盘消息,鼠标消息,定时器函数等。glutDisplayFunc(), glutPostRedisplay(). glutReshapeFunc(), glutTimerFunc(), glutKeyboardFunc(), glutMouseFunc()等。
- 创建复杂的三维物体。如创建网状体和实心体。如glutSolidSphere(), glutWireSphere()等。
- 菜单函数。创建添加菜单。如glutCreateMenu(), glutSetMenu(), glutAddMenuEntry(), glutAddSubMenu(), glutAttachMenu()等。
- 程序运行函数。glutMainLoop()。
使用GLUT进行显示窗口管理
- 使用OpenGL实用库的第一步是初始化GLUT。GLUT初始化的语句是:glutInit(&argc, argv)
- 接着,在显示窗口创建时需要给定窗口标题。glutCreateWindow(“An Example of OpenGL Program”)
- 接着,我们需要指定窗口所显示的图形内容。为此,使用OpenGL定义图形并将图形的定义函数名称传递给GLUT函数glutDisplayFunc。比如glutDisplayFunc(DrawLine),其中在DrawLine函数中定义直线图形。
- 此时窗口并未显示在屏幕上,我们需要执行函数glutMainLoop()将所创建的窗口和其中的图形内容激活。注意,该函数必须在程序最后执行,它显示初始图形并且程序进入等待鼠标键盘等输入设备输入的无限循环之中。
- 显示窗口具有默认位置和大小,我们可以通过使用glutInitWindowPosition()和glutInitWindowSize()来指定窗口的位置和大小。如glutInitWindowPosition(100,200)指定窗口左上角位置为(100, 200),glutInitWindowSize(400, 500)指定窗口宽度为400,高度为500。单位均为像素。
- 还可以使用glutInitDisplayMode()来设置窗口的缓存方式和颜色模型。默认的是glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB)。
完整
- 可以选择背景颜色。如glClearColor(1.0, 1.0, 1.0, 0.0)使用RGB颜色值将背景颜色设置为白色。
- glClearColor()还不能让窗口显示在屏幕上,必须引入函数glClear(GL_COLOR_BUFFER_BIT),其中GL_COLOR_BUFFER_BIT为opengl符号常量,用来指定它是颜色缓存(刷新缓存)中的位值,该缓存将使用函数中的指定值来设置。
- 还可以为显示在场景中的对象设置颜色。如glColor3f(0.0, 0.4, 0.2)。
- 我们还需要告诉opengl如何将三维图形投影到二维窗口。我们可以使用glMatrixMode(GL_PROJECTION)设置为正投影,使用gluOrtho2D(0.0, 200.0, 0.0, 150.0)设置世界坐标系二维矩形区域范围0.0< x <200.0,0.0< y <150.0内的对象投影到窗口,该坐标范围外的对象不会进行投影操作,即不会显示在屏幕上。
- 建立划线函数。
glBegin(GL_LINES);
glVertex2i(180, 15);
glVertex2i(10, 145);
glEnd();
最后,将各个部分组合起来,简单但完整的OpenGL划线程序如下:
#include<glut.h>
//将所有初始化和一次性的参数设定放在函数Init()中
void Init()
{
//设置窗口背景颜色为白色
glClearColor(1.0, 1.0, 1.0, 0.0);
glMatrixMode(GL_PROJECTION);
gluOrtho2D(0.0, 200.0, 0.0, 150.0);
}
//划线函数,将由glutDispalyFunc函数调用
void DrawLine()
{
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(0.0, 0.4, 0.2);
glBegin(GL_LINES);
glVertex2i(180, 15);
glVertex2i(10, 145);
glEnd();
glFlush();
}
//包含设定显示窗口以及将线段图形送到屏幕当中
void main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowPosition(50, 100);
glutInitWindowSize(400, 300);
glutCreateWindow("An Example of OpenGL Program");
Init();
glutDisplayFunc(DrawLine);
glutMainLoop();
}
运行截图: