2024-07-22|閱讀時間 ‧ 約 28 分鐘

[OpenGL]底下的各種GL,並論其本質

👋 剛學OpenGL時就對這件事情感到相當疑惑,還沒開始寫程式,光是前置作業,就被各種函式庫搞得頭痛,為什麼不能像OpenCV一樣方便呢?後來才知道這跟OpenGL的本質有關;怕自己忘記故在此紀錄之。

1. 前言 -各種流派

初學OpenGL時,無論是看書、上課或者網路上的開源教學,自己當時覺得OpenGL的環境搭建十分令人摸不著頭緒,每個教學的指南開發環境都不盡相同,有freeglut + glew的,也有glfw + glew的,也有glfw+glad的,也有一些應用是用gl + glu的。

且用不一樣函式庫,在開發程式時的寫法又有很大的差別;像是有些教學明明一樣是在c++環境下,在寫shader時,有的可以使用c++原生的char*宣告字元指標:

const char* VertexShader;

然而也些卻需要使用另一個GLchar*來進行宣告:

const GLchar* VertexShader;

否則後續編譯shader時會報錯,也因此環境的搭建與程式的寫法需個別討論。

下面自己把一些OpenGL相關資訊整理,並簡單看了一下並整理了一些後面的想法與廢話。




2.靈魂拷問 — OpenGL「原本」真的是一種圖形API嗎?

這裡先引用一下原文書-Learn OpenGL: Learn modern OpenGL graphics programming in a step-by-step fashion中的一段話:

OpenGL is mainly considered an API (an Application Programming Interface) that provides us with a large set of functions that we can use to manipulate graphics and images. However, OpenGL by itself is not an API, but merely a specification, developed and maintained by the www.khronos.org/.

原意大概就是:OpenGL本身不是一個具體的API,而是一套規範。書中後面敘述道:對於OpenGL而言,它的本質僅僅決定了每個函數的結果/輸出形式,以及它應該如何被執行,然後再由開發人員決定這個函數如何實際上運作。簡單來說,OpenGL只管頭尾,中間無論如何實現,只要符合規範即可,也因此在對岸的一些技術討論或交流中,常常會看到他們會形容OpenGL本身「僅有框架(frameworks),沒有實現(implementations)」。

而所謂實現(implementations)通常是由GPU製造商負責,並以驅動程式的形式在OpenGL的規範下去完成,所以應用層如遊戲、3D軟體底部所使用的3D渲染與計算,實際上都是GPU製造商實現的,而非OpenGL本身,每家廠商透過撰寫這些程序與自己GPU的運算單元溝通。




3.那麼結果 — 衍生出來的必要之惡:API

所以從上段我們可以知道-在OpenGL的規範下開發,是需要靠開發者自己去實現很多細節的,這種模式使的開發難度非常之高,此時就會有一群人開始整理一些OpenGL的函數,配合開發時所需要的視窗調用、事件觸發與處理等相關應用層的功能,整合成了一系列的函式庫(Library)實現了API的用途,使開發者能夠簡單調用這些函式並完成實現,而這個東西就是我們看到的各種gl__的原型。

故事還沒完,開源社群又秉持著模組化的精神,盡量使專案易於擴充與修改,又根據功能、開發環境將其拆分成數個函式庫,且為了因應高速發展的遊戲業、計算性能越來越強的GPU,許多複雜的3D運算與渲染技術陸續加入規範之中;而舊的函式庫會為了一些老產品或低階應用必須留著,所以又整合出了新的函式庫…..

就這樣,模組化+歷史共業造就出了一堆現在我們看到的各種gl_library,所以網路上看到環境設置不同的開發指南,都是根據不同應用、不同時空背景下所衍生出的……多樣性?或者負面一點的說法:必要之惡。

那既然搞清楚原因了,問題還是回到實際的專案開發上,我們該如何去決定開發時要用什麼樣的gl_library呢?




4. 回到現實 — 即使看完且知道了那麼多,你也不能改變什麼

即使知道了前因後果,你仍然只能從這些必要之惡中挑出幾個來用,使用之前還必須知道這些gl_library的用途,所幸對岸有人整理出下圖:


分成兩大類後,就可以把一些你聽到過的函式庫由老到新排列出來:

  • 負責封裝原本OpenGL規範接口,實現跨平台開發:

(老) glew → glad (新)

  • 負責處理I/O、管理視窗等,基本上處理跨平台以外的所有事情:

(老) glut → Freeglut→ glfw (新)

至於如何選擇,就需要是考慮GPU支援的OpenGL版本以及該函式庫支援的OpenGL版本來決定,基本上如果沒有什麼特殊原因,在現在(2023)做開發都還是建議用最新的glad + glfw。




5. 論其本質 — 那到底OpenGL還是不是一種圖形API?

綜合上面那些廢話,先大概整理了下面三個論點來說明:

  1. 開放性規範:OpenGL是一個開放的規範,由Khronos Group維護。這意味著它的規範是公開的,並且可以由多個圖形硬體和軟體供應商實現。這樣,不同供應商可以根據OpenGL的規範來實現自己的驅動程序,以支持他們的硬體,從而實現了跨平台的兼容性。
  2. 只管頭尾,不限中間實現:這是OpenGL的一個關鍵特點。OpenGL規範定義了一組函數和行為,但它並不關心具體的實現細節。這樣,不同供應商可以使用不同的方法和技術來實現OpenGL。這種靈活性使得OpenGL能夠適應不同的硬體和軟體環境。
  3. 庫和工具的選擇:除了OpenGL規範外,開發人員通常需要使用其他庫和工具,如窗口管理庫(如GLFW、SDL)和擴展管理庫(如GLEW、GLAD)來建立完整的OpenGL開發環境。這些庫和工具可以視為OpenGL開發的輔助元素,它們不是「OpenGL本身」的一部分,但通常與OpenGL一起使用以簡化開發過程。

所以對於底層開發者-我說的是那些跟底層打交道的GPU製造商,那它僅僅是一套規範;對於我們這種需要輔助庫與輔助工具的應用層開發人員,那它就是一種圖形API。

對於設計工具的人,它是業界規範(specification)對於使用工具的人,它是工具箱(API)

參考資料:

https://www.cnblogs.com/chencarl/p/10722839.html

原文書 : de Vries, Joey , Learn OpenGL: Learn modern OpenGL graphics programming in a step-by-step fashion (2020)


分享至
成為作者繼續創作的動力吧!
© 2024 vocus All rights reserved.