OpenGL外文翻译资料

 2022-08-10 16:42:44

英语原文共 540 页,剩余内容已隐藏,支付完成后下载完整资料


外文翻译

Part 1.导论

2.OpenGL

在开始我们的编程之旅前我们首先需要明确OpenGL到底是什么。OpenGL通常来说被认为是一个API(应用程序编程接口),它为我们提供了一系列的函数供我们来产生图形和图像。然而,OpenGL自身并不是一个API,而仅仅是一种规范,它由Khronos Group开发和维护。OpenGL规范详细定义了每一个函数应该输入和返回什么以及它应该如何工作。接下来由开发者来实现这个规范从而生成了一些函数应该如何运行的方法。由于OpenGL规范并不提供实现细节,实际的OpenGL完成版允许拥有不同的实现,只要它们的结果符合规范(因此对用户而言是一样的)就行。

一般来讲实现OpenGL库的人是图形卡制造商。你买的每一张图形卡都会支持特定版本的OpenGL,它是专为那张卡来设计的。譬如苹果系统,它的OpenGL是由苹果公司自己维护的。同时Linux系统背后也有一群图形供应商和爱好者来维护这些库。这也意味着当OpenGL表现出一些它本不该有的怪异行为时,这多半是图形卡制造商的问题(即维护OpenGL库的人)。

由于大多数的实现都由图形卡制造商来完成。当有bug出现时,你通常只要更新你的显卡驱动就能解决问题;这些驱动程序包含你的图形卡所支持的最新版本的OpenGL。这也是你应该时不时更新你的图形驱动的原因之一。

Khronos公开维护所有OpenGL版本的规范文档。感兴趣的读者可以在这找到OpenGL 3.3(也是这本书所用的版本)的规范说明,如果你想深入了解OpenGL的细节的话,这将是个不错的选择(注意它们仅仅只描述了结果而非实现)。这些规范也为你了解这些函数具体工作方法的一个很好的参考。

2.1 内核模式 VS 立即模式

早些时候,使用OpenGL意味着使用立即模式(或固定渲染管线)来开发程序,这也确实是描绘图形的一种方便的方法。OpenGL大多数的功能都隐藏在库中而开发者对于OpenGL如何完成计算并没有太多编程上的自由。开发者于是要求更多的灵活性,随后这些规范也就变得更加灵活;开发者获得了对它们图形卡更多的控制权。立即模式的确十分容易使用也容易理解,但是它也极其没有效率。正因如此,OpenGL规范开始将立即模式功能从3.2版本标注为过时并鼓励开发者使用转向OpenGL的内核模式,它是OpenGL规范的一个移除了所有过时功能的分支。

当我们使用OpenGL的内核模式时,OpenGL会强制我们使用一些现代的技术。当我们试图使用一个OpenGL的过时函数时,OpenGL会抛出一个错误并停止绘制。使用现代编程方法的优点就是它非常灵活且高效,然而不幸的是它也更难学习。立即模式从OpenGL实现的真正操作中抽象出了许多东西,虽然它容易学习,但它也让人更难了解OpenGL到底是怎样工作的。而现代的编程方法要求开发者真正理解OpenGL和图形编程——虽然它有些困难,但它能够提供更多的灵活性,更高校,而且最重要的是它能让你更好的理解图形编程。

这也是为什么我们的教程是为OpenGL 3.3版本的内核模式而准备的。尽管它更加困难,但这些困难确实值得。

到了今天,已经有更高版本的OpenGL发布了(写作本书时已有4.5版本),那么你可能会问:问什么我在OpenGL4.5版本发布之时还要去学3.3版本?答案其实相当简单。从3.3起的所有OpenGL版本基本上都只是为OpenGL添加一些额外的有用的特性而没有改变OpenGL的核心机制;更新版本的OpenGL只是添加了一些更高效或是更简便的方法来完成同样的工作。结果就是所有的概念和技术都同现代的OpenGL版本相同,因此学习3.3版本同样是十分有效的。当你已经有所准备或有过经验之后,你自然能够非常轻松地使用OpenGL最新版本的特定功能。

当你使用一些OpenGL较新版本才有的功能时,只有在最新的图形卡上你的程序才能跑起来。这就是为什么开发者通常针对低版本OpenGL开发程序,同时选择性地启用更高版本的功能。

在一些教程中你会时不时发现一些更现代的特性,正如我们下面即将提到的一样。

