入门-02.创建窗口

创建窗口

在我们画出出色的效果之前,首先要做的就是创建一个OpenGL上下文(Context)和一个用于显示的窗口。然而,这些操作在每个系统上都是不一样的,OpenGL有目的的抽象(Abstract)这些操作。这意味着我们不得不自己处理创建窗口,定义OpenGL上下文以及处理用户输入。
幸运的是,有一些库已经提供了我们所需的功能,其中一部分是特别针对OpenGL的。这些库节省了我们书写平台相关代码的时间,提供给我们一个窗口和上下文用来渲染。最流行的几个库有GLUT,SDL,SFML和GLFW。在教程里我们将使用GLFW。

GLFW

GLFW是一个专门针对OpenGL的C语言库,它提供了一些渲染物件所需的最低限度的接口。它允许用户创建OpenGL上下文,定义窗口参数以及处理用户输入。
这一节和下一节的内容是建立GLFW环境,并保证它恰当地创建窗口和OpenGL上下文。

构建GLFW

GLFW已经有针对Visual Studio 2012/2013的预编译的二进制版本(优先选择32为版本)和相应的头文件,但是为了完整性我们将从编译源代码开始,

  1. 下载源代码包。
  2. 一旦下载完了源码包,解压到某处。我们只关心里面的这些内容:
    编译生成的库
    include文件夹

从源代码编译库可以保证生成的目标代码是针对你的操作系统和CPU的,而一个预编译的二进制代码并不保证总是适合。提供源代码的一个问题是不是每个人都用相同的IDE来编译,因而提供的工程文件可能和一些人的IDE不兼容。所以人们只能从.cpp和.h文件来自己建立工程,这是一项笨重的工作。因此诞生了一个叫做CMake的工具。

CMAKE
CMake是一个工程文件生成工具,可以使用预定义好的CMake脚本,根据用户的选择生成不同IDE的工程文件。这允许我们从GLFW源码里创建一个Visual Studio 2012(或其他版本)工程文件。

CMake需要一个源代码目录和一个存放编译结果的目标文件目录。源代码目录我们选择GLFW的源代码的根目录,然后我们新建一个build文件夹来作为目标目录。


之后,点击Configure(设置)按钮,我们选择生成的目标平台为Visual Studio 11(因为Visual Studio 2012的内部版本号是11.0)。CMake会显示可选的编译选项,这里我们使用默认设置,再次点击Configure(设置)按钮,保存这些设置。保存之后,我们可以点击Generate(生成)按钮,生成的工程文件就会出现在你的build文件夹中。

编译
在build文件夹里可以找到GLFW.sln文件,用Visual Studio 2012打开。因为CMake已经配置好了项目所以我们直接点击Build Solution(构建解决方案)然后编译的结果glfw3.lib就会出现在src/Debug文件夹内。(注意我们现在使用的glfw的版本号为3.1)
生成库之后,我们需要让IDE知道库和头文件的位置。有两种方法:

找到IDE或者编译器的/lib和/include文件夹,之后添加GLFW的include目录到/include里去,相似的将glfw3.lib添加到/lib里去。这不是推荐的方式,因为很难去追踪library/include文件夹,而且重新安装IDE/Compiler可能会导致这些文件丢失。
推荐的方式是建立一个新的目录包含所有的第三方库文件和头文件,并且在你的IDE/Compiler中指定这些文件夹。我个人使用一个单独的文件夹包含Libs和Include文件夹,在这里存放OpenGL工程用到的所有第三方库和头文件。这样我的所有第三方库都在同一个路径(并且应该在你的多台电脑间共享),然而要求是每次新建一个工程我们都需要告诉IDE/编译器在哪能找到这些文件
完成上面步骤后,我们就可以使用GLFW创建我们的第一个OpenGL工程了!

我们的第一个工程

让我们打开Visual Studio,创建一个新Viesual C++的工程。

链接(Linking)

