X 窗口编程/OpenGL
OpenGL(Open Graphics Library)是一种标准规范,定义了跨语言、跨平台的 API,用于编写生成 3D 计算机图形(以及 2D 计算机图形)的应用程序。该接口包含 250 多个不同的函数调用,可用于从简单的基元绘制复杂的 3D 场景。OpenGL 由硅谷图形公司开发,在视频游戏行业很受欢迎,它与微软 Windows 平台上的 Direct3D 竞争。OpenGL 被广泛用于计算机辅助设计、虚拟现实、科学可视化、信息可视化、飞行模拟和视频游戏开发。
在最基本的层面上,OpenGL 是一个规范,这意味着它只是一个描述一组函数及其必须执行的精确行为的文档。从该规范中,硬件供应商创建了实现 - 为了匹配 OpenGL 规范中声明的函数而创建的函数库,尽可能地利用硬件加速。硬件供应商必须通过特定测试才能使其实现符合 OpenGL 实现的资格。
OpenGL 的高效供应商提供实现(在更大或更小的程度上利用图形加速硬件)存在于 Mac OS、Microsoft Windows、Linux、许多 Unix 平台、Wii 和 PlayStation 3 中。各种软件实现存在,将 OpenGL 带到各种没有供应商支持的平台。值得注意的是,开源库 Mesa 是一个完全基于软件的图形 API,与 OpenGL 代码兼容。但是为了避免与正式将其称为 OpenGL 实现相关的许可费用,它声称仅仅是一个“非常类似的”API。
OpenGL 规范目前由 OpenGL 架构审查委员会 (ARB) 监督,该委员会成立于 1992 年。ARB 由一群对创建一致且广泛可用的 API 有利害关系的公司组成。截至 2006 年 4 月,ARB 的投票成员包括 3D 硬件制造商硅谷图形公司、3Dlabs、ATI Technologies、NVIDIA 和英特尔,以及计算机制造商 IBM、苹果电脑、戴尔和太阳微系统。微软是创始成员之一,于 2003 年 3 月离开。除了这些公司之外,每年还有许多其他公司被邀请以一年为期加入 OpenGL ARB。由于有如此多的公司参与其中,而且利益如此多样,OpenGL 已经成为一个具有多种功能的通用 API。
根据当前计划,OpenGL 的控制权将在 2006 年底移交给 Khronos Group。这样做是为了改善 OpenGL 的营销,并消除 OpenGL 和 OpenGL ES 开发之间的障碍。[1]
Kurt Akeley 和 Mark Segal 创作了最初的 OpenGL 规范。Chris Frazier 编辑了 1.1 版。Jon Leech 编辑了 1.2 到现在的 2.0 版。
OpenGL 具有两个主要目的
- 通过向程序员提供一个统一的 API,来隐藏与不同的 3D 加速器接口的复杂性。
- 通过要求所有实现都支持完整的 OpenGL 功能集(必要时使用软件仿真),来隐藏硬件平台的不同功能。
OpenGL 的基本操作是接受点、线和多边形等基元,并将它们转换为像素。这是通过称为 OpenGL 状态机的图形管道来完成的。大多数 OpenGL 命令要么将基元发送到图形管道,要么配置管道如何处理这些基元。在引入 OpenGL 2.0 之前,管道的每个阶段都执行固定函数,并且仅在严格的限制内可配置,但在 OpenGL 2.0 中,几个阶段可以使用 GLSL 完全编程。
OpenGL 是一个低级过程式 API,要求程序员指定渲染场景所需的精确步骤。这与描述性(也称为场景图或保留模式)API 形成对比,在描述性 API 中,程序员只需要描述一个场景,就可以让库管理渲染它的细节。OpenGL 的低级设计要求程序员对图形管道有很好的了解,但也为实现新颖的渲染算法提供了一定程度的自由。
历史上,OpenGL 一直影响着 3D 加速器的开发,促进了现在消费级硬件中常见的基层功能。
- 将光栅化的点、线和多边形作为基本基元
- 变换和照明管道
- Z 缓冲
- 纹理映射
- Alpha 混合
许多现代 3D 加速器提供的功能远远超过此基线,但这些新功能通常是对此基本管道的增强,而不是对其进行彻底的改造。
我们首先清除颜色缓冲区,以便从一个空白画布开始。
glClear( GL_COLOR_BUFFER_BIT );
现在我们设置模型视图矩阵,它控制相机相对于我们渲染的基元的位置。我们将它沿 Z 轴向后移动 3 个单位,使其指向原点。
glMatrixMode( GL_MODELVIEW ); /* Subsequent matrix commands will affect the modelview matrix */ glLoadIdentity(); /* Initialize the modelview to identity */ glTranslatef( 0, 0, -3 ); /* Translate the modelview 3 units along the Z axis */
投影矩阵控制应用于基元的透视效果,并且其控制方式类似于模型视图矩阵。
glMatrixMode( GL_PROJECTION ); /* Subsequent matrix commands will affect the projection matrix */ glLoadIdentity(); /* Initialize the projection matrix to identity */ glFrustum( -1, 1, -1, 1, 1, 1000 ); /* Apply a perspective-projection matrix */
最后,我们发出一个多边形 - 一个位于 XY 平面上的绿色正方形。
glBegin( GL_POLYGON ); /* Begin issuing a polygon */ glColor3f( 0, 1, 0 ); /* Set the current color to green */ glVertex3f( -1, -1, 0 ); /* Issue a vertex */ glVertex3f( -1, 1, 0 ); /* Issue a vertex */ glVertex3f( 1, 1, 0 ); /* Issue a vertex */ glVertex3f( 1, -1, 0 ); /* Issue a vertex */ glEnd(); /* Finish issuing the polygon */
OpenGL 的受欢迎程度部分归功于其官方文档的出色表现。OpenGL ARB 随着规范发布了一系列手册,这些手册已经更新以跟踪 API 的变化。这些手册几乎普遍以其封面的颜色而闻名。
- 红皮书 - OpenGL 程序员指南。 ISBN 0-321-33573-2
- 一本可读的教程和参考书 - 对于 OpenGL 程序员来说,这是一本“必备”书籍。
- 蓝皮书 - OpenGL 参考手册。 ISBN 0-321-17383-X
- 本质上是 OpenGL 的 手册 页面的硬拷贝。
- 包括一个海报大小的折叠图,展示了理想化 OpenGL 实现的结构。
- 绿皮书 - X 窗口系统 OpenGL 编程。 ISBN 0-201-48359-9
- 一本关于 X11 接口和 GLUT 的书籍。
- 阿尔法书(实际上封面是白色的) - Windows 95 和 Windows NT OpenGL 编程。 ISBN 0-201-40709-4
- 一本关于将 OpenGL 与 Microsoft Windows 接口的书籍。
然后,对于 OpenGL 2.0 及更高版本
- 橙皮书 - OpenGL 着色语言。 ISBN 0-321-33489-2
- 一本可读的 GLSL 教程和参考书。
OpenGL 标准允许各个供应商通过扩展来提供额外的功能,以应对新技术的出现。扩展可以引入新的函数和新的常量,并且可以放宽或移除对现有 OpenGL 函数的限制。每个供应商都有一个字母缩写,用于命名其新的函数和常量。例如,英伟达的缩写 (NV) 用于定义其专有的函数 glCombinerParameterfvNV()
和其常量 GL_NORMAL_MAP_NV
。可能会出现多个供应商同意实现相同扩展功能的情况。在这种情况下,将使用缩写EXT。此外,架构审查委员会可能会“认可”该扩展。然后,它将被称为标准扩展,并且将使用缩写ARB。第一个 ARB 扩展是 GL_ARB_multitexture
,它是在 1.2.1 版中引入的。遵循官方扩展推广路径,多纹理不再是可选实现的 ARB 扩展,而是从 1.3 版开始成为 OpenGL 核心 API 的一部分。
在使用扩展之前,程序必须首先确定其可用性,然后获取指向扩展定义的任何新函数的指针。执行此操作的机制是特定于平台的,并且存在诸如 GLEW 和 GLEE 之类的库来简化此过程。
几乎所有扩展的规范都可以在官方扩展注册表 [1] 中找到。
关联的实用程序库
[edit | edit source]几个库建立在 OpenGL 之上或旁边,以提供 OpenGL 本身不可用的功能。诸如 GLU 之类的库总是可以与 OpenGL 实现一起找到,而其他一些库,例如 GLUT 和 SDL,随着时间的推移而发展,并提供基本的跨平台窗口和鼠标功能,如果不可用,则可以轻松下载并添加到开发环境中。简单的图形用户界面功能可以在诸如 GLUI 或 FLTK 之类的库中找到。其他一些库,如 AUX,是已被更流行的库中普遍可用的功能所取代的已弃用的库,但代码仍然存在,特别是在简单的教程中。其他库是为了让 OpenGL 应用程序开发人员能够轻松地管理 OpenGL 扩展和版本控制而创建的,这些库的例子包括 GLEW“The OpenGL Extension Wrangler Library”和 GLEE“The OpenGL Easy Extension library”。
除了上述简单的库之外,还存在其他更高级的面向对象的场景图保留模式库,例如 PLIB、OpenSG、OpenSceneGraph 和 OpenGL Performer,这些库作为跨平台的开源或专有编程接口提供,建立在 OpenGL 和系统库之上,以使创建实时视觉模拟应用程序成为可能。
Mesa 3D ([2]) 是 OpenGL 的开源实现。它支持纯软件渲染,以及为 Linux 下的多个 3D 图形卡提供硬件加速。截至 2006 年 2 月 2 日,它实现了 1.5 标准,并为一些平台提供了它自己的扩展。
绑定
[edit | edit source]为了强调其多语言和多平台特性,已经为 OpenGL 在许多语言中开发了各种绑定和端口。最值得注意的是,Java 3D 库可以依赖 OpenGL 来实现其硬件加速。直接绑定也可以使用,例如 Lightweight Java Game Library,它为 Java 和其他与游戏相关的组件提供了 OpenGL 的直接绑定。最近,Sun 发布了 JOGL 系统的测试版,该系统提供了对 C OpenGL 命令的直接绑定,与不提供这种低级支持的 Java 3D 不同。OpenGL 官方页面 [3] 列出了 Java、Fortran 90、Perl、Pike、Python、Ada、Delphi 和 Visual Basic 的各种绑定。绑定也适用于 C++ 和 C#,请参阅 [4]。
更高级的功能
[edit | edit source]OpenGL 被设计为仅用于图形输出:它仅提供渲染功能。核心 API 没有窗口系统、音频、屏幕打印、键盘/鼠标或其他输入设备的概念。虽然这乍一看似乎很严格,但它允许执行渲染的代码完全独立于它运行的操作系统,从而允许跨平台开发。但是,需要与本机窗口系统集成,以允许与主机系统进行干净的交互。这是通过以下附加 API 完成的
- GLX - X11(包括网络透明度)
- WGL - Microsoft Windows
此外,GLUT 和 SDL 库以可移植的方式提供了使用 OpenGL 进行基本窗口操作的功能。MacOS X 有三个 API 来获取 OpenGL 支持:用于 Carbon 的 AGL、用于 Cocoa 的 NSOpenGL 以及用于低级访问的 CGL。
历史
[edit | edit source]如今,三维动画场景的数字生成已成为日常生活中的常见现象。科学家利用计算机图形来分析各种可能的模拟。工程师和建筑师使用计算机图形设计虚拟模型。电影利用计算机图形来创造惊人的特效或完整的动画电影。在过去的几年里,电脑游戏将计算机图形技术带给了普通消费者,使用图形将玩家带入到无法存在的现实世界中。
将数字图形技术投入如此广泛的应用并非没有挑战。十五年前,开发能够与各种图形硬件及其所有不同接口一起工作的软件非常耗时。每个程序员团队都分别开发了接口,因此产生了大量重复的代码。这阻碍了计算机图形行业的发展。
到了 20 世纪 90 年代初,3D 图形领域的领导者 SGI 及其编程 API IrisGL 已成为业界事实上的标准,超过了基于开放标准的 PHIGS。IrisGL 编程接口 (API) 优雅、易于使用,重要的是,它支持即时模式渲染。相比之下,PHIGS 笨拙、难以使用,并且在功能和能力方面落后于 IrisGL 好几代,这主要是由于 PHIGS 标准化过程的低效。尽管如此,包括 Sun Microsystems、惠普和 IBM 在内的竞争供应商还是能够推出可靠的 3D 硬件,并通过对 PHIGS 的专有扩展来支持它们。到了 90 年代初,3D 图形硬件技术已被众多竞争者所熟知,不再是计算机系统购买中的决定性因素。因此,SGI 试图将事实上的标准转变为真正的开放标准,而不是延长 IrisGL 和 PHIGS 之间有争议且危险的斗争。
IrisGL API 本身不适合开放(尽管它以前已授权给 IBM 和其他人),部分原因是它多年来积累了大量杂乱无章的内容。例如,它包含一个窗口、键盘和鼠标 API,部分原因是它是在 X11 窗口系统 与 Sun 的 NeWS 之间的斗争解决之前开发的。因此,需要清理要开放的 API。此外,IrisGL 拥有庞大的软件供应商 (ISV) 投资组合;向 OpenGL API 的更改将使 ISV 被锁定到 SGI(和 IBM)硬件上几年,直到 OpenGL 的市场支持成熟。与此同时,SGI 将继续尝试通过推动更高层次的专有 Iris Inventor 和 Iris Performer 编程 API 来维持供应商锁定。
结果被称为OpenGL。OpenGL 标准化了对硬件的访问,并将硬件接口程序(有时称为设备驱动程序)的开发责任推给了硬件制造商,并将窗口功能委托给了底层操作系统。由于存在如此多种不同的图形硬件,因此让它们以这种方式说同一种语言对软件开发人员产生了非凡的影响,因为它为他们提供了更高级的 3D 软件开发平台。
1992 年,SGI 领导创建了 OpenGL 架构审查委员会 (OpenGL ARB),这是一个由多家公司组成的组织,负责在未来几年维护和扩展 OpenGL 规范。OpenGL 发展自 (并且在风格上与) SGI 早期的 3D 接口 IrisGL 非常相似。IrisGL 的一个限制是,它只能访问底层硬件支持的功能。如果图形硬件不支持某个功能,那么应用程序就无法使用它。OpenGL 通过在软件中为硬件不支持的功能提供支持来克服这个问题,从而使应用程序能够在性能相对较低的系统上使用高级图形。
1994 年,SGI 玩弄了发布名为 "OpenGL++" 的东西的想法,其中包含诸如场景图 API (可能是基于其 Performer 技术) 之类的元素。该规范在一些感兴趣的各方之间流传 - 但从未变成产品。
1995 年,Direct3D 发布后,微软、SGI 和惠普发起了 Fahrenheit 项目,这是一个联合项目,目标是统一 OpenGL 和 Direct3D 接口 - 并且再次添加场景图 API。它最初显示出了一些希望,可以给交互式 3D 计算机图形 API 世界带来秩序,但由于 SGI 的资金限制和行业普遍缺乏支持,该项目被放弃了。SGI 中的工程师们举行了一个海滩派对来庆祝 - 他们用篝火烧掉了大量的 Fahrenheit 文档。
OpenGL 2.0 由 3Dlabs 构思,旨在解决人们对 OpenGL 停滞不前且缺乏明确方向的担忧。3Dlabs 提出了对标准的一些重大补充,其中最重要的是 GLSL (OpenGL Shading Language,也称为 slang)。这将使程序员能够用类似于 C 的语言编写的着色器替换 OpenGL 固定功能顶点和片段管道,从而大幅扩展了可能的图形效果范围。GLSL 值得注意的是,它对当时可用的硬件的限制做出了相对较少的让步;这让人想起早期 OpenGL 为 3D 加速器设定一个雄心勃勃的、面向未来的目标的传统,而不仅仅是跟踪当前可用硬件的状态。最终的 OpenGL 2.0 规范 [5] 包含对 GLSL 的支持,但省略了许多最初提议的但被推迟到以后版本的 OpenGL 的其他功能 (尽管现在许多功能都可以作为扩展使用)。
OpenGL 2.1 于 2006 年 8 月 2 日发布,与所有以前的 OpenGL 版本向后兼容。OpenGL 2.1 包含以下功能
- OpenGL 着色语言修订版 1.20
- 用于指定和查询非正方形矩阵制服的命令,用于 OpenGL 着色语言
- 像素缓冲区对象,用于高效地将图像传输到缓冲区对象和从缓冲区对象传输到缓冲区对象,用于诸如以下命令glTexImage2D和glReadPixels.
- 此功能对应于ARB_pixel_buffer_object扩展。
- sRGB 纹理格式。
- 此功能对应于EXT_texture_sRGB扩展。
- GLUT - OpenGL 实用工具包。
- GLU - OpenGL 程序的一些附加功能。
- GLEW - OpenGL 扩展包装库。
- ↑ "OpenGL ARB to Pass Control of OpenGL Specification to Khronos Group". Press Releases. Khronos Group. July 31, 2006. Retrieved 2006-08-01.