2.2 扩展

OpenGL的一个非常棒的特性就是它对扩展性的支持。当图形公司开发了一些新的技术或是对渲染的一个重大优化时,它通常都包含在图形驱动的扩展实现中。

如果运行应用程序的硬件支持这样一种扩展,那么开发者就能使用这些扩展功能来实现更高级或更高效的图形处理。用这种方法,一个图形开发者依然能够使用这些新的渲染特性而无需等OpenGL来发布新版本将这些功能涵盖进去,开发者只需要简单地检查图形卡是否支持这些扩展。通常来讲,当一项扩展非常常见或是非常有用时,它最终会成为OpenGL未来版本的一部分。

之后,开发者需要检查这些扩展是否可用(或使用OpenGL扩展库)。这允许开发者根据硬件是否支持扩展特性来更好更高效地完成任务:

if(GL_ARB_extension_name)

{

// Do cool new and modern stuff supported by hardware

}

else

{

// Extension not supported: do it the old way

}

在OpenGL3.3版本中我们很少需要一项技术地扩展,但当它必要时我们也会提供合适的指导。

2.3 状态机

OpenGL自身是一个十分巨大的状态机:一系列定义OpenGL现在应该如何工作的值。OpenGL的状态通常被称作OpenGL上下文。当我们使用OpenGL时,我们经常通过设置一些选项,操作一些缓存来改变它的状态,然后使用当前上下文来渲染。

比如当我们告诉OpenGL我们现在想要画线而非三角形时我们会通过改变一些上下文变量来改变OpenGL的状态,这些变量设定了OpenGL应该如何绘制图形。只要我们改变状态告诉OpenGL应该画线了,下一次绘制指令就将绘制直线而非三角形。

当使用OpenGL时我们将会发现一些能够改变上下文的状态改变函数和一些基于当前上下文完成一些操作的状态使用函数。只要你记住OpenGL基本上就是一个大状态机,它的大多数的功能就能更容易被理解。

2.4 对象

OpenGL库是用C语言写的同时也有很多其它语言的变种,但它的核心部分还是一个C语言库。因为许多C语言的结构并不能很好地转换成其它高级语言,OpenGL本质上是通过一些抽象层来开发的。其中一个抽象层就是对象。

OpenGL的一个对象本质上是一个表示OpenGL状态子集的一系列选项。例如,我们可能有一个表示绘制窗口设置的对象;我们之后可以设置它的大小,它支持多少颜色等等。我们可以把它想象成一个类似C语言结构体的样子:

struct object_name { GLfloat option1; GLuint option2; GLchar[] name;

};

原始类型:

当你使用OpenGL时我们建议你使用OpenGL预定义的数据类型。比如我们使用GL来代替float;对于int,uint,char,bool等也是同样。OpenGL用一种跨平台的方式来定义GL原始数据类型因为某些操作系统可能对于这些数据类型有不同的内存布局。使用OpenGL的原始数据类型能帮助你确保你的程序能够跨平台工作。

当我们使用对象时它通常看起来像这样:(OpenGL的上下文被视作一个大的结构体)

// The State of OpenGL struct OpenGL_Context {

...

object* object_Window_Target;

...

};

// Create object GLuint objectId = 0;

glGenObject(1, amp;objectId);

// Bind object to context glBindObject(GL_WINDOW_TARGET, objectId);

// Set options of object currently bound to GL_WINDOW_TARGET glSetObjectOption(GL_WINDOW_TARGET, GL_OPTION_WINDOW_WIDTH, 800);

glSetObjectOption(GL_WINDOW_TARGET, GL_OPTION_WINDOW_HEIGHT, 600);

// Set context target back to default glBindObject(GL_WINDOW_TARGET, 0);

这一小块代码是一个你使用OpenGL时经常会见到的工作流程。我们首先创建一个对象然后以ID的形式保存一个它的引用(真正的对象数据是不可见的)。然后我们将这个对象绑定到一个上下文的目标位置(示例窗口对象目标的位置被定义为GL_WINDOW_TARGET)。接下来我们给这个窗口设置一系列选项,最终我们通过把当前窗口目标的对象ID设为0来解绑。我们已经设置的选项被objectID储存,只要我们再次把它绑定到GL_WINDOW_TARGET这些设置就会恢复。

