注意
本文正在建構中。
Khronos Group 發布了一個名為 EGL 的規範,它是一個 API,可以處理(在其他任務中)圖形上下文建立、渲染表面管理,以及不同 Khronos Group 圖形 API(OpenGL、OpenGL ES、OpenVG)之間的互操作。如需詳細資訊,請參閱 Khronos EGL 網頁。
目前,EGL 在作業系統/圖形驅動程式供應商之間並未廣泛使用。最顯著的採用是在 Android 架構中,當使用 Android NDK 時,EGL 是建立 OpenGL ES 1&2 渲染上下文的主要方法。此外,Mesa 在其 圖形驅動程式中實作了 EGL 規範。
Emscripten 也提供了 EGL v1.4 規範的實作。這允許 C/C++ 客戶端程式碼使用(幾乎)統一的程式碼庫,以在 Web、Linux(使用 Mesa)和 Android NDK 上建立 GLES2 (WebGL) 渲染上下文。Emscripten 中 EGL 規範的實作並不完美,請參閱本頁結尾的狀態圖表。
有點令人失望的是,EGL 並不是一個自行足夠的完整解決方案,用於初始化 GLES2 圖形渲染(在任何平台上,而不僅僅是 Emscripten)並監督各種相關任務。規範的範圍有限,並且缺乏某些功能。特別是,EGL 無法協助執行以下任務
建立渲染視窗。EGL 規範沒有指定如何建立要渲染到的目標視窗。必須使用平台特定的原生視窗系統函數(X11、Win32 API、ANativeWindow)來先建立渲染視窗。
以任意像素增量指定渲染視窗大小。EGL 沒有任何功能可以請求主渲染視窗的所需大小,或調整其大小。
指定全螢幕視訊模式/螢幕解析度。EGL 不能用於控制是以視窗模式還是全螢幕模式進行渲染,或在執行時期在這兩者之間切換。
因此,對於每個平台(包括 Emscripten),都存在平台特定的方法來執行這些任務。
在 Web 環境中,WebGL 是用於 3D 加速渲染的技術。WebGL 幾乎與 GLES2 相同,而且由於 EGL 完全不適用於 WebGL,因此在本頁的所有目的中,WebGL 和 GLES2 這兩個術語可以互換使用。因此,要建立 WebGL 上下文,可以使用 EGL,並根據其措辭,建立 GLES2 上下文。
執行以下步驟以使用 EGL 建立 GLES2 上下文
呼叫 eglGetDisplay
取得 EGLDisplay
物件的控制代碼。
呼叫 eglInitialize
在該顯示器上初始化 EGL。
呼叫 eglGetConfigs
和/或 eglChooseConfig
一次或多次,以找到代表所需主渲染目標參數的 EGLConfig
。若要檢查 EGLConfig
的屬性,請呼叫 eglGetConfigAttrib
。
此時,可以使用任何可用的平台特定函數(X11、Win32 API、ANativeWindow)來設定要渲染的原生視窗。對於 Emscripten,此步驟不適用,可以跳過。
呼叫 eglCreateWindowSurface
,並使用有效的顯示器和組態參數,建立主要渲染目標表面 (EGLSurface
)。將視窗和屬性清單參數設定為 null。
呼叫 eglCreateContext
建立 GLES2 渲染上下文 (EGLContext
),然後呼叫 eglMakeCurrent
來啟動渲染上下文。建立上下文時,請指定上下文屬性 EGL_CONTEXT_CLIENT_VERSION == 2
。
執行這些步驟後,您會擁有一組 EGL 物件 EGLDisplay
、EGLConfig
、EGLSurface
和 EGLContext
,它們代表主要的 GLES2 渲染上下文。
取消初始化時的清理順序如下
呼叫 eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT)
以釋放目前作用中的渲染上下文。
在其上呼叫 eglDestroyContext
,以取消初始化 EGLContext
物件。
在其上呼叫 eglDestroySurface
,以銷毀所有已初始化的 EGLSurface
物件。
呼叫 eglTerminate(display)
以完全取消初始化 EGL。
刪除原生渲染視窗。此步驟不適用於 Emscripten。
在 emscripten/test/third_party/glbook 目錄中的範例應用程式中,可以找到使用 EGL 初始化 WebGL 上下文的範例程式碼,更具體而言,是在 esUtil.c 檔案中。
本節列出所有 EGL v1.4 函數,並說明它們在 Emscripten 中的目前實作狀態。
eglInitialize
、eglGetConfigs
、eglQueryContext
、eglQueryString
、eglQuerySurface
、eglGetCurrentContext
、glGetCurrentSurface
、eglGetCurrentDisplay
、eglReleaseThread
、eglDestroySurface
、eglDestroyContext
:已實作,且應根據 EGL v1.4 規範運作。
eglSwapBuffers
:已實作,但此函數無法真正控制 WebGL 下的交換行為。在 Emscripten 下呼叫此函數是可選的。在 WebGL 中,只有在程式碼將執行權返回給瀏覽器之後,也就是當您從傳遞給 emscripten_set_main_loop()
的勾選回呼處理程式返回時,才會將顯示器的內容呈現到螢幕上。eglSwapBuffers
函數仍然可以用於偵測何時發生 GL 上下文遺失事件。
eglGetDisplay
:根據規範實作。Emscripten 不會使用多個 EGLNativeDisplayType
物件,因此請在此處傳入 EGL_DEFAULT_DISPLAY
。Emscripten 目前實際上會忽略在此處傳入的任何值,以用於 Linux 模擬目的,但您不應在未來依賴此行為。
eglGetError
:根據規範實作。
重要
根據規範,eglGetError
會報告單一最近發生的錯誤,而不是先前所有錯誤的清單。請勿以您呼叫 glGetError
的方式在迴圈中呼叫此函數。
eglChooseConfig
:已實作為存根,但此函式不會進行搜尋/篩選,目前與 eglGetConfigs
相同(issue #643)。
eglGetConfigAttrib
:已實作。查詢屬性 EGL_BUFFER_SIZE
、EGL_ALPHA_SIZE
、EGL_BLUE_SIZE
、EGL_GREEN_SIZE
、EGL_RED_SIZE
、EGL_DEPTH_SIZE
和 EGL_STENCIL_SIZE
目前會回傳硬編碼的預設值(issue #644)。屬性 EGL_MIN_SWAP_INTERVAL
和 EGL_MAX_SWAP_INTERVAL
目前沒有任何作用。請改為呼叫 emscripten_set_main_loop()
來指定主迴圈更新速率。
eglCreateWindowSurface
:已實作,但無法多次呼叫此函式以建立多個渲染視窗。
eglCreateContext
:已實作為存根。無法多次呼叫此函式以建立多個上下文。
eglBindAPI
、eglQueryAPI
:已實作,儘管這些函式在 Emscripten 上幾乎沒有用處,因為僅支援 GLES2 用戶端 API。
eglWaitClient
、eglWaitNative
:已實作為無操作函式。這些在 Emscripten 上沒有意義。
eglSwapInterval
:已實作為無操作存根。目前此函式無法設定垂直同步間隔,或啟用/停用它。
eglMakeCurrent
:已實作為無操作存根。
eglTerminate
:已實作為無操作函式存根。JavaScript 應用程式通常不會手動關閉,但在關閉瀏覽器或切換網頁時,瀏覽器會自動管理所有終止操作。因此,此函式在 Emscripten 中並不具有關鍵的重要性。
eglGetProcAddress
:已實作,實驗性功能。
目前未實作下列函式
eglCreatePbufferSurface
、eglCreatePixmapSurface
、eglCreatePbufferFromClientBuffer
、eglSurfaceAttrib
、eglBindTexImage
、eglReleaseTexImage
、eglWaitGL
、eglCopyBuffers
。
重要
請勿在 Emscripten 程式碼中呼叫這些函式,否則應用程式在嘗試執行未定義的函式時會停止。
目前,Emscripten 沒有實作 EGL 擴充功能註冊表 中的任何擴充功能。