1. 程式人生 > 實用技巧 >openGL 學習筆記 (一) 瞭解 OpenGL,建立第一個OpenGL視窗

openGL 學習筆記 (一) 瞭解 OpenGL,建立第一個OpenGL視窗

// 序章
最開始我以為OpenGL是一系列的API,他給出了一系列對計算機影象的操作介面。
但其實OpenGL其實並不是一個API,他是由khronos組織制定並維護的規範。

早期的OpenGL使用立即渲染模式(固定渲染管線),後期使用核心渲染模式。 -- TODO 以後要深入瞭解兩種渲染方式的區別。

OpenGL自身其實是一個巨大的狀態機:使用一系列變數來改變OpenGL的狀態。從而改變OpenGl的繪製方式。我們使用OpenGL狀態設定函式去改變OpenGL的上下文(既狀態);使用狀態使用函式,根據當前的OpenGl狀態執行一些操作。

OpenGL核心是用C寫的,因為C的一些語言結構不易被翻譯到其他高階語言,所以在開發時引入了一些抽象層如物件(Object)。

在OpenGL中物件是被作用於一些狀態的集合,他代表GL狀態的一個子集,其實就可以把OpenGL的狀態看做是一個巨大的結構體:

1     struct OpenGl_Context {
2         ...
3         float   stat_1
4         int     stat_2
5         char[]  stat_3
6         object* object_Window_Target;
7         ...
8     }

// 建立視窗
需要 GLFW GLAD
配置 GLFW 的連結庫,檔案包含, LINK連結器
配置 GLAD 的檔案包含,將glad.c 加入到專案中去

VS環境下需要有main函式編譯才能完全成功。

GLAD: 用來管理OpenGL的函式指標,在呼叫任何OpenGL的函式之前需要初始化GLAD,他會根據不同的編譯系統返回可使用的正確的函式。

雙緩衝:應用程式使用單緩衝繪圖時可能會存在影象閃爍的問題。因為單緩衝狀態下影象不是一下子就繪製出來的,是按照從左到右,從上到下一步步繪製而成。為了解決這個問題一般會使用雙緩衝繪製方式解決問題,前緩衝區儲存著最終輸出的成像,並在螢幕上顯示,所有的渲染指令都會在後緩衝上繪製,在所有渲染指令執行完畢後,交換(swap)前後緩衝,影象就可以立即顯示出來。

 1 #include <iostream>
 2
#include <glad/glad.h> 3 #include <GLFW/glfw3.h> 4 #include <Windows.h> 5 #include <ctime> 6 7 using namespace std; 8 9 const unsigned int SCR_WIDTH = 800; 10 const unsigned int SCR_HEIGHT = 600; 11 12 void framebuffer_size_callback(GLFWwindow* windos, int width, int height) 13 { 14 glViewport(0, 0, width, height); 15 } 16 17 void key_callback(GLFWwindow* window, int key, int scancode, int action, int mode) 18 { 19 if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) 20 { 21 glfwSetWindowShouldClose(window, GL_TRUE); 22 } 23 else if (key == GLFW_KEY_C && action == GLFW_PRESS) 24 { 25 srand(time(0)); 26 float r = ((rand() % 10) + 1) / 10.0f; 27 float g = ((rand() % 10) + 1) / 10.0f; 28 float b = ((rand() % 10) + 1) / 10.0f; 29 glClearColor(r, g, b, 1.0f); 30 glClear(GL_COLOR_BUFFER_BIT); 31 glfwSwapBuffers(window); 32 } 33 } 34 35 int main() 36 { 37 //初始化GLFW 38 glfwInit(); 39 40 //設定OpenGL版本號為3.3 41 glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); 42 glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); 43 44 //設定OpenGL渲染方式為核心渲染 45 glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); 46 47 // 建立一個寬800,高600,的視窗,視窗名字為"myGLWindow". 48 GLFWwindow* window = glfwCreateWindow(SCR_WIDTH, SCR_HEIGHT, "myGLWindow", NULL, NULL); 49 if (window == NULL) 50 { 51 std::cout << "Failed to create GLFW window" << std::endl; 52 glfwTerminate(); // 銷燬視窗和資源 53 return -1; 54 } 55 56 // 設定該視窗為GLFW的主當前執行緒的主上下文 57 glfwMakeContextCurrent(window); 58 59 //初始化GLAD, 其實是用載入系統相關的OpenGL函式指標地址的函式的返回值判斷GLAD是否初始化成功 60 if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) 61 { 62 std::cout << "Failed to initialize GLAD" << std::endl; 63 return -1; 64 } 65 66 // 獲取視窗windows的寬高 67 int width, height; 68 glfwGetFramebufferSize(window, &width, &height); 69 70 71 // 設定OpenGL渲染視窗的尺寸大小, 前兩個引數控制左下角原點的位置 72 glViewport(0, 0, width, height); 73 74 // 註冊視窗大小改變的回撥 75 glfwSetFramebufferSizeCallback(window, framebuffer_size_callback); 76 77 //新增鍵盤輸入回撥 78 glfwSetKeyCallback(window, key_callback); 79 80 // 迴圈渲染 81 while (!glfwWindowShouldClose(window)) 82 { 83 //glClearColor(0.2f, 0.3f, 0.5f, 1.0f); 84 //glClear(GL_COLOR_BUFFER_BIT); 85 //glfwSwapBuffers(window); // 交換視窗顏色緩衝 86 87 glfwPollEvents(); // 檢查事件觸發,更新視窗狀態,呼叫已經註冊的回撥函式 88 } 89 90 glfwTerminate(); 91 92 return 0; 93 }