上面的示例代码仅仅展示了OpenGL大致的工作;在这本教程中你还会遇见很多的实例。

使用这些对象的一大好处是我们可以在我们的应用程序中定义多个对象,设置它们的选项,然后只用我们开始一项需要用到OpenGL状态的操作,我们就将这个对象与需要的设置绑定。比如有一些对象用作3D模型数据的容器(一座房子或者一个人物),如果我们想要渲染它们中的一个,我们就绑定我们想要渲染的包含模型数据的对象(首先要创建并设置这些对象)。拥有多个对象允许我们定义许多模型而且只要我们想渲染一个特定的模型,我们只需简单地在渲染绑定相应对象而无需重新设置它们地选项。

2.5 让我们开始吧

你现在已经对OpenGL地规范和库,以及在背后OpenGL大致是如何工作的和它使用的一些小技巧有所了解了。如果你没有完全理解它,那也没关系;在这本教程中我们会涉及每一步而你会见到足够多的例子来帮你真正理解OpenGL。如果你已经准备好了,我们就可以在这开始创建一个OpenGL上下文和我们的第一个窗口了。

2.6 补充资源

- opengl.org: OpenGL的官方网站

- OpenGL registry: 主编OpenGL的规范和所有OpenGL版本的扩展。

3. 创建窗口

创建我们美丽图画的第一步就是创建一个OpenGL上下文以及一个用于绘画的应用程序窗口。然而,这些操作是依赖于操作系统的所以OpenGL有意的试图将这些操作抽象出来。这意味着我们需要创建一个窗口,定义一个上下文并自己处理用户输入。

幸运的是,有许多库已经为我们提供了我们需要的功能,其中一些还是专门为OpenGL设计的。那些库为我们省去了所有依赖于操作系统的工作并提供给我们一个窗口和一个OpenGL上下文用于渲染。其中一些比较流行的库包括GLUT,SDL,SFML,GLFW。在这本教程中我们将使用GLFW。

3.1 GLFW

GLFW是一个用C语言编写,针对OpenGL的库,用来提供对于在屏幕上画些东西最基本的支持。它允许我们创建一个OpenGL上下文,定义窗口参数并处理用户输入,这正是我们所需要的。

本节和下一节的内容是构建GLFW并让它运行起来,确保它正确地创建一个OpenGL上下文并正确地为我们显示一个用于渲染的窗口。这篇教程将一步一步地告诉你如何提取,构建并链接GLFW库。本教程中我们将使用Microsoft Visual Studio 2012。如果你没有使用Visual Studio(或者是一个旧版的VS),别担心,这个过程对于其它IDE来说基本上是差不多的。Visual Studio 2012(或是其它版本)可以在微软官网免费下载学习版。

3.2 构建GLFW

GLFW可以从他们的官方网页下载。GLFW已经有针对Visual Studio 2012/2013的预编译的二进制文件和头文件,但是出于完整性考虑我们将自己从源代码编译GLFW。那么就让我们开始下载源代码包吧。

如果你使用的是预编译版本,确保下载的是32位版本而非64位版本(除非你确实了解它)。许多读者报告了64位版本的一些诡异的错误。

如果你已经下载好了源码包,解压并打开它。我们只对其中一些东西感兴趣:

- 编译的输出库

- include文件夹

由源代码编译出库确保了你生成的库是完美适配于你的CPU和操作系统的,而预编译的二进制文件通常不能够保证这一点(有些时候,预编译的二进制文件甚至不能在你的系统上工作)。将源码开放给全世界的一个问题是并不是每个人都用相同的IDE来开发他们的程序,这意味着项目/解决方案文件可能与其他人的IDE并不适配。因此人们不得不使用它们自己的项目/解决方案然后将这些.c/.cpp/.h文件包含进来,这相当繁琐。尤其是还有这么一个叫做CMake的工具。

3.2.1 CMake

CMake是一个能够根据用户选择使用预定义的CMake算法从一堆源文件中生成对应的项目/解决方案文件

剩余内容已隐藏,支付完成后下载完整资料


资料编号:[238243],资料为PDF文档或Word文档,PDF文档可免费转换为Word

原文和译文剩余内容已隐藏,您需要先支付 30元 才能查看原文和译文全部内容!立即支付

发小红书推广免费获取该资料资格。点击链接进入获取推广文案即可: Ai一键组稿 | 降AI率 | 降重复率 | 论文一键排版