使用OpenGL創(chuàng)建窗口的示例詳解
效果展示

窗口創(chuàng)建并啟動(dòng)渲染循環(huán)
/*
因?yàn)镺penGL只是一個(gè)標(biāo)準(zhǔn)/規(guī)范,具體的實(shí)現(xiàn)是由驅(qū)動(dòng)開發(fā)商針對(duì)特定顯卡實(shí)現(xiàn)的。
由于OpenGL驅(qū)動(dòng)版本眾多,它大多數(shù)函數(shù)的位置都無法在編譯時(shí)確定下來,需要在運(yùn)行時(shí)查詢。
所以任務(wù)就落在了開發(fā)者身上,開發(fā)者需要在運(yùn)行時(shí)獲取函數(shù)地址并將其保存在一個(gè)函數(shù)指針中供以后使用。
GLAD是一個(gè)開源的庫,它能解決我們上面提到的獲取函數(shù)地址并將其保存在一個(gè)函數(shù)指針中供以后使用繁瑣的問題
*/
#include <glad/glad.h>
/*
GLFW是一個(gè)專門針對(duì)OpenGL的C語言庫,它提供了一些渲染物體所需的最低限度的接口。它允許用戶創(chuàng)建OpenGL上下文、定義窗口參數(shù)以及處理用戶輸入.
*/
#include <GLFW/glfw3.h>
/*
C++標(biāo)準(zhǔn)庫
*/
#include <iostream>
// 視口修改的函數(shù)
void framebuffer_size_callback(GLFWwindow* window,int width,int height) {
glViewport(0,0,width,height);
}
// 讓所有的輸入代碼保持整潔
void processInput(GLFWwindow *window) {
if (glfwGetKey(window,GLFW_KEY_ESCAPE) == GLFW_PRESS) {
glfwSetWindowShouldClose(window,true);
}
}
int main()
{
// 初始化GLFW
glfwInit();
// 配置GLFW
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);// 設(shè)置主版本號(hào)
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);// 設(shè)置次版本號(hào)
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); // 使用的是核心模式
//glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); // MacOSX系統(tǒng)才需要設(shè)置
// 創(chuàng)建一個(gè)窗口對(duì)象
GLFWwindow* window = glfwCreateWindow(800,600,"LearnOpenGL",NULL,NULL);
if (window == NULL) {
std::cout << "Failed to create GLFW window" << std::endl;
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(window);
// GLAD是用來管理OpenGL的函數(shù)指針的,所以再調(diào)用任何OpenGL的函數(shù)之前我們需要初始化GLAD
// 我們給GLAD傳入了用來加載系統(tǒng)相關(guān)的OpenGL函數(shù)指針地址的函數(shù)。GLFW給我們的是glfwGetProcAddress,它根據(jù)我們編譯的系統(tǒng)定義了正確的函數(shù)
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) {
std::cout << "Failed to initialize GLAD" << std::endl;
return -1;
}
// 告訴OpenGL渲染窗口的尺寸大小,即視口大小
// OpenGL幕后使用glViewport中定義的位置和寬高進(jìn)行2D坐標(biāo)的轉(zhuǎn)換、將OpenGL中的位置坐標(biāo)轉(zhuǎn)換為你的屏幕坐標(biāo)。處理過的OpenGL坐標(biāo)范圍只為-1到1,然后映射到(0,800)和(0,600)
glViewport(0,0,800,600);// 設(shè)置窗口的維度
// 用戶改變窗口的大小的時(shí)候,視口也應(yīng)該被調(diào)整
// 對(duì)窗口注冊(cè)一個(gè)回調(diào)函數(shù)(Callback Function)
glfwSetFramebufferSizeCallback(window,framebuffer_size_callback);
// 還可以將我們的函數(shù)注冊(cè)到其它很多的回調(diào)函數(shù)中。例如我們可以創(chuàng)建一個(gè)回調(diào)函數(shù)來處理手柄輸入變化,處理錯(cuò)誤消息等。我們會(huì)在創(chuàng)建窗口之后,渲染循環(huán)初始化之前注冊(cè)這些回調(diào)函數(shù)
// 添加渲染循環(huán)
while (!glfwWindowShouldClose(window)) {// 該函數(shù)在我們每次循環(huán)的開始前檢查依次GLFW是否被要求推出,如果是的話函數(shù)返回true然后渲染循環(huán)便結(jié)束了,之后我們就可以關(guān)閉應(yīng)用程序了
// 輸入
processInput(window);
// 渲染指令
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);// 設(shè)置清空屏幕所用的顏色(此函數(shù)是一個(gè)狀態(tài)設(shè)置函數(shù))
glClear(GL_COLOR_BUFFER_BIT);// 清除顏色緩沖(是一個(gè)狀態(tài)使用函數(shù))
// 檢查并調(diào)用事件,交換緩沖
glfwSwapBuffers(window);// 函數(shù)會(huì)交換顏色緩沖(它是一個(gè)儲(chǔ)存著GLFW窗口每一個(gè)像素顏色值的大緩沖),它在這一迭代中被用來繪制,并且將會(huì)作為輸出顯示在屏幕上
glfwPollEvents();// 函數(shù)檢查有沒有觸發(fā)什么事件(比如鍵盤輸入、鼠標(biāo)移動(dòng)等)、更新窗口狀態(tài),并調(diào)用對(duì)應(yīng)的回調(diào)函數(shù)(可以通過回調(diào)方法手動(dòng)設(shè)置)。
}
/*雙緩沖(Double Buffer)
應(yīng)用程序使用單緩沖繪圖時(shí)可能會(huì)存在圖像閃爍的問題。 這是因?yàn)樯傻膱D像不是一下子被繪制出來的,而是按照從左到右,由上而下逐像素地繪制而成的。
最終圖像不是在瞬間顯示給用戶,而是通過一步一步生成的,這會(huì)導(dǎo)致渲染的結(jié)果很不真實(shí)。為了規(guī)避這些問題,我們應(yīng)用雙緩沖渲染窗口應(yīng)用程序。
前緩沖保存著最終輸出的圖像,它會(huì)在屏幕上顯示;而所有的的渲染指令都會(huì)在后緩沖上繪制。
當(dāng)所有的渲染指令執(zhí)行完畢后,我們交換(Swap)前緩沖和后緩沖,這樣圖像就立即呈顯出來,之前提到的不真實(shí)感就消除了。
*/
glfwTerminate();
return 0;
}
參考資料
【1】LearnOpenGL
到此這篇關(guān)于使用OpenGL創(chuàng)建窗口的文章就介紹到這了,更多相關(guān)OpenGL創(chuàng)建窗口內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Microsoft Visual C++ 6.0開發(fā)環(huán)境搭建教程
這篇文章主要為大家詳細(xì)介紹了Microsoft Visual C++ 6.0開發(fā)環(huán)境搭建教程,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-04-04
C語言中fchdir()函數(shù)和rewinddir()函數(shù)的使用詳解
這篇文章主要介紹了C語言中fchdir()函數(shù)和rewinddir()函數(shù)的使用詳解,是C語言入門學(xué)習(xí)中的基礎(chǔ)知識(shí),需要的朋友可以參考下2015-09-09
C語言三種函數(shù)調(diào)用約定_cdecl與_stdcall及_fastcall詳細(xì)講解
本篇文章使用的工具是vs2010,內(nèi)容可能涉及到匯編的知識(shí),建議有一些匯編基礎(chǔ)的再來看,不過沒有匯編基礎(chǔ)也沒有關(guān)系,了解一下這三種調(diào)用約定即可2022-10-10
C++實(shí)現(xiàn)線程同步的四種方式總結(jié)
這篇文章主要為大家詳細(xì)介紹了C++實(shí)現(xiàn)線程同步的四種方式,文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)C++有一定的幫助,需要的可以參考一下2022-11-11
利用Qt實(shí)現(xiàn)可擴(kuò)展對(duì)話框的示例代碼
可擴(kuò)展對(duì)話框通常用于用戶對(duì)界面有不同要求的場合。當(dāng)供高級(jí)用戶使用或需要更多信息時(shí),可通過某種方式的切換顯示完整對(duì)話窗體(擴(kuò)展窗體)。本文將用Qt實(shí)現(xiàn)可擴(kuò)展對(duì)話框,需要的可以參考一下2022-06-06
C語言判斷一個(gè)數(shù)是否為素?cái)?shù)方法解析
這篇文章主要介紹了C語言判斷一個(gè)數(shù)是否為素?cái)?shù)方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-07-07
C語言實(shí)現(xiàn)將double/float 轉(zhuǎn)為字符串(帶自定義精度)
這篇文章主要介紹了C語言實(shí)現(xiàn)將double/float 轉(zhuǎn)為字符串(帶自定義精度),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-12-12

