【遊戲開發】基於VS2017的OpenGL開發環境搭建

1、簡介

  最近,馬三買了兩本有關於「計算機圖形學」的書籍,準備在工做之餘鼓搗鼓搗圖形學和OpenGL編程,提高本身的價值(奔着學完能漲一波工資去的)。俗話說得好,「工欲善其事,必先利其器」。想學習圖形學和OpenGL編程必須先把開發環境搭建好,而馬三隻是在上學的時候稍稍作了一些基於Android平臺的OpenGL開發學習,並無搭建過OpenGL開發環境。所以在搭建過程當中頗廢了一番周折,也查閱了很多資料纔算搭建成功,特此記錄一下搭建過程,以備不時之需。html

2、搭建環境

1.VS2017

  這個沒必要多說了,基本作過開發的都會安裝這個「宇宙最強IDE」了。直接去官網下載安裝助手,而後安裝便可。ios

2.GLFW庫

  正常來講開發進行OpenGL開發的話,glut庫是必不可少的,可是馬三在網上一搜啊,發現glut這個庫過期了,如今比較新版的GLFW徹底能夠替代它。關於這些名詞相關的具體介紹,咱們會在稍後仔細介紹一下,咱們仍是先去 GLFW官網 把庫下載下來。編程

  圖1:GLFW官網下載示意圖微信

 3.GLEW庫

  接着咱們還須要下載GLEW庫,衆所周知,OpenGL只是一個標準,不一樣的顯卡公司在不一樣的平臺下對其有不一樣的實現,同時也是發佈一些只支持自家顯卡的拓展函數。經過引入glew庫,咱們徹底能夠不用理睬這些細節,安心寫代碼就行了。框架

  一樣仍是去 GLEW的官網 下載咱們所須要的內容:ide

  圖2:GLEW官網下載示意圖函數

  對於以上的這兩個庫和源代碼,馬三已經下載了寫博客時的最新版本,並打成了壓縮包,方便各位下載。下載請移步工具

4.安裝並測試運行

  解壓咱們下載的兩個庫,並在VS2017裏面新建一個C++空項目。若是建立的是控制檯或者其餘項目的話,vs工具會自動幫你添加一個stdafx.h的預編譯頭,你必須在源文件的開頭寫上#include 「stdafx.h」相關語句,並且以後引入glew,glfw包會有莫名其妙的錯誤。因此建立一個空項目。以下如所示:學習

圖3:解壓後的庫測試

圖4:建立新的空項目

  而後,點擊「解決方案資源管理器」,右鍵點擊源文件,添加新項,建立.cpp源文件,能夠隨便命個名,好比main.cpp:

圖5:新建源文件

  接着,右鍵點擊項目,在彈出的選項中,單擊 「屬性」,點擊「VC++目錄」,而後選擇「包含目錄」選項,單擊下拉菜單中的「編輯」:

圖五、6項目屬性編輯

  接着咱們在新打開的窗口中添加頭文件。分別添加下載的glew和glfw文件夾下的include文件夾(include文件夾下是咱們須要的頭文件),並點擊「肯定」:

圖7:include頭文件

   以後,再繼續添加庫文件到項目中,頭文件一般是函數的聲明,而函數的實現通常都放在了庫中,兩者相輔相成,只有都正確的引入了,才能正常工做。其對應的路徑就是glew和glfw文件夾下的lib文件夾:

  有兩點須要咱們特別注意一下:

  • 當添加glew時,當選到lib文件夾後請繼續選擇,lib->Release->Win32,請選擇Win32後點擊「選擇文件夾」(x64會有莫名其妙的問題)
  • 當添加glfw時,低版本請選擇對應版本,2015以上版本請選擇「lib-vc2015」。馬三用的是2017因此選擇lib-vc2015

圖8:lib庫文件

只包含了庫文件還不行,咱們須要手動指定一下。配置連接器:

圖9:連接器配置

  在裏面手動加入以下選項,行與行之間請按回車,opengl32.lib是系統自帶的。glfw3.lib,glew32s.lib 是咱們下載的庫中的,其實就是以前包含的lib文件夾下的文件名(去掉glew32.lib):

opengl32.lib
glfw3.lib
glew32s.lib

