3 创建一个窗口

来源:互联网 发布:凤凰金融 以大数据 编辑:程序博客网 时间:2024/06/05 17:47
本文译自www.learnopengl.com,作者Joey de Vries.

在可以创建出炫目的图像之前,我们需要创建一个OpenGL环境,以及一个应用程序窗口。但是,这些操作在每个OS中都有所不同,而OpenGL有意从这些操作系统中抽象出来。这意味着我们必须创建一个窗口,定义一个环境,并自己处理所有的用户输入。

幸运的是,还真有一些库为我们提供了这些功能。有些正是为OpenGL开发的。这些库免去了所有跨平台的问题,同时也为我们提供了窗口和OpenGL环境等渲染所需的功能。流行的库主要有GLUT、SDL、SFML和GLFW。教程中我们使用GLFW。

 

GLFW

GLFW是一个C写的专门用于OpenGL开发的库,它只提供把物体渲染到屏幕所需的必要功能。它可以给我们创建一个OpenGL环境,定义窗口参数,以及相应用户输入,这些都是必要的功能。

本节和下一节关注如何使GLFW运行起来,确保它正确地创建一个OpenGL环境,使窗口合理地展示,为渲染做好准备。这个教程从获取、编译和链接GLFW库,一步一步地展开。我们将使用Microsoft Visual Studio 2012作为IDE。如果你用的不是Visual Studio(或者是使用的是老版本)也不用担心,这个配置过程也和使用其他大多数IDE差不多。Visual Studio 2012(或是其他版本)可以免费地从微软下载,选择express版就行。

 

构建GLFW

GLFW可以从他们的网站下载。GLFW也有为Visual Studio 2012/2013提供的已经编译好的二进制和头文件,但是为了追求获得完整的体验,我们会自己用源码自己编译一遍。所以先去下载源码包吧。

如果你使用它们的已经编译好的二进制文件,要确保下载的是32位版本,不要下载64位版(除非你知道自己在做什么)。很多读者都报告64位版会导致诡异的错误。

下载了源码包,解压然后打开它。我们只对里面几个东西感兴趣:

  • 用于编译的库的源码。
  • include文件夹。

用源码编译库保证了编译出来的库完美适应你的CPU/OS,那种奢侈的编译好的二进制不是总能提供这样的通用性(有时二进制库甚至在你的系统上不能用)。而从源码编译也有一个问题——不是所有人都用同样的IDE来开发它们的应用,这意味着项目/解决方案(project/solution)的文件可能与其他人的IDE不兼容。所以人们就必须去用.c/.cpp和.h/.hpp文件编译他们各自的项目/解决方案,这挺让人头疼的。我们这里使用一个叫做CMake的工具解决这个问题。

 

CMake

CMake是一个可以生成项目/解决方案的工具,它以使用CMake的预定义脚本让用户选择目标IDE(比如:Visual Studio、Code::Blocks、Eclipse)。这样我们就可以从GLFW的源码包生成Visual Studio 2012的项目文件了,然后就能编译出这个库。首先我们需要下载和安装CMake,可以从他们的下载页找到。我用的是Win32 Instanller。

当CMake安装好了,你可以选择是从命令行还是GUI来运行CMake。由于我们不打算把问题复杂化,我们会使用GUI。CMake需要一个源码文件夹和一个用于生成二进制的目标文件夹。我们把source code目录设置为下载的GLFW根目录。然后创建一个叫做build的目录作为二进制输出的目录(Where to build binaries)。图片1

源码和目标文件夹设置好了之后,点击Configure按钮,这时CMake就可以读取到需要的配置和源码了。我们必须选择项目的生成器。因为我们使用的是Visual Studio 2012我们会选择Visual Studio 11选项(Visual Studio 2012也就是Visual Studio11)。CMake会利用可用的编译选项来配置源码库。我们可以给它们设置为默认值,再次点击Configure储存设置。当配置已经完成,我们可以点击Generate,最后的项目文件就会出现在build文件夹中了。

 

编译

在build文件夹里有个文件叫做GLFW.sln,我们用Visual Studio 2012打开。由于CMake生成了一个已经包含了合适的配置的项目文件,我们可以点击Build Solution按钮,编译好的库就出现在src/Debug目录中了,它是glfw3.lib(注意,后缀3代表我们使用的是版本3)。

库生成之后,我们需要确保IDE知道从哪里找到库来包含文件。有两种方式达到这个目标:

  • 我们找到IDE/编译器的/lib和/include文件夹,添加GLFW的include文件夹到IDE的/include文件夹,同样添加glfw3.lib到IDE的/lib文件夹。这虽能够工作,但是不推荐。这样很难跟踪你的library/include文件,新安装了一个IDE/编译器后这些文件也就不可用了。
  • 推荐的方式是创建一个新的目录来储存你的第三方头文件和lib,这样你可以在IDE/编译器中引用。我个人使用一个单独文件夹来储存lib和include文件夹,那个文件夹是我所有的OpenGL项目所需的头文件和lib。现在所有第三方都组织在一个单独目录中(它可以在多个计算机中共享)。这样的话,每次我们创建一个新项目的时候都必须告诉IDE去哪儿找到这些路径。

当所需文件储存到了一个你选择的路径里,我们就可以使用GLFW创建我们第一个OpenGL项目了!

 

第一个项目

首先,我们打开Visual Studio创建一个新项目。选择Visual C++,如果有多个选项的话,选Empty Project(空项目),别忘了给你的项目取一个合适的名字。现在我们有了一个工作空间来创建我们第一个OpenGL应用了!

 

链接

