opengl代码实例_OpenGL-打开一个窗口
寫(xiě)在前面
讓我們?cè)囋嚹懿荒茏孏LFW正常工作。首先,新建一個(gè).cpp文件,然后把下面的代碼粘貼到該文件的最前面。
#include <iostream> #define GLEW_STATIC #include <GL/glew.h> #include <GLFW/glfw3.h>請(qǐng)確認(rèn)是在包含GLFW的頭文件之前包含了GLAD的頭文件。GLAD的頭文件包含了正確的OpenGL頭文件(例如GL/gl.h),所以需要在其它依賴于OpenGL的頭文件之前包含GLAD。
接下來(lái)我們創(chuàng)建main函數(shù),在這個(gè)函數(shù)中我們將會(huì)實(shí)例化GLFW窗口:
int main() {glfwInit();glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);//glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);return 0; }首先,我們?cè)趍ain函數(shù)中調(diào)用glfwInit函數(shù)來(lái)初始化GLFW,然后我們可以使用glfwWindowHint函數(shù)來(lái)配置GLFW。glfwWindowHint函數(shù)的第一個(gè)參數(shù)代表選項(xiàng)的名稱,我們可以從很多以GLFW_開(kāi)頭的枚舉值中選擇;第二個(gè)參數(shù)接受一個(gè)整型,用來(lái)設(shè)置這個(gè)選項(xiàng)的值。
如果你現(xiàn)在編譯你的cpp文件會(huì)得到大量的 undefined reference (未定義的引用)錯(cuò)誤,也就是說(shuō)你并未順利地鏈接GLFW庫(kù)。
接下來(lái)我們創(chuàng)建一個(gè)窗口對(duì)象,這個(gè)窗口對(duì)象存放了所有和窗口相關(guān)的數(shù)據(jù),而且會(huì)被GLFW的其他函數(shù)頻繁地用到。
//OPengGL GLFW Window GLFWwindow* window = glfwCreateWindow(800, 600, "LearnOpenGL", NULL, NULL); if (window == NULL) {printf("Failed to create GLFW window");glfwTerminate();return -1; } glfwMakeContextCurrent(window);glfwCreateWindow函數(shù)需要窗口的寬和高作為它的前兩個(gè)參數(shù)。第三個(gè)參數(shù)表示這個(gè)窗口的名稱(標(biāo)題),這里我們使用"LearnOpenGL",當(dāng)然你也可以使用你喜歡的名稱。最后兩個(gè)參數(shù)我們暫時(shí)忽略。這個(gè)函數(shù)將會(huì)返回一個(gè)GLFWwindow對(duì)象,我們會(huì)在其它的GLFW操作中使用到。創(chuàng)建完窗口我們就可以通知GLFW將我們窗口的上下文設(shè)置為當(dāng)前線程的主上下文了。
GLAD
GLAD是用來(lái)管理OpenGL的函數(shù)指針的,所以在調(diào)用任何OpenGL的函數(shù)之前我們需要初始化GLAD。//Init GLEW glewExperimental = true; if (glewInit() != GLEW_OK) {printf("Failed to Init GLFW");glfwTerminate();return -1; }我們給GLAD傳入了用來(lái)加載系統(tǒng)相關(guān)的OpenGL函數(shù)指針地址的函數(shù)。GLFW給我們的是glfwGetProcAddress,它根據(jù)我們編譯的系統(tǒng)定義了正確的函數(shù)。
視口
在我們開(kāi)始渲染之前還有一件重要的事情要做,我們必須告訴OpenGL渲染窗口的尺寸大小,即視口(Viewport),這樣OpenGL才只能知道怎樣根據(jù)窗口大小顯示數(shù)據(jù)和坐標(biāo)。我們可以通過(guò)調(diào)用glViewport函數(shù)來(lái)設(shè)置窗口的維度(Dimension):
glViewport(0, 0, 800, 600);glViewport函數(shù)前兩個(gè)參數(shù)控制窗口左下角的位置。第三個(gè)和第四個(gè)參數(shù)控制渲染窗口的寬度和高度(像素)。
準(zhǔn)備好你的引擎
我們可不希望只繪制一個(gè)圖像之后我們的應(yīng)用程序就立即退出并關(guān)閉窗口。我們希望程序在我們主動(dòng)關(guān)閉它之前不斷繪制圖像并能夠接受用戶輸入。因此,我們需要在程序中添加一個(gè)while循環(huán),我們可以把它稱之為渲染循環(huán)(Render Loop),它能在我們讓GLFW退出前一直保持運(yùn)行。下面幾行的代碼就實(shí)現(xiàn)了一個(gè)簡(jiǎn)單的渲染循環(huán):
while(!glfwWindowShouldClose(window)) {glfwSwapBuffers(window);glfwPollEvents(); }glfwWindowShouldClose函數(shù)在我們每次循環(huán)的開(kāi)始前檢查一次GLFW是否被要求退出,如果是的話該函數(shù)返回true然后渲染循環(huán)便結(jié)束了,之后為我們就可以關(guān)閉應(yīng)用程序了。
glfwPollEvents函數(shù)檢查有沒(méi)有觸發(fā)什么事件(比如鍵盤(pán)輸入、鼠標(biāo)移動(dòng)等)、更新窗口狀態(tài),并調(diào)用對(duì)應(yīng)的回調(diào)函數(shù)(可以通過(guò)回調(diào)方法手動(dòng)設(shè)置)。
glfwSwapBuffers函數(shù)會(huì)交換顏色緩沖(它是一個(gè)儲(chǔ)存著GLFW窗口每一個(gè)像素顏色值的大緩沖),它在這一迭代中被用來(lái)繪制,并且將會(huì)作為輸出顯示在屏幕上。
雙緩沖(Double Buffer)應(yīng)用程序使用單緩沖繪圖時(shí)可能會(huì)存在圖像閃爍的問(wèn)題。 這是因?yàn)樯傻膱D像不是一下子被繪制出來(lái)的,而是按照從左到右,由上而下逐像素地繪制而成的。最終圖像不是在瞬間顯示給用戶,而是通過(guò)一步一步生成的,這會(huì)導(dǎo)致渲染的結(jié)果很不真實(shí)。為了規(guī)避這些問(wèn)題,我們應(yīng)用雙緩沖渲染窗口應(yīng)用程序。前緩沖保存著最終輸出的圖像,它會(huì)在屏幕上顯示;而所有的的渲染指令都會(huì)在后緩沖上繪制。當(dāng)所有的渲染指令執(zhí)行完畢后,我們交換(Swap)前緩沖和后緩沖,這樣圖像就立即呈顯出來(lái),之前提到的不真實(shí)感就消除了。
寫(xiě)在最后
當(dāng)渲染循環(huán)結(jié)束后我們需要正確釋放/刪除之前的分配的所有資源。我們可以在main函數(shù)的最后調(diào)用glfwTerminate函數(shù)來(lái)完成。
glfwTerminate(); return 0;這樣便能清理所有的資源并正確地退出應(yīng)用程序。現(xiàn)在你可以嘗試編譯并運(yùn)行你的應(yīng)用程序了,如果沒(méi)做錯(cuò)的話,你將會(huì)看到如下的輸出:
如果你看見(jiàn)了一個(gè)非常無(wú)聊的黑色窗口,那么就對(duì)了!如果你沒(méi)得到正確的結(jié)果,或者你不知道怎么把所有東西放到一起,請(qǐng)到這里參考源代碼。
輸入
我們同樣也希望能夠在GLFW中實(shí)現(xiàn)一些輸入控制,這可以通過(guò)使用GLFW的幾個(gè)輸入函數(shù)來(lái)完成。我們將會(huì)使用GLFW的glfwGetKey函數(shù),它需要一個(gè)窗口以及一個(gè)按鍵作為輸入。這個(gè)函數(shù)將會(huì)返回這個(gè)按鍵是否正在被按下。我們將創(chuàng)建一個(gè)processInput函數(shù)來(lái)讓所有的輸入代碼保持整潔。
void processInput(GLFWwindow *window) {if(glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)glfwSetWindowShouldClose(window, true); }這里我們檢查用戶是否按下了返回鍵(Esc)(如果沒(méi)有按下,glfwGetKey將會(huì)返回GLFW_RELEASE。如果用戶的確按下了返回鍵,我們將通過(guò)glfwSetwindowShouldClose使用把WindowShouldClose屬性設(shè)置為 true 的方法關(guān)閉GLFW。下一次while循環(huán)的條件檢測(cè)將會(huì)失敗,程序?qū)?huì)關(guān)閉。
我們接下來(lái)在渲染循環(huán)的每一個(gè)迭代中調(diào)用processInput:
while (!glfwWindowShouldClose(window)) {processInput(window);glfwSwapBuffers(window);glfwPollEvents(); }這就給我們一個(gè)非常簡(jiǎn)單的方式來(lái)檢測(cè)特定的鍵是否被按下,并在每一幀做出處理。
渲染
我們要把所有的渲染(Rendering)操作放到渲染循環(huán)中,因?yàn)槲覀兿胱屵@些渲染指令在每次渲染循環(huán)迭代的時(shí)候都能被執(zhí)行。代碼將會(huì)是這樣的:
// 渲染循環(huán) while(!glfwWindowShouldClose(window)) {// 輸入processInput(window);// 渲染指令...// 檢查并調(diào)用事件,交換緩沖glfwPollEvents();glfwSwapBuffers(window); }為了測(cè)試一切都正常工作,我們使用一個(gè)自定義的顏色清空屏幕。在每個(gè)新的渲染迭代開(kāi)始的時(shí)候我們總是希望清屏,否則我們?nèi)阅芸匆?jiàn)上一次迭代的渲染結(jié)果(這可能是你想要的效果,但通常這不是)。我們可以通過(guò)調(diào)用glClear函數(shù)來(lái)清空屏幕的顏色緩沖,它接受一個(gè)緩沖位(Buffer Bit)來(lái)指定要清空的緩沖,可能的緩沖位有GL_COLOR_BUFFER_BIT,GL_DEPTH_BUFFER_BIT和GL_STENCIL_BUFFER_BIT。由于現(xiàn)在我們只關(guān)心顏色值,所以我們只清空顏色緩沖。
glClearColor(0.2f, 0.3f, 0.3f, 1.0f); glClear(GL_COLOR_BUFFER_BIT);注意,除了glClear之外,我們還調(diào)用了glClearColor來(lái)設(shè)置清空屏幕所用的顏色。當(dāng)調(diào)用glClear函數(shù),清除顏色緩沖之后,整個(gè)顏色緩沖都會(huì)被填充為glClearColor里所設(shè)置的顏色。在這里,我們將屏幕設(shè)置為了類似黑板的深藍(lán)綠色。
總結(jié)
以上是生活随笔為你收集整理的opengl代码实例_OpenGL-打开一个窗口的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 1 access中iif函数中的_Jav
- 下一篇: latex换页_备忘 | Latex 双