圖10:編輯連接器配置

  通過上面一系列的繁瑣的操做,咱們的OpenGL開發環境基本也算搭建完成了,下面讓咱們在main.cpp中添加一些代碼測試一下,環境是否搭建成功,咱們的程序是否可以跑起來。在main.cpp中加入以下測試代碼:

 1 #include<iostream>
 2 #define GLEW_STATIC
 3 #include <GL/glew.h>
 4 #include <GLFW\glfw3.h>
 5 
 6 using namespace std;
 7 
 8 int main(int argc, char** argv[])
 9 {
10     /*glewExperimental = GL_TRUE;
11     if (glewInit()!=GLEW_OK)
12     {
13     cout << "failed to initalize GLEW" << endl;
14     return -1;
15     }*/
16 
17     glfwInit();//初始化
18     glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);//配置GLFW
19     glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);//配置GLFW
20     glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);//
21     glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);
22 
23     GLFWwindow* window = glfwCreateWindow(800, 600, "LearnOpenGL", nullptr, nullptr);
24     if (window == nullptr)
25     {
26         cout << "Failed to create GLFW window" << endl;
27         glfwTerminate();
28         return -1;
29     }
30     glfwMakeContextCurrent(window);
31     while (!glfwWindowShouldClose(window))
32     {
33         glfwPollEvents();
34         glfwSwapBuffers(window);
35     }
36     glfwTerminate();
37     return 0;
38 
39 
40 }

  而後,點擊調試,若是成功了的話能夠看到相似於下面的這種窗口,實際上是初始化了一個空的OpenGL窗口:

圖11:初始化OpenGL窗口

  可是咱們會發如今vs的錯誤列表窗口中出現了一條警告:「警告 LNK4098 默認庫「MSVCRT」與其餘庫的使用衝突;請使用 /NODEFAULTLIB:library BuildEnv F:\xxxx」

  這個警告也是比較好解決的,打開咱們以前配置連接器的那個頁面,而後選擇忽略特定庫選項,並編輯。在其中加入 "MSVCRT.lib",而後而後點擊肯定,以後就會發現警告消失不見了。若是之後還有其餘的相似的庫衝突,咱們可使用一樣的方法解決。

圖12:解決庫衝突

3、一些名詞概念

  儘管咱們已經成功的搭建了OpenGL開發環境,可是相信此時必定有很多小夥伴和馬三同樣對OpenGL開發中的一些庫和名詞處於矇蔽狀態。馬三也是蒐集了這些名詞的資料和你們一塊兒分享一下。

1.OpenGL是什麼

  OpenGL函數庫相關的API有核心庫(gl),實用庫(glu),輔助庫(aux)、實用工具庫(glut),窗口庫(glx、agl、wgl)和擴展函數庫等。gl是核心,glu是對gl的部分封裝。glx、agl、wgl 是針對不一樣窗口系統的函數。glut是爲跨平臺的OpenGL程序的工具包,比aux功能強大(aux很大程度上已經被glut庫取代。)。擴展函數庫是硬件廠商爲實現硬件更新利用OpenGL的擴展機制開發的函數。

2.gult:OpenGL工具庫(OpenGL Utility Toolkit)

  這部分函數以glut開頭,主要包括窗口操做函數,窗口初始化、窗口大小、窗口位置等函數;回調函數:響應刷新消息、鍵盤消息、鼠標消息、定時器函數等;建立複雜的三維物體;菜單函數;程序運行函數。gult對應的開源實現是freegult,freegult官網請移步

3.glew庫是什麼

  GLUT或者FREEGLUT主要是1.0的基本函數功能;GLEW是使用OPENGL2.0以後的一個工具函數。不一樣的顯卡公司,也會發布一些只有自家顯卡才支持的擴展函數,你要想用這數函數,不得不去尋找最新的glext.h,有了GLEW擴展庫,你就不再用爲找不到函數的接口而煩惱,由於GLEW能自動識別你的平臺所支持的所有OpenGL高級擴展函數。也就是說,只要包含一個glew.h頭文件,你就能使用gl,glu,glext,wgl,glx的所有函數。glew庫提供高版本 gl 函數的支持。若是不嫌麻煩的話,也能夠手寫函數指針,來判斷各個 opengl 高版本函數是否支持,可是 glew 庫 作了大大的簡化,使得 opengl 各個版本的函數像原生函數同樣,能夠隨意調用。