为了使我们的程序使用GLFW,我们需要把GLFW库链接(Link)进工程。于是我们需要在链接器的设置里写上glfw3.lib。但是我们的工程还不知道在哪寻找这个文件,于是我们首先需要将我们放第三方库的目录添加进设置。
为了添加这些目录,我们首先进入Project Properties(工程属性)(在解决方案窗口里右键项目),然后选择VC++ Directories选项卡(如下图)。在下面的两栏添加目录:



现在VS可以找到我们链接GLFW需要的所有文件了。最后需要在Linker(链接器)选项卡里的Input选项卡里添加glfw3.lib这个文件:



要链接一个库我们必须告诉链接器它的文件名。因为我们的库名字是glfw3.lib,我们把它加到Additional Dependencies域里面(手动或者使用选项)。这样GLFW就会被链接进我们的工程。除了GLFW,你也需要链接OpenGL的库,但是这个库可能因为系统的不同而有一些差别。
  • Windows上的OpenGL库
    如果你是Windows平台,opengl32.lib已经随着Microsoft SDK装进了Visual Studio的默认目录,所以Windows上我们只需将opengl32.lib添加进Additional Dependencies。

  • Linux上的OpenGL库
    在Linux下你需要链接libGl.so,所以要添加-lGL到你的链接器设置里。如果找不到这个库你可能需要安装Mesa,NVidia或AMD的开发包,这部分因平台而异就不仔细讲解了。

现在,如果你添加好了GLFW和OpenGL库,你可以用如下方式添加GLFW头文件:

#include <GLFW\glfw3.h>

这个头文件包含了GLFW的设置。

GLEW

因为OpenGL只是一个规范,具体的实现是由驱动开发商针对特定显卡实现的。由于显卡驱动版本众多,大多数函数都无法在编译时确定下来,需要在运行时获取。开发者需要运行时获取函数地址并保存下来供以后使用。Windows下看起来类似这样:

// 定义函数类型
typedef void (*GL_GENBUFFERS) (GLsizei, GLuint*);
// 找到正确的函数并赋值给函数指针
GL_GENBUFFERS glGenBuffers  = (GL_GENBUFFERS)wglGetProcAddress("glGenBuffers");
// 现在函数可以被正常调用了
GLuint buffer;
glGenBuffers(1, &buffer);

幸运的是,有一个针对此目的的库,GLEW,是目前最流行的做这件事的方式。

编译和链接GLEW
GLEW是OpenGL Extension Wrangler Library的缩写,它管理我们上面提到的一系列繁琐的任务。因为GLEW也是一个库,我们同样需要链接进工程。
我们使用GLEW的静态版本glew32s.lib(注意这里的’s’),用如上的方式添加其库文件和头文件,最后在链接器的选项里加上glew32s.lib。注意GLFW3也是编译成了一个静态库。
如果你希望静态链接GLEW,必须在包含GLEW头文件之前定义预编译宏GLEW_STATIC:

#define GLEW_STATIC
#include <GL/glew.h>

如果你希望动态链接,那么就不要定义这个宏。但是使用动态链接的话你需要拷贝一份dll文件到你的应用程序目录。

对于Linux用户建议使用这个命令行-lGLEW -lglfw3 -lGL -lX11 -lpthread -lXrandr -lXi。没有正确链接相应的库会产生undefined reference(未定义的引用)这个错误。

  • 记住确保你的头文件和库文件的目录设置正确,以及链接器里引用的库文件名正确。

额外的资源

Polytonic/Glitter: 一个简单的样板项目,它已经提前配置了所有相关的库;如果你想要很方便地搞到一个LearnOpenGL教程的范例工程,这是一个很好的东西。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,042评论 6 490
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 89,996评论 2 384
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 156,674评论 0 345
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,340评论 1 283
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,404评论 5 384
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,749评论 1 289
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,902评论 3 405
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,662评论 0 266
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,110评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,451评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,577评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,258评论 4 328
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,848评论 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,726评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,952评论 1 264
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,271评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,452评论 2 348

推荐阅读更多精彩内容