我们需要理解 OpenGL 的工作机制。OpenGL本身仅仅支持最原始点、线段和平面的绘制,因此多数情况下我们都是准备好 vertex 数据,这些或者组织成为 display list 提交给显卡的 evaluator,这个 evaluator 将点信息转换成为需要描述的面的信息(如法向量等,这个功能在创建复杂的几何形体如曲面等时会经常用到);之后通过设定的 per-vertex 操作,如进行几何变换,计算纹理位置,光源、材料等等;然后是 assemble,获得显示到窗口的投影坐标。这之后就需要将这些计算出来的数据进行 rasterization(像素化,栅格化),同时将纹理信息加入到这些面上,进一步就可以做 fragment 操作(如根据深度去掉被遮挡的、又或者进行 blending 等,一般每种操作对应某种 buffer),最后将结果放到某个 buffer 中(可能是用于显示的,也可能是用于 swap 的)。而一般外部的位图数据,一般会首先经过处理(如放缩、平移、映射等)形成纹理。
编写 OpenGL 的程序要理解清楚,我们所绘制的对象是一个所谓的 OpenGL context,这个 context 里面包括了所有打开的 OpenGL 使用的 buffer 等对象,我们做图时往往需要指定一个 context,做图的过程就是将这个 context 的状态不停的改变,比如我们希望改变渲染的对象,我们会在 GL_RENDER 下切换到矩阵的 GL_MODELVIEW 里面,而如果只是改变投影我们是在 GL_PROJECTION 里面;如果我们需要选择所画的某些对象,我们会切换到 GL_SELECT 这种模式,并通过 GL_PROJECTION 设定我们观看的区域,然后切换回 GL_MODELVIEW 重新绘制,退回 GL_RENDER 的时候就会获得一个被选择的对象列表。所以我们需要搞清楚有些什么样的状态,对应状态下可以进行一些什么操作。
推荐的文档有两个,一个是 OpenGL 红皮书(红宝书?)即 OpenGL Programming Guide,现在已经到第 7 版了,非常经典的书,现在也开始涉及到 OpenGL 3.0 的东西,最新的 4.1 尚未涉及;4.1 相关的主要是 NVIDIA 在推动;这本书网上有电子版,中文版只能说翻译质量一般;另一个自然就是官方的 spec,网上可以免费下载(见这里)。
另外,我们需要理解清楚下面几个概念。
- OpenGL 与 WGL、AGL 和 GLX 的关系:OpenGL 本质上和窗口系统无关,因此如果需要在某些窗体环境中使用 OpenGL 需要这些 GUI 提供某种 OpenGL 扩展,WGL 是 Windows 的扩展,AGL(另外还有 CGL、Cocoa 的 NSOpenGL 类)是苹果的扩展,而 GLX 是 X11 扩展(并且允许 network-transparent 的 OpenGL 渲染)。
- OpenGL 与 GLU 和 GLUT 之间的关系:前面说了 OpenGL 本身仅仅提供了非常原始的操作;GLU 另外提供了层次纹理(mipmapping)、简单的矩阵操作(更加方便)、polygon tessellation(将曲面分解成为多边形)、二次曲面以及 NURBS 的支持;GLUT 提供的是接口统一跨平台的 GUI 接口。