opengl關(guān)于glut, freeglut, glfw, glew, glad, gl3w庫(kù)的說(shuō)明

剛?cè)腴T(mén)opengl的時(shí)候最煩的就是各種庫(kù)的配置,glut, freeglut, glfw, glew, glad, gl3w 等等,簡(jiǎn)直要暈了. 最后查閱網(wǎng)上的資料大概得出了這樣的結(jié)論:


opengl僅僅是一個(gè)標(biāo)準(zhǔn)/規(guī)范,但是具體利用opengl開(kāi)發(fā)對(duì)應(yīng)的應(yīng)用則需要依賴具體的開(kāi)發(fā)環(huán)境例如windows, linux等, 而最常見(jiàn)的就是窗口, IO控制等交互邏輯,因此glut, freeglut, glfw這類(lèi)的庫(kù)便產(chǎn)生了


  • glut (Opengl Utility Tool)

    • 定義以及控制視窗
    • 偵測(cè)并處理鍵盤(pán)和鼠標(biāo)事件
    • 以一個(gè)函數(shù)呼叫繪制某些常用立體圖形,如長(zhǎng)方體,球,猶他茶壺
    • 提供了簡(jiǎn)單選單列的實(shí)現(xiàn)

    所有g(shù)lut的庫(kù)函數(shù)均已glut開(kāi)頭, 例如glutPostRedisplay(). 后來(lái)以及停止維護(hù)了

  • freeglut

    glut的替代品,最新穩(wěn)定的版本是Freeglut3.0.0 (2015年3月7日)

  • glfw (Graphics Library Framework)

    • 創(chuàng)建管理窗口和opengl的上下文
    • 處理手柄,鍵盤(pán),鼠標(biāo)輸入

    目前glfw還在維護(hù),可以說(shuō)glfw庫(kù)可以是代替glut和freeglut的庫(kù)的


opengl是一個(gè)標(biāo)準(zhǔn)/規(guī)范, 具體的實(shí)現(xiàn)是由驅(qū)動(dòng)開(kāi)發(fā)商針對(duì)特定的顯卡而實(shí)現(xiàn).支持opengl的驅(qū)動(dòng)版本眾多,大多數(shù)函數(shù)的地址(內(nèi)存地址)無(wú)法在編譯時(shí)候確定下來(lái),需要運(yùn)行的時(shí)候查詢.所以在運(yùn)行的時(shí)候獲取函數(shù)的內(nèi)存地址并把其保存在一個(gè)函數(shù)指針中供后續(xù)使用. glew, glad, gl3w基本都是實(shí)現(xiàn)類(lèi)似的功能


  • glad

    //glad.h
    ///////////////////////////////////////////////////////////////////
    /*#55 定義一個(gè)函數(shù)指針,為GLADloadproc類(lèi)型,這種函數(shù)是以一個(gè)const char*為參數(shù)并返回void*的類(lèi)型,在glad.c中便用GLADloadproc load來(lái)聲明了一個(gè)GLADloadproc 類(lèi)型的函數(shù)load, 所以load函數(shù)的參數(shù)為(const char *name)返回值為void*
    */
    typedef void* (* GLADloadproc)(const char *name);
    
    ////////////////////////////////////////////////////////////////////////
    //這里的APIENTRYP(API_entry_pointer即api條目指針) 表示 APIENTRY *, 而APIENTRY表示 __stdcall
    #define GLAPI extern
    #define APIENTRY __stdcall
    #define APIENTRYP APIENTRY *
    
    ///////////////////////////////////////////////////////////////////////
    /*#1806, 定義函數(shù)指針,為PFNGLGENBUFFERSPROC類(lèi)型,參數(shù)為(GLsizei n, GLuint *buffers), 返回值為void的類(lèi)型*/
    typedef void (APIENTRYP PFNGLGENBUFFERSPROC)(GLsizei n, GLuint *buffers);
    /*用為PFNGLGENBUFFERSPROC類(lèi)型來(lái)定義一個(gè)函數(shù)指針名字為glad_glGenBuffers, 類(lèi)型是extern*/
    GLAPI PFNGLGENBUFFERSPROC glad_glGenBuffers;
    #define glGenBuffers glad_glGenBuffers // glGenBuffers的宏定義,使用glGenBuffers函數(shù)時(shí)候其實(shí)就是調(diào)用的glad_glGenBuffers
    
    ////////////////////////////////////////////////////////////////////////
    //glad.c
    PFNGLGENBUFFERSPROC glad_glGenBuffers = NULL;//#452 聲明和定義glad_glGenBuffers這個(gè)函數(shù)指針為NULL
    glad_glGenBuffers = (PFNGLGENBUFFERSPROC)load("glGenBuffers");//#1086, 使用glad_glGenBuffers函數(shù)的時(shí)候就去load名字為glGenBuffers的函數(shù)
    

    具體怎么找函數(shù)的流程:

    1. openg工程中main函數(shù)里面有g(shù)ladLoadGLLoader, gladLoadGLLoader里面把從opengl1.0到目前最高opengl4.6的函數(shù)都讀入

    2. 在glad.c中有一個(gè)函數(shù)

      static int open_gl(void) {
      #ifndef IS_UWP
          libGL = LoadLibraryW(L"opengl32.dll");
          if(libGL != NULL) {
              void (* tmp)(void);
              tmp = (void(*)(void)) GetProcAddress(libGL, "wglGetProcAddress");
              gladGetProcAddressPtr = (PFNWGLGETPROCADDRESSPROC_PRIVATE) tmp;
              return gladGetProcAddressPtr != NULL;
          }
      #endif
      

      去系統(tǒng)中加載opengl32.dll這個(gè)庫(kù),然后GetProcAddress檢索指定的動(dòng)態(tài)鏈接庫(kù)(DLL)中的輸出庫(kù)函數(shù)地址.

    3. 而[根據(jù)某位知乎網(wǎng)友的解答][https://www.zhihu.com/question/30130562/answer/46983748] ,opengl32.dll僅僅為用戶提供了統(tǒng)一API的接口以及擴(kuò)展這些接口的可能, opengl32.dll被加載后嘗試調(diào)用更底層的ICD驅(qū)動(dòng)程序,從而完成具體的圖形操作. 而GLEW這些庫(kù),根據(jù)opengl的接口說(shuō)明,從動(dòng)態(tài)庫(kù)(opengl32.dll)中請(qǐng)求對(duì)應(yīng)的函數(shù)接口,如果能得到有效地址,那么這個(gè)函數(shù)是被當(dāng)前驅(qū)動(dòng)所支持的,就可以用,否則就無(wú)法支持.實(shí)際上,你也可以根據(jù)你當(dāng)前應(yīng)用中使用到的函數(shù)(通常一個(gè)小的演示demo,如顯示一個(gè)三角形,并沒(méi)有使用到很多的gl函數(shù))而獲取函數(shù)接口也是完全可行的. glew,glad,gl3w這些庫(kù)幫助用戶完成了所有接口的查詢和獲取.

  • glad, gl3w的作用類(lèi)似不做更多敘述.
    但是gl3w是利用python開(kāi)發(fā)的, 因此需要安裝python庫(kù)進(jìn)行編譯生成相關(guān)的文件,具體的流程可以參考基于GLFW和GL3W庫(kù)的OPEN GL環(huán)境配置


結(jié)論: 可以用上面兩類(lèi)的庫(kù)進(jìn)行組合,例如我自己常用的是glfw + glad來(lái)進(jìn)行opengl的開(kāi)發(fā), 也有很多開(kāi)發(fā)者使用的是glfw + gl3w, 或者 glfw + glew

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容