創(chuàng)建窗口
在我們畫出出色的效果之前,首先要做的就是創(chuàng)建一個OpenGL上下文(Context)和一個用于顯示的窗口胜宇。然而耀怜,這些操作在每個系統(tǒng)上都是不一樣的,OpenGL有目的的抽象(Abstract)這些操作桐愉。這意味著我們不得不自己處理創(chuàng)建窗口财破,定義OpenGL上下文以及處理用戶輸入。
幸運的是仅财,有一些庫已經(jīng)提供了我們所需的功能狈究,其中一部分是特別針對OpenGL的。這些庫節(jié)省了我們書寫平臺相關(guān)代碼的時間,提供給我們一個窗口和上下文用來渲染抖锥。最流行的幾個庫有GLUT亿眠,SDL,SFML和GLFW磅废。在教程里我們將使用GLFW纳像。
GLFW
GLFW是一個專門針對OpenGL的C語言庫,它提供了一些渲染物件所需的最低限度的接口拯勉。它允許用戶創(chuàng)建OpenGL上下文竟趾,定義窗口參數(shù)以及處理用戶輸入。
這一節(jié)和下一節(jié)的內(nèi)容是建立GLFW環(huán)境宫峦,并保證它恰當(dāng)?shù)貏?chuàng)建窗口和OpenGL上下文岔帽。
構(gòu)建GLFW
GLFW已經(jīng)有針對Visual Studio 2012/2013的預(yù)編譯的二進制版本(優(yōu)先選擇32為版本)和相應(yīng)的頭文件,但是為了完整性我們將從編譯源代碼開始导绷,
- 下載源代碼包犀勒。
- 一旦下載完了源碼包,解壓到某處妥曲。我們只關(guān)心里面的這些內(nèi)容:
編譯生成的庫
include文件夾
從源代碼編譯庫可以保證生成的目標(biāo)代碼是針對你的操作系統(tǒng)和CPU的贾费,而一個預(yù)編譯的二進制代碼并不保證總是適合。提供源代碼的一個問題是不是每個人都用相同的IDE來編譯檐盟,因而提供的工程文件可能和一些人的IDE不兼容褂萧。所以人們只能從.cpp和.h文件來自己建立工程,這是一項笨重的工作葵萎。因此誕生了一個叫做CMake的工具导犹。
CMAKE
CMake是一個工程文件生成工具,可以使用預(yù)定義好的CMake腳本陌宿,根據(jù)用戶的選擇生成不同IDE的工程文件锡足。這允許我們從GLFW源碼里創(chuàng)建一個Visual Studio 2012(或其他版本)工程文件。
CMake需要一個源代碼目錄和一個存放編譯結(jié)果的目標(biāo)文件目錄壳坪。源代碼目錄我們選擇GLFW的源代碼的根目錄舶得,然后我們新建一個build文件夾來作為目標(biāo)目錄。
之后爽蝴,點擊Configure(設(shè)置)按鈕沐批,我們選擇生成的目標(biāo)平臺為Visual Studio 11(因為Visual Studio 2012的內(nèi)部版本號是11.0)。CMake會顯示可選的編譯選項蝎亚,這里我們使用默認(rèn)設(shè)置九孩,再次點擊Configure(設(shè)置)按鈕,保存這些設(shè)置发框。保存之后躺彬,我們可以點擊Generate(生成)按鈕,生成的工程文件就會出現(xiàn)在你的build文件夾中。
編譯
在build文件夾里可以找到GLFW.sln文件宪拥,用Visual Studio 2012打開仿野。因為CMake已經(jīng)配置好了項目所以我們直接點擊Build Solution(構(gòu)建解決方案)然后編譯的結(jié)果glfw3.lib就會出現(xiàn)在src/Debug文件夾內(nèi)。(注意我們現(xiàn)在使用的glfw的版本號為3.1)
生成庫之后她君,我們需要讓IDE知道庫和頭文件的位置脚作。有兩種方法:
找到IDE或者編譯器的/lib和/include文件夾,之后添加GLFW的include目錄到/include里去缔刹,相似的將glfw3.lib添加到/lib里去球涛。這不是推薦的方式,因為很難去追蹤library/include文件夾校镐,而且重新安裝IDE/Compiler可能會導(dǎo)致這些文件丟失亿扁。
推薦的方式是建立一個新的目錄包含所有的第三方庫文件和頭文件,并且在你的IDE/Compiler中指定這些文件夾灭翔。我個人使用一個單獨的文件夾包含Libs和Include文件夾魏烫,在這里存放OpenGL工程用到的所有第三方庫和頭文件辣苏。這樣我的所有第三方庫都在同一個路徑(并且應(yīng)該在你的多臺電腦間共享)肝箱,然而要求是每次新建一個工程我們都需要告訴IDE/編譯器在哪能找到這些文件
完成上面步驟后,我們就可以使用GLFW創(chuàng)建我們的第一個OpenGL工程了稀蟋!
我們的第一個工程
讓我們打開Visual Studio煌张,創(chuàng)建一個新Viesual C++的工程。
鏈接(Linking)
為了使我們的程序使用GLFW退客,我們需要把GLFW庫鏈接(Link)進工程骏融。于是我們需要在鏈接器的設(shè)置里寫上glfw3.lib。但是我們的工程還不知道在哪尋找這個文件萌狂,于是我們首先需要將我們放第三方庫的目錄添加進設(shè)置档玻。
為了添加這些目錄,我們首先進入Project Properties(工程屬性)(在解決方案窗口里右鍵項目)茫藏,然后選擇VC++ Directories選項卡(如下圖)误趴。在下面的兩欄添加目錄:
現(xiàn)在VS可以找到我們鏈接GLFW需要的所有文件了。最后需要在Linker(鏈接器)選項卡里的Input選項卡里添加glfw3.lib這個文件:
要鏈接一個庫我們必須告訴鏈接器它的文件名务傲。因為我們的庫名字是glfw3.lib凉当,我們把它加到Additional Dependencies域里面(手動或者使用選項)。這樣GLFW就會被鏈接進我們的工程售葡。除了GLFW看杭,你也需要鏈接OpenGL的庫,但是這個庫可能因為系統(tǒng)的不同而有一些差別挟伙。
Windows上的OpenGL庫
如果你是Windows平臺楼雹,opengl32.lib已經(jīng)隨著Microsoft SDK裝進了Visual Studio的默認(rèn)目錄,所以Windows上我們只需將opengl32.lib添加進Additional Dependencies。Linux上的OpenGL庫
在Linux下你需要鏈接libGl.so贮缅,所以要添加-lGL到你的鏈接器設(shè)置里瓜贾。如果找不到這個庫你可能需要安裝Mesa,NVidia或AMD的開發(fā)包携悯,這部分因平臺而異就不仔細(xì)講解了祭芦。
現(xiàn)在,如果你添加好了GLFW和OpenGL庫憔鬼,你可以用如下方式添加GLFW頭文件:
#include <GLFW\glfw3.h>
這個頭文件包含了GLFW的設(shè)置龟劲。
GLEW
因為OpenGL只是一個規(guī)范,具體的實現(xiàn)是由驅(qū)動開發(fā)商針對特定顯卡實現(xiàn)的轴或。由于顯卡驅(qū)動版本眾多昌跌,大多數(shù)函數(shù)都無法在編譯時確定下來,需要在運行時獲取照雁。開發(fā)者需要運行時獲取函數(shù)地址并保存下來供以后使用。Windows下看起來類似這樣:
// 定義函數(shù)類型
typedef void (*GL_GENBUFFERS) (GLsizei, GLuint*);
// 找到正確的函數(shù)并賦值給函數(shù)指針
GL_GENBUFFERS glGenBuffers = (GL_GENBUFFERS)wglGetProcAddress("glGenBuffers");
// 現(xiàn)在函數(shù)可以被正常調(diào)用了
GLuint buffer;
glGenBuffers(1, &buffer);
幸運的是萍诱,有一個針對此目的的庫,GLEW,是目前最流行的做這件事的方式。
編譯和鏈接GLEW
GLEW是OpenGL Extension Wrangler Library的縮寫退盯,它管理我們上面提到的一系列繁瑣的任務(wù)。因為GLEW也是一個庫,我們同樣需要鏈接進工程漓骚。
我們使用GLEW的靜態(tài)版本glew32s.lib(注意這里的’s’)噩斟,用如上的方式添加其庫文件和頭文件齐鲤,最后在鏈接器的選項里加上glew32s.lib牡肉。注意GLFW3也是編譯成了一個靜態(tài)庫炭庙。
如果你希望靜態(tài)鏈接GLEW免绿,必須在包含GLEW頭文件之前定義預(yù)編譯宏GLEW_STATIC:
#define GLEW_STATIC
#include <GL/glew.h>
如果你希望動態(tài)鏈接迹卢,那么就不要定義這個宏。但是使用動態(tài)鏈接的話你需要拷貝一份dll文件到你的應(yīng)用程序目錄殃饿。
對于Linux用戶建議使用這個命令行-lGLEW -lglfw3 -lGL -lX11 -lpthread -lXrandr -lXi帖池。沒有正確鏈接相應(yīng)的庫會產(chǎn)生undefined reference(未定義的引用)這個錯誤睡汹。
- 記住確保你的頭文件和庫文件的目錄設(shè)置正確,以及鏈接器里引用的庫文件名正確寂殉。
額外的資源
Polytonic/Glitter: 一個簡單的樣板項目囚巴,它已經(jīng)提前配置了所有相關(guān)的庫;如果你想要很方便地搞到一個LearnOpenGL教程的范例工程友扰,這是一個很好的東西文兢。