前言
本书的主要目标是用作计算机科学专业本科OpenGL 3D图形编程相关课程的教材。同时,我们也付出了很大的努力,让本书成为一本无须配合课程使用的自学教材。在以这两者为目标的前提下,我们尽力将内容解释得简单而清晰。本书中的所有代码示例都已经尽可能地简化,同时没有破坏其完整性,以便读者可以直接运行。
我们期望本书与众不同的一点是,新手(刚接触3D图形编程的人)更容易学习。关于这个主题的学习资料从来都不匮乏,恰恰相反,很多新手刚入门的时候,相关的资料就扑面而来了。我们刚接触3D图形编程的时候,就期望能遇见这样的教材——一步步解释基础概念,循序渐进并有序地梳理进阶概念,因此我们也尝试将本书编写成这样的教材。我们曾想将本书命名为shader programming made easy(《轻松学着色器编程》),虽然我们并不认为有什么方法能真的让着色器编程变得“轻松”,但我们希望本书能够帮助你尽可能地达成这个目标。
本书使用C++进行OpenGL编程教学。使用C++学习图形编程有以下几个好处。
●由于OpenGL的原生语言是C,因此C++程序可以直接进行OpenGL函数调用。
●C++编写的OpenGL应用程序通常有着很好的性能。
●C++提供C语言所没有的现代编程结构(类、多态等)。
●在OpenGL社区中,C++是一个热门选项。许多OpenGL的教学资源有C++版本。
值得一提的是,OpenGL也存在着与其他语言绑定。常见的有Java、C#、Python等,但本书仅关注C++。
本书与众不同的另一点是它有一个Java版,英文书名是Computer Graphics Programming in OpenGL with Java。这两本书是按同样的节奏组织的,它们使用相同类型的章节编号、主题、图表、习题和讲解方式,其代码组织方式也尽可能地相似。诚然,使用C++或Java编程肯定有着相当大的差异。尽管如此,我们相信这两本书提供了几乎相同的学习路径,甚至可以让选修同一门课的学生使用不同的语言版本作为教材。
需要说明的一点是,OpenGL有着不同的版本(稍后简述)和不同的变体。例如,在标准OpenGL(也称桌面OpenGL)之外,还有一个变体叫作OpenGL ES。它是为嵌入式系统(Embedded System)的开发而定制的(因此称为ES)。“嵌入式系统”包括手机、游戏主机、汽车和工业控制系统之类的设备。OpenGL ES的大部分内容是标准OpenGL的子集,删除了嵌入式系统通常用不到的很多操作。OpenGL ES还增加了一些功能,通常是特定目标环境下的特定功能。本书侧重于标准OpenGL。
OpenGL的另一种变体称为WebGL。WebGL基于OpenGL ES,它的设计目标是支持在浏览器中运行OpenGL。WebGL允许应用程序通过JavaScript进行OpenGL ES操作调用,从而简单地将OpenGL图形嵌入标准HTML(Web)文档中。大多数现代Web浏览器,包括Apple Safari、Google Chrome、Microsoft Internet Explorer、Mozilla Firefox和Opera,支持WebGL。由于Web编程超出了本书的讨论范围,因此本书不会涵盖WebGL。不过,由于WebGL基于OpenGL ES,而OpenGL ES又基于标准OpenGL,因此本书所涵盖的大部分内容可以直接迁移到这些OpenGL变体的学习中去。
3D图形编程这个主题通常让人想起精美而宏大的画面。事实上,许多相关热门教材中充满了令人惊叹的场景,很大程度上是为了吸引读者翻阅他们的图库。虽然我们认同这些图例的激励作用,但我们的目标是教学而非令人惊叹。本书中的图像仅仅是示例程序的输出。由于本书只是入门教程,其渲染的场景应该无法让专家侧目。然而,本书呈现的技术确实是构成当今这些炫目3D效果的基础。
我们没有尝试写一本“OpenGL参考大全”,因此,本书所涵盖的OpenGL部分只是其所有功能中的一小部分。我们的目标是以OpenGL作为基础工具,教授基于现代着色器的3D图形编程,并为读者提供足够深入的理解,以供进一步研究。
目标读者
本书的主要目标读者是计算机科学专业的学生(可以是本科在读学生),其实任何想要学习计算机科学相关知识的人也适合阅读本书。因此,我们假设读者有扎实的面向对象编程基础,至少相当于计算机科学专业大二或大三学生的水平。
还有一些本书没有涵盖的内容,因为我们假设读者已经掌握了足够的背景知识,包括:
●C++及其常用库,如标准模板库(Standard Template Library);
●熟悉集成开发环境(Integrated Development Environment,IDE),如Visual Studio;
●事件驱动编程概念;
●基础矩阵代数、三角函数;
●了解颜色模型,如RGB、RGBA等。
希望本书的潜在受众能够因为对其Java版的喜爱而进一步支持本书。正如前面所说的,我们期望看到这样一种情景——学生在同一门课中可以自由选择使用C++或Java版本的教材。由于这两本书按同样的节奏对教学内容进行组织编排,因此我们认为可以尝试以这种开放的方式来开展课程教学和学习。
如何使用本书
本书从内容安排上适合从前往后阅读,即后面各章中的内容经常依赖于前面各章中所讲的内容。因此,在各章中来回跳跃地选择性阅读可能并不适合本书,读者最好逐章顺序阅读。
本书同时可以作为实用的动手指南。由于已经有许多其他偏理论的学习材料,因此读者应该将本书作为一本“练习册”,通过一边参考本书一边自己动手编程来理解基础概念。虽然我们为所有的示例提供了代码,但是想要真正理解这些概念,还是得自己动手“实现”这些代码——通过编程来搭建你自己的3D场景。
本书在第2章到第14章的最后都留给读者一些习题。有的题比较简单,仅仅需要对提供的代码进行简单改动就可以解决。那些标记为“项目”的习题,则需要读者花费更多的时间来解答,因为可能需要编写大量代码或者使用多个示例中用到的技术。少数标记为“研究”的习题,则在本书中并没有提供解题需要学习的细节知识,我们鼓励读者进行自主学习并解答。
OpenGL调用通常会有很长的参数列表。在撰写本书时,两位作者在每种情况下都会讨论是否要描述所有的参数。最终我们决定在最初的部分描述所有参数。随着主题深入,我们避免在每次OpenGL调用中陷入细枝末节的描述过程(因为调用的次数很多),以防读者失去对全局的理解。因此,在浏览示例时,读者需要在手边准备OpenGL和所使用的各种库的参考资料。
为此,我们建议结合一些优秀的在线资源使用本书。OpenGL的文档是绝对必要的。有关各种命令的详细信息,可以利用搜索引擎,或访问OpenGL的官方网站获取。
我们的示例中用到了称作GLM的数学库。在安装GLM(见附录)后,读者应该找到其在线文档并将其加入书签。
本书中经常用到的另一个库是SOIL2,用于读取和处理纹理图像文件,读者可能也需要定期查阅它的文档。SOIL2没有中心化的文档资源,但读者通过Web搜索可以找到一些例子。
还有许多关于3D图形编程的图书,我们建议与本书并行阅读(例如要解决各章后的“研究”问题)。以下是我们经常提到的5本。
●[SW15] Sellers et al. OpenGL SuperBible.
●[KS16] Kessenich et al. OpenGL Programming Guide.
●[WO13] Wolff, OpenGL 4 Shading Language Cookbook.
●[AS14] Angel and Shreiner, Interactive Computer Graphics.
●[LU16] Luna, Introduction to 3D Game Programming with DirectX 12.
配套资源
本书提供随书的配套资源供读者下载,其内容有:
●书中所有C++ / OpenGL程序和相关的实用类文件以及GLSL着色器代码;
●各种程序和示例中使用的模型和纹理文件;
●用于制作天空和地平线的天空顶和立方体贴图图像文件;
●用于照明和表面细节效果的法线贴图和高度贴图;
●本书中所有的图表以图像文件形式提供。
上述文件也可以通过访问异步社区(www.epubit.com)上的本书页面获取。
教师辅助
我们鼓励大学或学院的教师获取本书的教师辅助包,其中包含以下附加项:
●一套完整的PowerPoint幻灯片,涵盖本书中的所有主题;
●本书中大多数章末习题的答案和所需代码;
●基于本书的课程大纲示例;
●每章用于讲解材料的额外内容。
教师辅助包可以通过联系出版商获取:contact@epubit.com.cn。
致谢
本书中的许多内容是基于我们之前出版的Computer Graphics Programming in OpenGL with Java。我们需要感谢许多帮助我们完成上一本书的人,他们继续为本书的编写提供了帮助。Java版早期的草稿被用于加州州立大学萨克拉门托分校的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的建议。
我们也从许多教师那里得到了很好的反馈,他们采用Computer Graphics Programming in OpenGL with Java作为课程教材,同时向我们分享了他们的教学经验。塔尔萨大学的Mauricio Papa博士和我们进行了几次对我们非常有帮助的邮件沟通。Sean McCrory对光照(第7章)和柏林噪声(第14章)出现的问题进行了非常详细的修正。他们的建议帮助我们对本书进行了改进。我们还收到了许多来自不同学校的学生提出的问题,这些问题帮助我们评估了我们编写方法的优缺点。
我们对本系列书的第一次试用是在2017年的秋天,当时我们的同事Pinar Muyan-Ozcelik博士在她教授的CSc-155课程上第一次使用了Computer Graphics Programming in OpenGL with Java,这让我们有机会评估我们是否实现了让本书成为“自学”资源的目标。课程进展顺利的同时,Pinar Muyan-Ozcelik博士也为每章留存了问题和更正日志。这份日志帮我们对本书进行了许多改进。
Martín Lucas Golini是SOIL2纹理图像处理库的开发者和维护者,也对本书表现出了极大的支持和热情。我们对他的帮助表示非常感谢。
Jay Turberville来自于亚利桑那州Scottsdale的Studio 522 Productions。他创建了本书英文版的封面和书中用到的海豚模型,学生们非常喜欢。Studio 522 Productions制作出极高质量的3D动画和视频,以及自定义3D建模。我们很感谢Turberville慷慨地为本书创建这个精美的模型。
我们还要感谢其他一些艺术家和研究人员。他们非常慷慨地让我们使用他们的模型和纹理。来自Planet Pixel Emporium的James Hastings-Trew提供了许多行星表面纹理。Paul Bourke允许我们使用他拥有的精彩的星域。斯坦福大学的Marc Levoy博士授权我们使用著名的“斯坦福龙”模型。Paul Baker的凹凸贴图教程是我们在许多例子中使用的“圆环”模型的基础。我们还要感谢Mercury Learning允许我们使用《DirectX 12 3D游戏开发实战》中的一些纹理。
Danny Kopec博士向我们介绍了Mercury Learning公司,并向它的出版商David Pallai引荐了我们。Kopec博士的《人工智能(第2版)》的成功出版让我们考虑与Mercury合作,我们与Kopec的电话交谈也对我们非常有帮助。Kopec博士的早逝让我们深感悲痛,也对他没有机会看到本书的成书感到遗憾。
最后,我们要感谢Mercury Learning的David Pallai和Jennifer Blaney,他们一直保持着对这个项目的热情并引导我们完成了本书的整个出版流程。
勘误
如果你在阅读本书时发现任何错误,请告诉我们!尽管我们尽了最大努力,但本书肯定还有错误。当收到错误报告时,我们将会尽最大努力尽快发布。我们建立了一个用于收集并发布勘误的网页:
http://athena.ecs.csus.edu/~gordonvs/errata.html
出版商Mercury Learning也保留了本书勘误表页面的链接。因此,如果我们的勘误页面的URL有变动,请查看Mercury Learning网站以获取最新链接。