4.glfw

  GLFW無愧於其號稱的lightweight的OpenGL框架,的確是除了跨平臺必要作的事情都沒有作,因此一個頭文件,不多量的API,就完成了任務。GLFW的開發目的是用於替代glut的,從代碼和功能上來看,我想它已經徹底的完成了任務。一個輕量級的,開源的,跨平臺的library。支持OpenGL及OpenGL ES,用來管理窗口,讀取輸入,處理事件等。由於OpenGL沒有窗口管理的功能,因此不少熱心的人寫了工具來支持這些功能,好比早期的glut,如今的freeglut等。

  那麼GLFW有何優點呢?glut太老了,最後一個版本仍是90年代的。freeglut徹底兼容glut,算是glut的代替品,功能齊全,可是bug太多。所以,GLFW應運而生。

綜上所述:

1.glfw是glut的升級和改進

2.glew包含了OpenGL所需的核心

5.glad庫

  目前網上的一些教程還有使用glad庫的,glad與glew有什麼區別呢?簡單說glad是glew的升級版。用哪一個都行。glew比較老,glad比較新。下面簡單介紹一些glad如何使用:

  glad有一個在線服務,直接下下來就能夠用了(編譯好的),將語言(Language)設置爲C/C++,在API選項中,選擇3.3以上的OpenGL版本(3.3是可編程管線版本,但更新的版本也能正常工做)。以後將模式(Profile)設置爲Core,而且保證生成加載器(Generate a loader)的選項是選中的。如今能夠先(暫時)忽略拓展(Extensions)中的內容。都選擇完以後,點擊生成(Generate)按鈕來生成庫文件。

  下載到本地是個壓縮文件,解壓完成後會有這樣的文件夾結構:

test

圖13:glad文件目錄

  包含兩個頭文件目錄(內有頭文件glad.h和khrplatform.h),和一個src文件夾下的glad.c文件。只須要將原來的第五步的 VC++目錄 -> 包含目錄 中的glew的include文件夾改爲glad的include文件夾便可。後面的步驟glad都不須要。

  而後將glad.c文件複製到源文件夾下:

glad.c

圖14:glad複製到源文件夾

  注意glad.c文件這時候或者編譯的時候會出錯,首先看看glad.c的include的路徑是否是對的,有時候包含目錄文件夾路徑不同,你要改爲你本身配置的glad路徑(就是以前VC++目錄配置的路徑)。

  而後須要將咱們的測試代碼換成以下這段:

 1 #include <glad/glad.h>
 2 #include <GLFW/glfw3.h>
 3  
 4 #include <iostream>
 5  
 6 const unsigned int SCR_WIDTH = 800;
 7 const unsigned int SCR_HEIGHT = 600;
 8  
 9 int main()
10 {
11     glfwInit();
12     glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
13     glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
14     glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
15  
16     GLFWwindow* window = glfwCreateWindow(SCR_WIDTH, SCR_HEIGHT, "LearnOpenGL", NULL, NULL);
17     if (window == NULL)
18     {
19         std::cout << "Failed to create GLFW window" << std::endl;
20         glfwTerminate();
21         return -1;
22     }
23     glfwMakeContextCurrent(window);
24  
25     if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
26     {
27         std::cout << "Failed to initialize GLAD" << std::endl;
28         return -1;
29     }    
30  
31     while (!glfwWindowShouldClose(window))
32     {
33  
34         glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
35         glClear(GL_COLOR_BUFFER_BIT);
36  
37         glfwSwapBuffers(window);
38         glfwPollEvents();
39     }
40  
41     glfwTerminate();
42     return 0;
View Code

4、總結

  在本篇博客中,馬三和你們一塊兒從頭開始搭建了一個OpenGL開發環境,而且瞭解了一些OpenGL的概念與名詞。接下來馬三將會一邊學習計算機圖形學和OpenGL,一邊隨時隨地的把想法記錄下來與你們分享~

  參考資料:

 

若是以爲本篇博客對您有幫助,能夠掃碼小小地鼓勵下馬三,馬三會寫出更多的好文章,支持微信和支付寶喲!

       

 

做者:馬三小夥兒
出處:http://www.javashuo.com/article/p-szumdrsi-v.html 請尊重別人的勞動成果,讓分享成爲一種美德,歡迎轉載。另外,文章在表述和代碼方面若有不妥之處,歡迎批評指正。留下你的腳印,歡迎評論!

相關文章
相關標籤/搜索