- 窗口初始化
glfwInit();
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); \\主版本號
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); \\次版本號
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); \\核心渲染模式
- 創建窗口對象
// glfwCreateWindow函數需要窗口的寬和高作爲它的前兩個參數。第三個參數表示這個窗口的名稱,後兩個參數可以暫時忽略
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加載函數指針
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
{
std::cout << "Failed to initialize GLAD" << std::endl;
return -1;
}
- 告訴OpenGL渲染窗口的大小,即視口ViewPort
// glViewport函數前兩個參數控制窗口左下角的位置。第三個和第四個參數控制渲染窗口的寬度和高度(像素)。
glViewport(0, 0, 800, 600);
- 釋放資源
glfwTerminate();
return 0;
- 其他一些使創建窗口更合理的函數
- 我們希望用戶更改窗口大小適合視口也應該被調整,故對窗口註冊一個回調函數
void framebuffer_size_callback(GLFWwindow* window, int width, int height)
{
glViewport(0, 0, width, height);
}
// 在main註冊回調函數,使得每次調整窗口大小都調用這個函數
glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
- 我們不希望繪製一個圖像後就立即關閉窗口,而是隻有當我們主動關閉它之前不斷繪製並能接受用戶輸入,因而我們定義了一個渲染循環**(Render Loop),
- ** 這裏注意glfwSwapBuffers(window)函數,即交換顏色緩衝函數:它是一個儲存着GLFW窗口每一個像素顏色值的大緩衝), 如果渲染是一部分一部分渲染的,那麼圖像就不是瞬間顯示給用戶,就顯得很不真實,採用雙緩衝機制,前緩衝保存着最終輸出的圖像,而所有的的渲染指令都會在後緩衝上繪製。當所有的渲染指令執行完畢後,我們交換(Swap)前緩衝和後緩衝,這樣圖像就立即呈顯出來
while(!glfwWindowShouldClose(window))
{
glfwSwapBuffers(window);
glfwPollEvents() // 函數檢查有沒有觸發什麼事件(比如鍵盤輸入、鼠標移動等)、更新窗口狀態,並調用對應的回調函數;
}
- 我們同樣希望在GLFW實現輸入控制,利用Esc退出
void processInput(GLFWwindow *window)
{
if(glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
glfwSetWindowShouldClose(window, true);
}
因此,得到最終的渲染循環爲:
// 渲染循環
while(!glfwWindowShouldClose(window))
{
// 輸入
processInput(window);
// 渲染指令, 我們自定義了一個有顏色屏幕
glClearColor(0.2f, 0.3f, 0.3f, 1.0f); // RGBAlpha(透明度)
glClear(GL_COLOR_BUFFER_BIT); //清空上一次渲染顏色緩衝,並使得整個顏色緩衝都會被填充爲glClearColor裏所設置的顏色
// 檢查並調用事件,交換緩衝
glfwPollEvents();
glfwSwapBuffers(window);
}