LearnOpenGL-第一個視窗
阿新 • • 發佈:2018-12-15
一 建立專案
1.新建專案
你可以建立一個cpp來執行一下main
2.引入OpenGL相關庫
3.設定連結器
4.工程引入glad.c
二 開始寫程式碼
參考例子
// 因為OpenGL只是一個標準/規範,具體的實現是由驅動開發商針對特定顯示卡實現的。
// 由於OpenGL驅動版本眾多,它大多數函式的位置都無法在編譯時確定下來,需要在執行時查詢。
// glad提供了上述問題的解決方案。
#include <glad/glad.h>
// GLFW是一個專門針對OpenGL的C語言庫,它提供了一些渲染物體所需的最低限度的介面。
// 它允許使用者建立OpenGL上下文,定義視窗引數以及處理使用者輸入,這正是我們需要的。
// http://www.glfw.org/download.html
#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
// 初始化GLFW
// ------------------------------
glfwInit();
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); // 主版本號。
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); // 次版本號。指定建立的上下文必須相容的客戶端API版本 我們這裡設定為3.3
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); // GLFW_OPENGL_PROFILE指定要為其建立上下文的OpenGL配置檔案。這裡設定為核心渲染模式
#ifdef __APPLE__
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); // 如果使用的是Mac OS X系統,你還需要加這行程式碼到你的初始化程式碼中這些配置才能起作用
#endif
// glfw window creation
// 建立一個視窗物件
// glfwCreateWindow函式需要視窗的寬和高作為它的前兩個引數。
// 第三個引數表示這個視窗的名稱(標題),這裡我們使用"LearnOpenGL",當然你也可以使用你喜歡的名稱。
// 最後兩個引數我們暫時忽略。這個函式將會返回一個GLFWwindow物件,我們會在其它的GLFW操作中使用到。
// --------------------
GLFWwindow* window = glfwCreateWindow(SCR_WIDTH, SCR_HEIGHT, "LearnOpenGL_WUYANHUI", NULL, NULL);
if (window == NULL)
{
std::cout << "Failed to create GLFW window" << std::endl;
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(window);// 建立完視窗我們就可以通知GLFW將我們視窗的上下文設定為當前執行緒的主上下文了。
glfwSetFramebufferSizeCallback(window, framebuffer_size_callback); // 對視窗註冊一個回撥函式(Callback Function),它會在每次視窗大小被調整的時候被呼叫。
// glad: load all OpenGL function pointers
// GLAD是用來管理OpenGL的函式指標的,所以在呼叫任何OpenGL的函式之前我們需要初始化GLAD。
// ---------------------------------------
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
{
std::cout << "Failed to initialize GLAD" << std::endl;
return -1;
}
// render loop // 準備好你的引擎
// -----------
while (!glfwWindowShouldClose(window))
{
// 輸入
// -----
processInput(window);
// 渲染指令
// ------
// 我們可以通過呼叫glClear函式來清空螢幕的顏色緩衝,它接受一個緩衝位(Buffer Bit)來指定要清空的緩衝。
// 除了glClear之外,我們還呼叫了glClearColor來設定清空螢幕所用的顏色。
// 當呼叫glClear函式,清除顏色緩衝之後,整個顏色緩衝都會被填充為glClearColor裡所設定的顏色。
glClearColor(0.2f, 0.3f, 0.3f, 1.0f); // 深藍色
glClear(GL_COLOR_BUFFER_BIT);
// 檢查並呼叫事件,交換緩衝
// -------------------------------------------------------------------------------
glfwSwapBuffers(window); // glfwPollEvents函式檢查有沒有觸發什麼事件(比如鍵盤輸入、滑鼠移動等)、更新視窗狀態,並呼叫對應的回撥函式(可以通過回撥方法手動設定)。
glfwPollEvents(); // glfwSwapBuffers函式會交換顏色緩衝(它是一個儲存著GLFW視窗每一個畫素顏色值的大緩衝),它在這一迭代中被用來繪製,並且將會作為輸出顯示在螢幕上。
}
// 雙緩衝(Double Buffer)
// 應用程式使用單緩衝繪圖時可能會存在影象閃爍的問題。
// 這是因為生成的影象不是一下子被繪製出來的,而是按照從左到右,由上而下逐畫素地繪製而成的。
// 最終影象不是在瞬間顯示給使用者,而是通過一步一步生成的,這會導致渲染的結果很不真實。
// 為了規避這些問題,我們應用雙緩衝渲染視窗應用程式。
// 前緩衝儲存著最終輸出的影象,它會在螢幕上顯示;而所有的的渲染指令都會在後緩衝上繪製。
// 當所有的渲染指令執行完畢後,我們交換(Swap)前緩衝和後緩衝,這樣影象就立即呈顯出來,之前提到的不真實感就消除了。
// 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) // glfwWindowShouldClose函式在我們每次迴圈的開始前檢查一次GLFW是否被要求退出,如果是的話該函式返回true然後渲染迴圈便結束了,之後為我們就可以關閉應用程式了。
glfwSetWindowShouldClose(window, true);
}
// glfw: whenever the window size changed (by OS or user resize) this callback function executes
// 當用戶改變視窗的大小的時候,視口也應該被調整。
// 當視窗被第一次顯示的時候framebuffer_size_callback也會被呼叫。
// ---------------------------------------------------------------------------------------------
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. // 對於視網膜(Retina)顯示屏,width和height都會明顯比原輸入值更高一點。
glViewport(0, 0, width, height); // 位置\寬高
}