书名:计算机图形学编程(使用OpenGL和C++)(第2版)
ISBN:978-7-115-59633-8
本书由人民邮电出版社发行数字版。版权所有,侵权必究。
您购买的人民邮电出版社电子书仅供您个人使用,未经授权,不得以任何方式复制和传播本书内容。
我们愿意相信读者具有这样的良知和觉悟,与我们共同保护知识产权。
如果购买者有侵权行为,我们可能对该用户实施包括但不限于关闭该帐号等维权措施,并可能追究法律责任。
著 [美] V.斯科特·戈登(V. Scott Gordon)
[美] 约翰·克莱维吉(John Clevenger)
译 魏广程 沈 瞳
责任编辑 郭泳泽
人民邮电出版社出版发行 北京市丰台区成寿寺路11号
邮编 100164 电子邮件 315@ptpress.com.cn
网址 http://www.ptpress.com.cn
读者服务热线:(010)81055410
反盗版热线:(010)81055315
本书以C++和OpenGL作为工具,介绍计算机图形学编程的相关内容。全书从图形编程的基础和准备工作出发,介绍了OpenGL图像管线、图形编程数学基础、管理3D图形数据、纹理贴图、3D模型、光照、阴影、天空和背景、增强表面细节、参数曲面、曲面细分、几何着色器、水面模拟、光线追踪等图形学编程技术。附录分别介绍了Windows、macOS平台上的安装设置,以及Nsight图形调试器的应用。本书配备了不同形式的习题,供读者巩固所学知识。
本书适合作为高等院校计算机科学专业的计算机图形编程课程的教材或辅导书,也适合对计算机图形编程感兴趣的读者自学。
魏广程 程序员、游戏开发爱好者,现旅居北美,任职于互联网金融技术公司,有十几年IT行业从业经验。本科毕业于西安交通大学,研究生毕业于美国雪城大学。合译有《游戏开发物理学(第2版)》《计算机图形学编程(使用OpenGL和C++)》。
沈瞳 程序员、创业者、游戏开发爱好者,现居上海,任职于不动产大数据科技公司,从事地产科技、不动产区块链相关行业工作。本科毕业于西安交通大学,研究生毕业于美国布兰迪斯大学。合译有《计算机图形学编程(使用OpenGL和C++)》。
欢迎来到计算机图形学编程和OpenGL的世界!跟随本书两位作者,你将经历一段奇妙的旅程。
计算机图形学(Computer Graphics,CG)是研究使用计算机创造图形的学科,属于计算机科学的分支。本书涵盖一部分常用的计算机图形学概念和理论,但并不是完整介绍这方面知识的教材。本书的优点是在简明地介绍概念的同时,手把手地讲解OpenGL的基础技术实现。图形学不只是一门学科,也是一项实践技术。工业界对图形学算法和方法的实现往往会为了性能而牺牲完全的精确性。因此,同时理解理论知识和掌握实践技巧,并懂得在应用时如何取舍,是学习图形学编程的重要目标之一。
OpenGL是当今行业中使用最多、功能最强大的图形库吗?很可能不是。OpenGL向前兼容,有不小的历史包袱。它的状态机制也可能导致在某些情境下无谓的性能丧失。更重要的是,当前在工业界有很多更具优势的其他图形库。例如,由操作系统厂商推出的自家图形接口,如Windows下的DirectX、macOS下的Metal等,通常情况下都能实现远高于OpenGL的图形性能;Vulkan之类的图形库又给了开发者对GPU细节更强的掌控力。实际上,在真实的生产环境中使用OpenGL的应用并没有那么多。这是不是意味着初学者应该直接开始学习这些在工作中也许能直接输出价值的技术呢?也很可能不是。
正如前言中两位原作者所述,本书面向的是计算机图形编程初学者。对初学者而言,最重要的是建立对重要概念的全局认知,而不是陷入各种琐碎的API细节中。从这个维度看,OpenGL在一定程度上隐藏了GPU驱动程序的事务性细节,让读者能专注于理解图形学技术及其实现,掌握着色器编程模型和基础技巧,而这些正是会在读者未来学习和工作中发挥基础性和长期性作用的知识。相较于上文所述的其他图形库,OpenGL的学习曲线较为缓和,读者跟随本书的进程能在渐进式的过程中感受到图形编程的全貌,这能为后续对其他图形库的学习打下良好的基础。本书第2版新增的模拟水面、光线追踪、立体视觉等内容都是近期热点话题,虽然有很多硬件或软件的方式能让我们更高效地实现这些场景,但是了解这些技术的原理既对直接应用这些技术有帮助,也能帮读者更进一步练习、巩固学习到的各项技术。
此外,常用于Android设备的OpenGL ES和网页标准WebGL基本上就是OpenGL的子集。在移动和Web端大行其道的今天,如BIM、CIM和数字孪生、智慧城市、数字驾驶舱等应用也常结合基于WebGL的模型可视化和数据可视化技术,OpenGL也有其用武之地。
我们祝愿每一位读者学习顺利,收获长期价值。
魏广程 沈瞳
2021年11月
本书的主要写作目标是为计算机科学专业本科OpenGL 3D图形编程相关课程提供合格的教材。同时,我们也付出了很大的努力,让本书成为一本无须配合课程使用的自学教材。在以这两者为目标的前提下,本书尽力将内容解释得简单而清晰。本书中的所有代码示例都已经尽可能地在保证完整性的同时进行了简化,以便读者直接运行。
我们期望本书与众不同的一点是对初学者(刚接触3D图形编程的读者)友好。关于3D图形编程这个主题的学习资料从来都不匮乏,恰恰相反,很多初学者刚入门的时候,相关的资料就扑面而来,令人不知所措。作者在刚接触3D图形编程的时候,期望能遇见这样的教材:一步步解释基础概念,循序渐进并有序地梳理进阶概念,因此作者也尝试将本书编写成这样的教材。作者曾想将本书命名为“轻松学习着色器编程”,虽然我们并不认为有什么方法能真的让着色器编程变得“轻松”,但我们希望本书能够帮助读者尽可能地达成这个目标。
本书使用C++进行OpenGL编程教学。使用C++学习图形编程有以下好处。
值得一提的是,OpenGL也存在着其他语言绑定,常见的有Java、C#、Python,以及其他许多语言。但本书仅关注C++。
本书与众不同的另一点是它有一个Java版,英文书名是Computer Graphics Programming in OpenGL with Java, 2nd Edition。这两本书是按同样的节奏组织的,使用相同的章节编号、主题、图表、习题和讲解方式,也尽可能以相似的方式组织代码。诚然,使用C++或Java编程肯定有着相当大的差异(不过书中着色器代码完全一致)。尽管如此,我们仍然相信这两本书提供了几乎相同的学习路径,甚至可以让选修同一门课程的学生使用。
需要着重澄清的一点是,OpenGL有着不同的版本(稍后简述)和不同的变体。例如:在标准OpenGL(也称桌面OpenGL)之外,还有一个变体叫作OpenGL ES,是为嵌入式系统(Embedded System)的开发而定制的(因此称为“ES”)。“嵌入式系统”包括手机、游戏主机、汽车和工业控制系统之类的设备。OpenGL ES大部分内容是标准OpenGL的子集,删除了嵌入式系统通常用不到的很多操作。OpenGL ES还增加了一些功能,通常是特定目标环境下的特定功能。本书侧重于介绍标准OpenGL。
OpenGL的另一个变体称为WebGL。WebGL基于OpenGL ES,它的设计目标是支持在浏览器中运行OpenGL。WebGL允许应用程序通过JavaScript[1]进行OpenGL ES操作调用,从而简单地将OpenGL图形嵌入标准HTML(Web)文档中。大多数现代Web浏览器都支持WebGL,包括Apple Safari、Google Chrome、Microsoft Edge、Microsoft Internet Explorer、Mozilla Firefox和Opera。由于Web编程超出了本书的范围,因此本书不会涵盖WebGL。不过,由于WebGL基于OpenGL ES,而OpenGL ES又基于标准OpenGL,因此本书涵盖的大部分内容都可以直接迁移到这些OpenGL变体中去。
3D图形编程这个主题通常让人想起精美而宏大的画面。事实上,许多相关热门教材中充满了令人惊叹的场景,吸引着读者翻阅它们的图库。虽然我们认同这些图像的激励作用,但我们的目标是教学而非令人惊叹。本书中的图像仅仅是示例程序的输出。由于本书只是入门教程,因此其渲染的场景大概无法让专家心动。然而,本书呈现的技术确实是构成当今这些炫目3D效果的基础。
本书并没有尝试成为一本“OpenGL参考大全”,所涵盖的OpenGL部分只是其所有功能中的一小部分。本书的目标是以OpenGL作为基础工具,教授基于现代着色器的3D图形编程,并为读者提供足够深入的理解,以供读者自行进行进一步的研究。
本书在第1版的基础上新增了3章。
在过去多年的教学中,学生们对于水的模拟表现出了极大的兴趣。但是,由于水的形态繁多,在入门教材中加入这样一章很困难。最终,我们决定用辅助本书其他章节内容的形式加入与水相关的内容。在第15章中,我们主要介绍了如何使用第14章中所介绍的噪声图,生成像湖面或海面的水面。
光线追踪(ray tracing)这个主题最近变得很热门,因此我们涵盖了这部分内容。同时光线追踪也是一个很庞大的话题,虽然本书只涵盖了一些基础介绍,但第16章依然是书中篇幅最大的一章。第16章同时也涵盖了OpenGL 4.3所引入的计算着色器(compute shader)的介绍,并在展开14.2节中的话题时介绍了加法混色和减法混色。
3D眼镜和VR头显的立体视觉(stereoscopy)相关内容的加入是因为虚拟现实的日益流行。当然,这些知识同样可以应用于开发“3D电影”中的动画。同时,我们在第 17 章中尝试对这两种应用情景以同样权重进行涵盖。
由于新加了以上内容,本书篇幅比第1版要长一些。
除了新的内容之外,本书还有很多重要的修正。如修复了第6章中的Torus类的代码缺陷并优化了第14章中的噪声图代码,对Utils.cpp类进行了扩展以处理计算着色器的加载,为SOIL2库找到了一个会影响macOS用户加载立方体贴图的代码缺陷(现已修复)。
书中还有很多读者可能注意不到的小改动散布于各章中:改正错别字、整理代码、更新安装指引、微小的措辞修改、整理图表、更新引用等。在一本讲述快速进化的技术话题的书中完全消灭错别字几乎是一件不可能的任务,但我们对此倾尽了全力。
本书的目标读者是计算机科学专业的学生(可以是本科生),但其实任何想要学习计算机科学相关知识的人都适合阅读本书。因此,我们假设读者有扎实的面向对象编程基础,至少有相当于计算机科学专业大二或大三学生的水平。
本书中未涵盖如下内容,因为我们假设读者已经有足够的背景知识。
希望本书的潜在受众能够因对Java版的喜爱而进一步支持本书。正如前面所说的,我们期望看到这样一种情景——学生在同一门课中可以自由选择使用C++版教材或Java版教材。这两本教材按照同样的节奏对教学内容进行组织编排,这种模式已经在图形学编程的课程实践中获得了成功。
本书内容安排上适合从前往后阅读,即对后面章节中知识的学习经常依赖于前面章节中所讲的内容。我们不推荐在各章节中来回跳跃地选择性阅读,读者最好逐章阅读。
同时,本书也希望成为一本实用的动手指南。由于已经有许多其他偏理论的学习材料,读者应该将本书作为一本“练习册”,通过一边参考本书一边自己动手编程来学习和理解基础概念。虽然我们为所有的示例提供了代码,但是想要真正学会这些概念,还是得自己动手“实现”这些代码——通过编程来搭建自己的3D场景。
本书第2章~第14章留给读者一些习题,其中有的题目比较简单,仅仅需要对提供的代码进行简单的改动就可以解决。而那些标记为“项目”的习题需要读者花更多的时间来解决,因为可能需要编写大量代码或者使用多个示例中用到的技术。少数标记为“研究”的习题则会用到在本书中并没有提供的知识细节,我们鼓励读者自主学习并解答。
OpenGL中的函数调用通常会有很长的参数列表。我们在撰写本书时曾多次讨论是否要描述所有参数,最终决定在前面的章节中详细讲解函数的所有参数。随着主题深入,本书会避免在每次OpenGL调用(因为调用次数很多)中过分描述细枝末节,以防读者失去对全局的理解。因此,在浏览示例时,读者需要准备OpenGL和所使用的各种库的参考资料。
为此,我们建议结合一些优秀的在线资源使用本书。OpenGL的官方文档是绝对必要的,它涵盖了有关各种命令的详细信息。可以利用搜索引擎,或访问OpenGL的官方网站获取帮助。
本书示例使用了名为GLM的数学库。安装GLM(见附录)后,读者应找到其官方在线文档并将其加入浏览器书签。
本书经常用到的另一个库是SOIL2,用于读取以及处理纹理图像文件,读者可能也时常需要查阅它的文档。虽然SOIL2没有中心化的文档资源,但通过搜索可以找到一些例子。
还有许多关于3D图形编程的图书,建议与本书并行阅读(例如在解决各章最后的“研究”习题时翻阅)。以下是本书中经常提到的5本图书。
Angel和Shreiner著《交互式计算机图形学:基于WebGL的自顶向下方法(第七版)》[AS14]。
Luna著,王陈译《DirectX 12 3D游戏开发实战》[LU16]。
本书提供随书的配套资源,其内容有:
上述资源可以通过访问异步社区(www.epubit.com)的本书页面获取。
我们鼓励教师获取本书的教学辅助资料,其中包含以下附加项(以英文提供):
教师辅助包获取方式请联系contact@epubit.com.cn。
本书中的许多内容都基于Java版教材——Computer Graphics Programming in OpenGL and Java,它是作者于2016年为加利福尼亚州立大学萨克拉门托分校的CSc-155(高级计算机图形编程)课程编写的教材。当年许多学习CSc-155课程的学生都主动对早期的草稿给出了修改建议,并帮助修复了相关程序中的代码缺陷。要特别感谢Mitchell Brannan、Tiffany Chiapuzio-Wong、Samson Chua、Anthony Doan、Kian Faroughi、Cody Jackson、John Johnston、Zeeshan Khaliq、Raymond Rivera、Oscar Solorzano、Darren Takemoto、Jon Tinney、James Womack、Victor Zepeda的建议。在接下来的几年中,我们的同事Pinar Muyan-Ozcelik博士开始在她的CSc-155课程教学中使用Java版,并持续记录了每章中所遇到的问题以及需要更正的内容,最终为Java版的第2版以及C++版的第1版提供了许多改进意见。
2020年春天,作者在CSc-155课程中测试了让学生自由选择使用C++或Java并使用对应版本教材进行学习的计划。作者以此测试在一门课程中同时使用C++版和Java版教材,其结果令人很满意。同时,学生们也发现了书中的一些错误——Paul McHugh发现并修复了3D纹理代码中的一个重大内存泄露问题。
同时我们也从全世界使用本书作为课程教材的教师、专业人士以及爱好者群体中持续收到了很棒的反馈——在这里要感谢Mauricio Papa博士(University of Tulsa)、Dan Asimov(NASA Ames)、Sean McCrory、Michael Hiatt、Scott Anderson、Reydalto Hernandez、Bill Crupi等人。
Alan Mills博士在2020年年初开始教授课程之后,从浏览Java版时整理的笔记中,发给我们超过200条建议和修正意见。其中大约一半建议和修正意见同样适用于C++版。在他的诸多发现中,有一个条目是对环形模型中纹理坐标的重大修正。Alan对细节的关注令人赞叹,我们非常感谢他为本书所做的工作,他的工作对本书产生了积极的影响。
Jay Turberville来自亚利桑那州Scottsdale的Studio 522 Productions。他创建了封面以及书中所有的海豚模型,学生们非常喜欢。Studio 522 Productions制作了高质量的3D动画和视频,以及自定义3D建模。我们很高兴Turberville先生慷慨地为本书建立这个精美的模型。
Martín Lucas Golini,作为SOIL2纹理图像处理库的开发者和维护者,也对本书付出了极大的支持和热情,一直快速回应我们提出的相关问题。我们对他的帮助表示感谢。
我们还要感谢其他一些艺术家和研究人员,他们非常慷慨地让我们使用他们的模型和纹理。 来自Planet Pixel Emporium的James Hastings-Trew提供了许多行星表面纹理。Paul Bourke允许我们使用他所拥有的精彩的星域。斯坦福大学的Marc Levoy博士授权我们使用著名的“斯坦福龙”模型。Paul Baker的凹凸贴图教程是我们在许多例子中使用的“环面”模型的基础。我们还要感谢Mercury Learning允许我们使用[LU16]中的一些纹理。
已逝的Danny Kopec博士向我们介绍了Mercury Learning公司,并向其出版人David Pallai引荐了我们。作为象棋爱好者的Gordon博士(本书作者之一)最早熟悉Kopec博士是因为其国际象棋大师、国际象棋畅销书作者的身份。Kopec博士同时也是一名计算机科学家,他编写的教科书Artificial Intelligence in the 21st Century[《人工智能(第2版)》,人民邮电出版社,ISBN:9787115488435]让我们考虑通过Mercury Learning出版图书,我们在与Kopec博士的几次通话中获得了很多信息。Kopec博士于2016年早逝,我们深感悲痛,也对他没有机会看到他所启动的项目取得的成果而感到遗憾。
最后,我们要感谢Mercury Learning的David Pallai和Jennifer Blaney。感谢他们对这个项目持续的热情和支持,以及引导我们完成了本书的整个出版流程。
[AS14] E. Angel and D. Shreiner, Interactive Computer Graphics: A Top-Down Approach with WebGL, 7th ed. (Pearson, 2014).
[KS16] J. Kessenich, G. Sellers, and D. Shreiner, OpenGL Programming Guide: The Official Guide to Learning OpenGL, Version 4.5 with SPIR-V, 9th ed. (AddisonWesley, 2016).
[LU16] F. Luna, Introduction to 3D Game Programming with DirectX 12, 2nd ed. (Mercury Learning, 2016).
[SW15] G. Sellers, R. Wright Jr., and N. Haemel, OpenGL SuperBible: Comprehensive Tutorial and Reference, 7th ed. (Addison-Wesley, 2015).
[WO18] D. Wolff, OpenGL 4 Shading Language Cookbook, 3rd ed. (Packt Publishing, 2018).
[1] JavaScript 是一门脚本语言,其代码可以嵌入网页中运行。它与Java 有一定的相似性,但同时在很多重要的方面也有区别。
V. 斯科特·戈登(V. Scott Gordon)博士在加利福尼亚州立大学系统担任教授已超过25年,目前在加利福尼亚州立大学萨克拉门托分校教授高级图形学和游戏工程课程。他撰写及合著了30多部出版物,涉及人工智能、神经网络、演化计算、计算机图形学、软件工程、视频和策略游戏编程、计算机科学教育等多个领域。Gordon博士在科罗拉多州立大学获得博士学位。同时他也是爵士乐鼓手以及优秀的乒乓球运动员。
约翰·克莱维吉(John Clevenger)博士拥有超过40年的教学经验,教学内容包括高级图形学、游戏架构、操作系统、VLSI芯片设计、系统仿真和其他主题。他是多个用于图形和游戏架构教学的软件框架和工具的开发人员,其中包括本书对应Java版中用到的graphicslib3D库。他是国际大学生程序设计竞赛(ICPC)的技术总监,负责监督PC2的持续开发,PC2是使用广泛的编程竞赛支持系统。Clevenger博士在加利福尼亚大学戴维斯分校获得博士学位。他还是一位爵士乐表演艺术家,常在他的山间小屋过暑假。
图形编程是计算机科学中最具挑战性的主题之一,并因此而闻名。当今,图形编程是基于着色器的,也就是说,有些程序是用诸如C++或Java等标准编程语言编写的,并运行在中央处理器(Central Processing Unit,CPU)上;另一些是用专用的着色器语言编写的,直接运行在图形处理单元(Graphics Processing Unit,GPU)上。着色器编程的学习曲线很陡峭,以致哪怕是绘制简单的东西,也需要一系列错综复杂的步骤,把图形数据从一个“管线”(pipeline,又称为“流水线”)中传递下去才能完成。现代显卡能够并行处理数据,即使是绘制简单的形状,图形程序员也必须理解GPU的并行架构。
这虽然并不简单,但可以换回超强的渲染能力。电子游戏中涌现出来的令人惊艳的虚拟现实(Virtual Reality,VR)和好莱坞电影中越来越逼真的特效,很大程度上是由着色器编程的进步带来的。如果阅读本书是你进入3D图形世界的第一步,那么你正在开始接受一个对自己的挑战。挑战的奖励不仅有漂亮的图片,还有过往不敢想象的对机器的掌控程度。欢迎来到激动人心的计算机图形编程世界!
现代图形编程使用图形库完成,也就是说,程序员编写代码时,调用一个预先定义的库(或者一系列库)中的函数,由这个库来提供对底层图形操作的支持。现在有很多图形库,但常见的平台无关图形库叫作OpenGL(代表open graphics library,即开放图形库)。本书将会介绍如何在C++中使用OpenGL进行3D图形编程。
在C++中使用OpenGL需要配置多个库。这里按照个人需求,可以有一系列令人眼花缭乱的选择。在本节中,我们会介绍哪几种库是必要的,各种库的一些常见选择,以及我们在本书中选择的库。
总的来说,你需要用到:
读者可能需要进行几项准备,以保证这几种库已安装在系统中,并可以正常使用。下面几个小节将简单介绍它们。它们的安装和配置的更多细节请参阅附录。
C++是一种通用编程语言,最早出现在20世纪80年代中期。它的设计,以及它通常被编译成本机的机器码这一事实,使得它成了需要高性能的系统(比如3D图形计算)的优秀选择。C++的另一个优点是OpenGL调用库是基于C语言开发的。
有许多可用的C++开发环境。在阅读本书时,如果读者使用PC(Windows操作系统),我们推荐使用Microsoft Visual Studio [VS20];如果在Mac上,我们推荐使用Xcode [XC18]。附录中也介绍了各个平台下C++开发环境的安装和配置。
OpenGL的1.0版本出现在1992年,是一种对各家供应商各不相同的计算机图形应用程序接口(Application Programming Interface,API)的“开放性”替代品。
它的规范和开发工作由当时新成立的OpenGL架构评审委员会管理和控制。ARB是由一群行业参与者组成的小组。2006年,ARB将OpenGL规范的控制权交给了Khronos Group。Khronos Group是一个非营利性联盟,不仅管理着OpenGL标准,还管理着很多其他的开放性行业标准。
从一开始,OpenGL就定期修订和扩展。2004年,2.0版本中引入了OpenGL着色语言GLSL,使得“着色器程序”可以被直接安装到图形管线的各个阶段并执行。
2009年,3.1版本中移除了大量被弃用的功能,以强制使用着色器编程,而不是之前的老方法(称为“立即模式”)[1]。4.0版本(2010年)在可编程管线中增加了一个曲面细分阶段。
本书假定读者的计算机有一个支持至少 4.3 版本 OpenGL 的显卡。如果你不确定你的GPU 支持哪个版本的 OpenGL,网上有免费的应用程序可以用来找出答案。其中一个是GLView,由realtech VR公司提供[GV20]。
OpenGL实际上并不是把图像直接绘制到计算机屏幕上,而是将之渲染到一个帧缓冲区,然后由计算机来负责把帧缓冲区中的内容绘制到屏幕上的一个窗口中。有不少库都可以支持这一部分工作。一个选择是使用操作系统提供的窗口管理功能,比如Microsoft Windows API。但这通常不实用,因为需要很多底层的编码工作。GLUT库曾经是一个很流行的选择,但现在已经被弃用了。它的一个现代化的变体是freeglut库。其他相关的选项还有CPW库、GLOW库、GLUI库等。
GLFW是最流行的选择之一,也是本书中选择使用的。它内置了对Windows、macOS、Linux和其他操作系统[GF20]的支持。它可以在其官网下载,并且需要在要使用它的计算机上编译。(我们在附录中介绍了相关步骤。)
OpenGL围绕一组基本功能和扩展机制进行组织。随着技术的发展,扩展机制可以用来支持新的功能。现代版本的OpenGL,比如我们在本书中使用的4.3以上版本,需要识别GPU上可用的扩展。OpenGL的核心中有一些内置的命令用来支持这一点,但是为了使用现代命令,需要执行很多相当复杂的代码。在本书中,我们会经常使用这些命令。所以使用一个扩展库来处理这些细节已经成了标准做法,这样能让程序员可以直接使用现代OpenGL命令。扩展库有Glee、GLLoader和GLEW,以及新版的GL3W和GLAD。
上面列出的这些库中,常用的是GLEW。这个名称代表OpenGL extension wrangler,即OpenGL扩展牛仔。GLEW支持各种操作系统,包括Windows、macOS和Linux [GE20],但它并不是完美的选择。例如,它需要一个额外的动态链接库。最近,很多开发者选择GL3W或者GLAD。它们的优势是可以自动更新,但是需要Python环境。本书使用GLEW。它可以在其官网下载。附录中给出了安装和配置GLEW的完整说明。
3D图形编程会大量使用向量和矩阵代数。因此,配合一个支持常见数学计算任务的函数库或者类包,能极大地方便OpenGL的使用。常常和OpenGL一起使用的两个这样的库是Eigen和vmath。后者在流行的《OpenGL超级宝典(第7版)》[SW15]中使用。
本书使用OpenGL Mathematics数学库,一般称作GLM。它是一个只有头文件的C++库,兼容Windows、macOS和Linux [GM20]。GLM命令能很方便地遵循和GLSL相同的命名惯例,使得来回阅读特定应用程序的C++和GLSL代码时更容易。GLM可以在其官网下载。
GLM可提供与图形概念相关的类和基本数学函数,例如矢量、矩阵和四元数。它还包含各种工具类,用于创建和使用常见的3D图形结构,例如透视和视角矩阵。它最早在2005年发布,由Christophe Riccio [GM20]维护。有关安装GLM的说明,请参阅附录。
从第5章开始,我们将使用图像文件来向图形场景中的对象添加“纹理”。这意味着我们会频繁加载这些图像文件到我们的C++/OpenGL代码中。从零开始编写一个纹理图像加载器是可以做到的。但是,考虑到各种各样的图像文件格式,使用一个纹理图像加载库通常是更好的。比如FreeImage、DevIL、GLI和Glraw。SOIL可能是最常用的OpenGL图像加载库,尽管它有点儿过时了。
本书中使用的纹理图像加载库是SOIL2——SOIL的一个更新的分支版本。像我们之前选择的库一样,SOIL2兼容各种平台[SO20]。附录中给出了其详细的安装和配置说明。
读者可能希望利用很多其他有用的库。例如,在本书中,我们将展示如何从零开始实现一个简单的OBJ模型加载器。然而,正如你将看到的,它没有处理OBJ标准中很多可用的选项。有一些更复杂的、现成的OBJ模型加载器可供选择,比如Assimp和tinyobjloader。本书的例子只会使用书中介绍和实现的简单模型加载器。
关于本书使用的C++版本,我们争吵了很久,因为我们想要找到囊括用来运行示例程序的平台特定的配置信息的最佳方法。配置C++来使用OpenGL的系统要比配置Java复杂得多。Java版本的配置只需要短短几个段落就可以描述完毕(正如在本书Java版中可看到的[GC18])。最终,我们选择把安装和配置信息在各平台特定的附录中分别进行描述。我们希望这能为每个读者提供对应其系统的特定信息,使读者不被与其无关的其他平台的信息干扰。在本书中,我们在附录A中提供了Windows平台的详细配置教程,在附录B中提供了macOS平台的详细配置教程。
本书的英文网站上将会持续维护更新的库安装指南。
[GC18] V. Gordon and J. Clevenger, Computer Graphics Programming in OpenGL with Java, 2nd ed. (Mercury Learning, 2018).
[GE20] OpenGL Extension Wrangler (GLEW), accessed July 2020.
[GF20] Graphics Library Framework (GLFW), accessed July 2020.
[GM20] OpenGL Mathematics (GLM), accessed July 2020.
[GV20] GLView, realtech-vr, accessed July 2020.
[SO20] Simple OpenGL Image Library 2 (SOIL2), SpartanJ, accessed July 2020.
[SW15] G. Sellers, R. Wright Jr., and N. Haemel, OpenGL SuperBible: Comprehensive Tutorial and Reference, 7th ed. (Addison-Wesley, 2015).
[VS20] Microsoft Visual Studio downloads, accessed July 2020.
[XC18] Apple Developer site for Xcode, accessed January 2018.
[1] 尽管如此,许多显卡厂商(比如 NVIDIA)依然继续支持被弃用的功能。