Emscripten 提供三種 OpenGL 模式
與 WebGL 相容的 OpenGL ES 2.0/3.0 子集 (預設) — 支援直接對應到 WebGL 1/2 的 OpenGL ES 2.0/3.0 命令集。
OpenGL ES 2.0/3.0 模擬 — 支援 WebGL 中不存在的某些模擬 OpenGL ES 2.0/3.0 功能。
舊版桌面 OpenGL API 功能的模擬 — 支援許多舊版 GL 1.x 功能和命令。
本主題提供有關模式以及如何啟用它們的資訊。
提示
我們強烈建議新程式碼使用與 WebGL 相容的 OpenGL ES 2.0/3.0 子集,如果可能,將現有程式碼移植到此子集。其他兩種模式效率較低,僅應考慮用於嚴重依賴這些功能的程式碼庫。
預設情況下,Emscripten 的目標是與 WebGL 相容的 OpenGL ES 2.0 子集。這是直接對應到 WebGL 的 GL ES 命令集,因此每個 GL 命令都大致直接對應到 WebGL。它包含幾乎所有 OpenGL ES 2.0,但值得注意的是客戶端陣列以及 WebGL 1.0 規格/第 6 章中列出的一些其他功能除外。
為了針對 OpenGL ES 的 WebGL 子集進行程式設計,可以使用 GL ES 2.0 標頭檔和 GL ES 2.0 API,同時遵守 WebGL 規格第 6 章中指定的限制。
預設使用此模式,因為它最符合瀏覽器提供的 WebGL 功能。
為了針對 WebGL 2,請傳遞連結器旗標 -sMAX_WEBGL_VERSION=2
。指定此旗標會在執行時啟用 (並預設為,除非在建立內容時另行指定) 建立 WebGL 2 內容,但仍然可以建立 WebGL 1 內容,因此應用程式可以選擇是否需要 WebGL 2 或是否支援回退到 WebGL 1。
為了僅針對 WebGL 2 並完全放棄對 WebGL 1 的支援以節省程式碼大小,請傳遞連結器旗標 -sMIN_WEBGL_VERSION=2
和 -sMAX_WEBGL_VERSION=2
。
此建置模式模擬 OpenGL ES 2.0/3.0 的一些功能,這些功能不是核心 WebGL 1 規格的一部分。
特別是,此模式模擬缺少 1 的客戶端陣列與 WebGL 相容的 OpenGL ES 2.0/3.0 子集。
這讓您可以使用 glDrawArrays 和 glDrawElements 等函式,而無需繫結緩衝區,Emscripten 的 GL 繫結會自動設定緩衝區 (WebGL 需要繫結緩衝區)。
注意
此建置模式有一個限制,即客戶端索引緩衝區中最大的索引必須小於該緩衝區中的索引總數。如需詳細資訊,請參閱issue #4214。
若要啟用OpenGL ES 2.0 模擬,請在連結專案的最終可執行檔 (.js/.html) 時指定emcc 選項 -sFULL_ES2
。
若要啟用OpenGL ES 3.0 模擬,請在連結專案的最終可執行檔 (.js/.html) 時指定emcc 選項 -sFULL_ES3
。這會新增將記憶體區塊對應至客戶端記憶體的模擬。旗標 -sFULL_ES2
和 -sFULL_ES3
是正交的,因此可以指定其中一個或兩個來模擬不同的功能。
此 OpenGL 模式支援許多舊版桌面 OpenGL 1.x 功能和命令 (例如「立即模式」和 glNormalPointer)。
雖然模擬絕非完整,但它已足以使用 Emscripten 移植 Sauerbraten 3D 遊戲 (BananaBread 專案) 和其他一些真實世界的程式碼庫。
若要啟用此模式,請在連結專案的最終可執行檔 (.js/.html) 時指定emcc 選項 -sLEGACY_GL_EMULATION
。
在此模式 (-sLEGACY_GL_EMULATION
) 中,有一些額外的旗標可用於調整 GL 模擬層的效能
-sGL_UNSAFE_OPTS
嘗試略過多餘的 GL 工作和清除。此最佳化是不安全的,因此預設不會啟用。
-sGL_FFP_ONLY
告知 GL 模擬層您的程式碼完全不會使用可程式化管線/著色器。這讓 GL 模擬程式碼可以在知道安全的情況下執行額外的最佳化。
將 Module.GL_MAX_TEXTURE_IMAGE_UNITS
整數新增到您的 shell .html 檔案,以表示程式碼使用的紋理單位最大數量。這可確保 GL 模擬層在檢查要執行的固定函式管線 (FFP) 模擬著色器時,不會浪費時脈週期來迭代未使用的紋理單位。
您可以考慮針對 Regal 桌面 OpenGL 模擬程式庫建置程式碼庫,該程式庫旨在支援基於 OpenGL ES 2.0 的桌面 OpenGL 功能。根據專案的不同,這可能比 Emscripten 的 GL 模擬更好或更差。另一種選擇是使用 gl4es,它旨在快速將 OpenGL 轉換為 GLES 以用於遊戲。它的目標是基於 OpenGL ES 2.0 的 OpenGL 2.1 設定檔,並且已經使用 Emscripten 移植了一些遊戲。
在移植程式碼時,應注意桌面 OpenGL、OpenGL ES 和 WebGL 各自擁有自己的擴充功能登錄。這表示桌面 OpenGL 或 OpenGL ES 擴充功能都不會自動成為 WebGL 擴充功能,儘管確實存在一定程度的對等性。請參閱 WebGL 1.0 擴充功能登錄以取得完整已註冊擴充功能清單。
此外,在 WebGL 中,與桌面或行動 OpenGL 不同,必須先啟用擴充功能,它們所公開的功能才會生效。如果您使用原生 API SDL、EGL、GLUT 或 GLFW 來建立 GL 內容,則對於大多數擴充功能,會自動完成此操作。如果您改為使用 HTML5 WebGL 內容建立 API,則必須明確選擇是否自動啟用 WebGL 擴充功能。如果未在內容建立時自動啟用擴充功能,則可以使用 HTML5 API 函式 emscripten_webgl_enable_extension 來啟用它。偵錯相關的擴充功能、草稿擴充功能和廠商前置字元擴充功能 (MOZ_*, WEBKIT_*) 永遠不會在內容建立時自動啟用,而是必須一律手動啟用。
從 WebGL 1 遷移到 WebGL 2 時,請注意一些 WebGL 1 擴充功能會遷移到核心 WebGL 2,因此它們的功能不再宣傳為 GL 擴充功能。這並不表示缺少這些功能,而是可以在 WebGL 2 中利用這些功能,而無需先進行功能測試以確認是否存在 GL 擴充功能。
test/third_party/glbook 中的檔案提供了一些僅使用與 WebGL 相容的 OpenGL ES 2.0/3.0 子集的簡單範例。
其他模式已在各種測試中涵蓋,包括 test/test_browser.py 中的幾個測試。 找到這些測試的最佳方法是搜尋原始碼中適當的編譯器標誌: FULL_ES2
、 LEGACY_GL_EMULATION
等。
Emscripten 的 錯誤追蹤器 有專用於 OpenGL 和 OpenGL 模擬的標籤,用於追蹤各種與 GL 相關的問題。
腳註
WebGL 中缺少客戶端陣列,因為它們不如正確使用 GPU 端資料有效率。