为了项目能够使用GLFW,我们需要把这个库链接到项目上。这样就要在链接设置中指定glfw3.lib,但目前我们的项目还不知道在哪儿去找到glfw3.lib。这是因为我们把第三方库粘贴到了一个不同的目录里。我们需要把这些目录先加到我们的项目里。

添加这些路径(就是让VS搜索哪些lib和include文件)要到项目属性那里设置(在solution explorer中右击项目名)然后进入VC++ Directories列表,如下图所示:

图片2

在那里你可以添加自己的路径,好让项目知道去哪儿搜索。可以手动插入到文本中,或者点击需要的那个路径字符串,选择<Edit..>选项,在那里你会看到如下所示图片:

图片3

在这儿,你可以随意添加多个附加路径。当IDE搜索头文件的时候,也会搜索这些目录,所以一旦你引入了GLFW的Include文件夹,你就能通过包含<GLFW/..>找到所有的GLFW的头文件了。这同样也适用于lib的路径。

这时VS就能找到所有需要的文件了,我们最后把GLFW链接到项目,到Linker列表,选择input:

图片4

为了链接一个库,你必须向连接器指出这个库的名字。由于这个库的名字是glfw3.lib。我们就把它添加到Additional Dependencies框中(无论手动或是使用<Eidit..>选项都行),这时候当我们编译时,GLFW就被链接了。除了GLFW,你也要把OpenGL库连接上,但是在每个操作系统上都有所不同:

 

Windows上的OpenGL库

如果你在Windows上用OpenGL库,Microsoft SDK提供了一个opengl32.lib,它是你安装Visual Studio时自带的。因为这个教程使用的是VS编译器,操作系统是windows,我们把opengl32.lib加到链接设置里就行了。

 

Linux上的OpenGL库

在Linux系统里我们需要通过添加-lGL到你的连接器设置上来链接到libGL.so。如果你找不到这个库,你也许需要安装一个Mesa、NVdia或者AMD开发包。但是我不会解释太多细节,因为它根据平台会有所不同(此外,我也对Linux不是很精通)。

之后,你可以把GLFW和OpenGL库添加到链接设置里,添加GLFW的头文件这么做:

前文总结了安装和配置GLFW。

 

GLEW

自此,我们还没把准备工作做完,现在还有一件事情需要做。由于OpenGL是一种标准/规范,它需要由驱动制造商在驱动中来实现这份特定的显卡支持规范。因为有许多不同版本的OpenGL驱动,OpenGL的大多数函数在编译时(compile-time)是未知状态的,需要在运行时(run-time)来请求。这就是开发者的任务了,开发者获取他/她所需要的函数的地址,把它们储存在函数指针中以备后用。获取这些地址是依系统而定的,在Windows中它看起来像这样:

如你所见,这段代码看起来有点儿复杂了,你所需要的函数还没被声明,所以为每个函数都做一遍这件事是在有点麻烦。幸运的是有一些为了解决这个问题应运而生的工具,目前最流行而且持续更新着的库是GLEW。

 

构建和链接GLEW

GLEW是OpenGL Extension Wrangler Library的缩写,它管理着之前我们提到的那件麻烦事。由于GLEW是一个库,所以我们需要把它构建/链接到我们的项目上。GLEW可以从他们的下载页面中下载到,如果你的平台已经在他们的列表中也可以选择他们的预先编译的二进制版本,当然你也可以像前面编译GLFW那样从源码中自己编译。同样的,如果你不确定你在干什么就使用GLEW的32位库吧。

我们会使用GLEW的静态版本,它是glew32s.lib(注意后面的’s’),把这个库添加到你的库文件夹里,同样也把include的内容添加到你自己的include文件夹。下面我们就可以通过把glew32s.lib添加到VS的链接配置,从而把GLEW链接到项目上了。需要注意的是GLFW3默认也是被编译为静态库的。

静态链接库的意思是,在编译库的时候会整合到你的二进制文件当中,这样做的好处是你不必保持跟踪这额外的文件,只需要发布你的单独的二进制文件。缺点是你的可执行文件会变得更大,当一个库有一个更新的版本时你需要重新编译整个的应用程序。

动态链接库就是.dll或.so文件,库的代码是与你的二进制代码分开存在的,它可以使你的二进制文件更小,更新的时候也更容易,不足之处是你必须在你的最终的应用程序中发布你的DLL文件。

如果你使用GLEW的静态库,我们必须在包含GLEW之前定义一个预处理变量GLEW_STATIC。

如果你想使用动态库你要移除对GLEW_STATIC的定义。不要忘记如果你想用动态库,你就得把.DLL复制到你二进制文件的同一个文件夹里。

对于在Linux上使用GCC编译的用户,下面的命令行选项可以帮你编译项目-lGLEW -lglfw3 -lGL -lX11 -lpthread -lXrandr -lXi。不正确地链接相应的库会导致未定义引用(undefined reference)错误。

现在我们成功地编译和链接了GLFW和GLEW,这些是为下一节所做的准备,下节我们会讨论如何使用GLFW和GLEW来配置一个OpenGL环境以及弹出一个窗口。确保你的include和lib路径是正确的,链接器设置中的lib的名字和库的名字相匹配。如果你仍然为问题所困,去检查注释,查看每个附加资源,或者在下面提问。

 

附加资源

  • 构建应用: provides great info about the compilation/linking process of your application and a large list of possible errors (plus solutions) that might come up.
  • GLFW在Code::BLocks中的使用: building GLFW in Code::Blocks IDE.
  • 使用CMake:short overview of how to run CMake on both Windows and Linux.

 


①译注:GLUT并不建议使用,GLFW的目前不支持Android和IOS平台,SDL也不错稍微多一点学习成本但跨平台效果更好,当然你还可以使用Qt。

0 0