最近在學(xué)習(xí)OpenGL豁延,搭建環(huán)境的時(shí)候發(fā)現(xiàn)網(wǎng)絡(luò)上面的教程都太籠統(tǒng)了昙篙,而且跟著上面搭建最后各種報(bào)錯(cuò),這里我會(huì)一步一步詳細(xì)的教大家如何搭建OpenGL的開發(fā)環(huán)境诱咏。注意如果我教程里提供的鏈接打不開苔可,請找一些小辦法
準(zhǔn)備
需要的軟件
- VS 2017(隨便什么版本都行,我這里用的是2017)
- CMake
開發(fā)系統(tǒng)
- Windows
配置GLFW
在我們畫出出色的效果之前袋狞,首先要做的就是創(chuàng)建一個(gè)OpenGL上下文(Context)和一個(gè)用于顯示的窗口焚辅。然而,這些操作在每個(gè)系統(tǒng)上都是不一樣的硕并,OpenGL有目的地從這些操作抽象(Abstract)出去法焰。這意味著我們不得不自己處理創(chuàng)建窗口,定義OpenGL上下文以及處理用戶輸入倔毙。
幸運(yùn)的是埃仪,有一些庫已經(jīng)提供了我們所需的功能,其中一部分是特別針對OpenGL的陕赃。這些庫節(jié)省了我們書寫操作系統(tǒng)相關(guān)代碼的時(shí)間卵蛉,提供給我們一個(gè)窗口和上下文用來渲染。最流行的幾個(gè)庫有GLUT么库,SDL傻丝,SFML和GLFW。在教程里我們將使用GLFW诉儒。
第一步
我們?nèi)LFW的官網(wǎng)上下載源碼包
我們把下載好的源碼包解壓
第二步
這里我們需要用到CMake這個(gè)軟件把源碼編譯葡缰,這個(gè)軟件直接去百度下載就OK了,下載安裝好了打開軟件忱反,在where is the source code
選擇我們解壓好的源碼存放的文件夾泛释,where is the build the binaries
里面隨便選擇一個(gè)文件夾存放編譯好的文件。然后點(diǎn)擊configure
然后選擇你對應(yīng)你所使用的VS版本温算,然后再點(diǎn)擊Generate
怜校,等待編譯完成就行了,那些飄紅的東西完全可以無視了注竿。
第三步
完成后我們可以在文件夾里看見編譯生成的文件茄茁,這時(shí)候我們要用我們的VS來打開里面的GLFW.sln
魂贬,來打開這個(gè)項(xiàng)目,然后直接點(diǎn)擊Build Solution(生成解決方案)按鈕裙顽,然后編譯的庫glfw3.lib(注意我們用的是第3版)就會(huì)出現(xiàn)在src/Debug文件夾內(nèi)付燥。然后我們創(chuàng)建一個(gè)文件夾命名為OpenGL,再在里面創(chuàng)建一個(gè)名字叫l(wèi)ib的文件夾锦庸,把我們剛才生成的glfw32.lib文件放進(jìn)去机蔗,再去我們一開始解壓GLFW的文件夾,把里面的include文件夾也復(fù)制到OpenGL文件里甘萧。
創(chuàng)建工程
現(xiàn)在我們就可以在我們的VS里面新建項(xiàng)目了萝嘁,我們新建一個(gè)空白的vc++的項(xiàng)目,新建完畢后扬卷,我們右擊我們的項(xiàng)目選擇屬性:
然后在VC++目錄這個(gè)選項(xiàng)里牙言,在包含目錄里添加我們創(chuàng)建好的OpenGL/include文件夾的位置,在庫目錄里添加OpenGL/ilb文件夾的位置
然后我們再在鏈接器選項(xiàng)里選擇輸入后編輯附加依賴項(xiàng)
在里面輸入
opengl32.lib
glfw3.lib
然后點(diǎn)確認(rèn)怪得,一定要記得所有選項(xiàng)都要點(diǎn)確定咱枉,不然都白忙活了。
GLAD
到這里還沒有結(jié)束徒恋,我們?nèi)匀贿€有一件事要做蚕断。因?yàn)镺penGL只是一個(gè)標(biāo)準(zhǔn)/規(guī)范,具體的實(shí)現(xiàn)是由驅(qū)動(dòng)開發(fā)商針對特定顯卡實(shí)現(xiàn)的入挣。由于OpenGL驅(qū)動(dòng)版本眾多亿乳,它大多數(shù)函數(shù)的位置都無法在編譯時(shí)確定下來,需要在運(yùn)行時(shí)查詢径筏。所以任務(wù)就落在了開發(fā)者身上葛假,開發(fā)者需要在運(yùn)行時(shí)獲取函數(shù)地址并將其保存在一個(gè)函數(shù)指針中供以后使用。你可以看到代碼非常復(fù)雜滋恬,而且很繁瑣聊训,我們需要對每個(gè)可能使用的函數(shù)都要重復(fù)這個(gè)過程。幸運(yùn)的是恢氯,有些庫能簡化此過程带斑,其中GLAD是目前最新,也是最流行的庫勋拟。
首先我們要去[官網(wǎng)]下載遏暴,這里我們隨便選一個(gè)GL的版本然后點(diǎn)擊GENERATE,然后下載生成的壓縮包指黎,然后解壓。
解壓后把里面的include的文件夾同樣復(fù)制到我們前面建立的OpenGL文件夾里州丹,把src文件夾里的glad.c文件放到我們項(xiàng)目的源文件里
開始OpenGL
到這里我們的環(huán)境就搭建好了醋安,我們可以建個(gè)窗體來測試一下杂彭,首先我們先新建一個(gè)cpp文件
在里面寫入代碼
#include <glad/glad.h>
#include <GLFW/glfw3.h>
#include <iostream>
void framebuffer_size_callback(GLFWwindow* window, int width, int height);
void processInput(GLFWwindow *window);
// settings
const unsigned int SCR_WIDTH = 800;
const unsigned int SCR_HEIGHT = 600;
int main()
{
// glfw: initialize and configure
// ------------------------------
glfwInit();
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
#ifdef __APPLE__
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); // uncomment this statement to fix compilation on OS X
#endif
// glfw window creation
// --------------------
GLFWwindow* window = glfwCreateWindow(SCR_WIDTH, SCR_HEIGHT, "LearnOpenGL", NULL, NULL);
if (window == NULL)
{
std::cout << "Failed to create GLFW window" << std::endl;
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(window);
glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
// glad: load all OpenGL function pointers
// ---------------------------------------
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
{
std::cout << "Failed to initialize GLAD" << std::endl;
return -1;
}
// render loop
// -----------
while (!glfwWindowShouldClose(window))
{
// input
// -----
processInput(window);
// glfw: swap buffers and poll IO events (keys pressed/released, mouse moved etc.)
// -------------------------------------------------------------------------------
glfwSwapBuffers(window);
glfwPollEvents();
}
// glfw: terminate, clearing all previously allocated GLFW resources.
// ------------------------------------------------------------------
glfwTerminate();
return 0;
}
// process all input: query GLFW whether relevant keys are pressed/released this frame and react accordingly
// ---------------------------------------------------------------------------------------------------------
void processInput(GLFWwindow *window)
{
if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
glfwSetWindowShouldClose(window, true);
}
// glfw: whenever the window size changed (by OS or user resize) this callback function executes
// ---------------------------------------------------------------------------------------------
void framebuffer_size_callback(GLFWwindow* window, int width, int height)
{
// make sure the viewport matches the new window dimensions; note that width and
// height will be significantly larger than specified on retina displays.
glViewport(0, 0, width, height);
}
然后點(diǎn)擊本地Windows調(diào)試器,就可以看到我們創(chuàng)建的窗體了吓揪,也就代表著我們OpenGL環(huán)境搭建大成功G椎 !柠辞!