天天看點

關于OpenGL的繪制上下文

     什麼是繪制上下文(Rendering Context)

      初學OpenGL,打開紅寶書,會告訴你OpenGL是個狀态機,OpenGL采用了用戶端-伺服器模式,那時覺得好抽象,直到後來了解了繪制上下文才把這些聯系起來。我們可以認為每一個硬體GPU是個伺服器,每一個繪制上下文對應于申請的一個用戶端,一個用戶端維護着一套狀态機,如果兩個視窗分别對應兩個不同的繪制上下文,則兩個視窗彼此狀态獨立。申請繪制上下文,意味着系統資源的申請,每個繪制上下文還是需要不少資源的,記得曾經試過在chrome的TAB頁不斷加載WebGL頁面,由于WebGL使用的是OpenGL ES,同樣需要繪制上下文,當加載三十多個頁面的時候,Chrome整個崩潰了。

     所有的OpenGL調用,都需要指定是在哪個上下文環境下調用的。不同的上下文中,同樣的資源ID,可能對應于各自上下文中不同類型的資源。

     不同的作業系統,都有各自的繪制上下文建立、和設定目前繪制上下文的API。

     如何建立繪制上下文

     我們一般做Demo程式,都會使用GLUT,是以很多人可能并沒有自己建立過繪制上下文。GLUT的函數GlutCreateWindow除了建立了一個視窗,同時還建立了一個繪制上下文,并将建立的繪制上下文設定為目前的繪制上下文。對于Windows平台,首先建立一個裝置上下文(Device Context,DC),以DC為輸入,可以建立一個繪制上下文。建立繪制上下文以後,調用MakeCurrent,将建立的上下文設定為目前的繪制上下文。

     建立了繪制上下文,并設定為目前上下文以後,還不能使用OpenGL最新的特性,調用OpenGL 1.1以後的API仍然會崩潰。一般我們使用Glew庫,調用glewInit(),得到OpenGL随顯示卡驅動一起釋出的新特性的函數入口位址。

    繪制上下文和線程

   兩個線程同時MakeCurrent到同一個繪制上下文,會導緻程式崩潰。大型程式的一般做法是申請一條線程,專門用于繪制,建立線程時,為該繪制線程申請一個繪制上下文,一直作為目前的上下文。所有的繪制相關的操作,都在繪制線程完成。

   上下文之間的資源共享

   每個視窗一個上下文,優點是可以保證狀态機不互相影響。但多個視窗需要使用同一份紋理,如何避免重複的資源申請呢?答案是上下文之間的圖形資源可以共享,先建立上下文A,再以A為輸入,建立上下文B,則B可通路在A上下文下建立的紋理資源。紋理、shader、Buffer等資源是可以共享的,但Frame Buffer Object(FBO)、Vertex Array Object(VAO)等容器對象不可共享,但可将共享的紋理和VBO綁定到各自上下文的容器對象上。

轉載于:https://www.cnblogs.com/Liuwq/p/5444641.html

繼續閱讀