Emscripten bietet drei OpenGL-Modi
WebGL-freundliche Untermenge von OpenGL ES 2.0/3.0 (Standard) — unterstützt die Menge der OpenGL ES 2.0/3.0-Befehle, die direkt auf WebGL 1/2 abbilden.
OpenGL ES 2.0/3.0 Emulation — Unterstützung für einige emulierte OpenGL ES 2.0/3.0-Funktionen, die in WebGL nicht vorhanden sind.
Emulation älterer Desktop OpenGL API-Funktionen — Unterstützung für eine Reihe älterer GL 1.x-Funktionen und -Befehle.
Dieses Thema enthält Informationen über die Modi und wie sie aktiviert werden.
Tipp
Wir empfehlen dringend, die WebGL-freundliche Untermenge von OpenGL ES 2.0/3.0 für neuen Code zu verwenden und, wenn möglich, vorhandenen Code auf diese Untermenge zu portieren. Die anderen beiden Modi sind weniger effizient und sollten nur für Codebasen in Betracht gezogen werden, die stark auf diese Funktionen angewiesen sind.
Standardmäßig zielt Emscripten auf die WebGL-freundliche Untermenge von OpenGL ES 2.0 ab. Dies ist die Menge der GL ES-Befehle, die direkt auf WebGL abgebildet werden, sodass jeder GL-Befehl eine ungefähr direkte Zuordnung zu WebGL hat. Sie umfasst fast alles von OpenGL ES 2.0, mit der bemerkenswerten Ausnahme von clientseitigen Arrays und einigen anderen Funktionen, die in WebGL 1.0 Spezifikation/Kapitel 6 aufgeführt sind.
Um mit der WebGL-Untermenge von OpenGL ES zu programmieren, verwendet man die GL ES 2.0 Header-Dateien und die GL ES 2.0 API, wobei die in Kapitel 6 der WebGL-Spezifikation genannten Einschränkungen einzuhalten sind.
Dieser Modus wird standardmäßig verwendet, da er am besten zu den von Browsern bereitgestellten WebGL-Funktionen passt.
Um WebGL 2 anzuvisieren, übergeben Sie das Linker-Flag -sMAX_WEBGL_VERSION=2. Das Angeben dieses Flags ermöglicht (und ist Standard, sofern bei der Kontexterstellung nichts anderes angegeben wird) die Erstellung von WebGL 2-Kontexten zur Laufzeit, aber es ist immer noch möglich, WebGL 1-Kontexte zu erstellen, sodass Anwendungen wählen können, ob sie WebGL 2 benötigen oder eine Rückfalloption auf WebGL 1 unterstützen möchten.
Um nur WebGL 2 anzuvisieren und die Unterstützung für WebGL 1 vollständig zu entfernen, um die Codegröße zu sparen, übergeben Sie die Linker-Flags -sMIN_WEBGL_VERSION=2 und -sMAX_WEBGL_VERSION=2.
Dieser Build-Modus emuliert einige Funktionen von OpenGL ES 2.0/3.0, die nicht Teil der WebGL 1-Kernspezifikation sind.
Insbesondere emuliert dieser Modus clientseitige Arrays, die in der 1 WebGL-freundlichen Untermenge von OpenGL ES 2.0/3.0 fehlen.
Dies ermöglicht die Verwendung der Funktionen glDrawArrays und glDrawElements usw. ohne gebundenen Puffer, und die GL-Bindungen von Emscripten richten den Puffer automatisch ein (WebGL erfordert, dass ein Puffer gebunden ist).
Hinweis
Dieser Build-Modus hat die Einschränkung, dass der größte Index im clientseitigen Indexpuffer kleiner sein muss als die Gesamtzahl der Indizes in diesem Puffer. Weitere Details finden Sie in Ausgabe #4214.
Um die OpenGL ES 2.0 Emulation zu aktivieren, geben Sie die emcc-Option -sFULL_ES2 beim Linken des finalen ausführbaren Programms (.js/.html) des Projekts an.
Um die OpenGL ES 3.0 Emulation zu aktivieren, geben Sie die emcc-Option -sFULL_ES3 beim Linken des finalen ausführbaren Programms (.js/.html) des Projekts an. Dies fügt die Emulation für die Abbildung von Speicherblöcken auf clientseitigen Speicher hinzu. Die Flags -sFULL_ES2 und -sFULL_ES3 sind orthogonal, sodass entweder eines oder beide angegeben werden können, um verschiedene Funktionen zu emulieren.
Dieser OpenGL-Modus ermöglicht die Unterstützung einer Reihe älterer Desktop OpenGL 1.x-Funktionen und -Befehle (zum Beispiel "immediate mode" und glNormalPointer).
Obwohl die Emulation keineswegs vollständig ist, war sie ausreichend, um das 3D-Spiel Sauerbraten (BananaBread-Projekt) und einige andere reale Codebasen mit Emscripten zu portieren.
Um diesen Modus zu aktivieren, geben Sie die emcc-Option -sLEGACY_GL_EMULATION beim Linken der finalen ausführbaren Datei (.js/.html) des Projekts an.
In diesem Modus (-sLEGACY_GL_EMULATION) gibt es einige zusätzliche Flags, die verwendet werden können, um die Leistung der GL-Emulationsschicht zu optimieren
-sGL_UNSAFE_OPTS versucht, redundante GL-Arbeit und Bereinigung zu überspringen. Diese Optimierung ist unsicher und daher standardmäßig nicht aktiviert.
-sGL_FFP_ONLY weist die GL-Emulationsschicht an, dass Ihr Code die programmierbare Pipeline/Shader überhaupt nicht verwenden wird. Dies ermöglicht dem GL-Emulationscode, zusätzliche Optimierungen durchzuführen, wenn er weiß, dass dies sicher ist.
Fügen Sie die Ganzzahl Module.GL_MAX_TEXTURE_IMAGE_UNITS zu Ihrer Shell-Datei .html hinzu, um die maximale Anzahl der vom Code verwendeten Textureinheiten zu signalisieren. Dies stellt sicher, dass die GL-Emulationsschicht keine Taktzyklen verschwendet, indem sie ungenutzte Textureinheiten durchläuft, wenn sie überprüft, welcher Fixed Function Pipeline (FFP)-Emulationsshader ausgeführt werden soll.
Sie können in Betracht ziehen, die Codebasis gegen die Desktop-OpenGL-Emulationsbibliothek Regal zu erstellen, die darauf abzielt, Desktop-OpenGL-Funktionen auf OpenGL ES 2.0 zu unterstützen. Dies kann je nach Projekt besser oder schlechter funktionieren als die GL-Emulation von Emscripten. Eine weitere Option ist die Verwendung von gl4es, das eine schnelle OpenGL-zu-GLES-Konvertierung für Spiele anstrebt. Es zielt auf das OpenGL 2.1-Profil auf OpenGL ES 2.0 ab und wurde bereits verwendet, um einige Spiele mit Emscripten zu portieren.
Beim Portieren von Code ist zu beachten, dass Desktop OpenGL, OpenGL ES und WebGL jeweils eigene Erweiterungsregister haben. Dies bedeutet, dass weder Desktop OpenGL- noch OpenGL ES-Erweiterungen automatisch auch WebGL-Erweiterungen sind, obwohl ein gewisses Maß an Parität besteht. Die vollständige Liste der registrierten Erweiterungen finden Sie im WebGL 1.0 Erweiterungsregister.
Zusätzlich müssen in WebGL, anders als in Desktop- oder mobilen OpenGL, Erweiterungen erst aktiviert werden, bevor die von ihnen bereitgestellten Funktionen wirksam werden. Wenn Sie eine der nativen APIs SDL, EGL, GLUT oder GLFW verwenden, um Ihren GL-Kontext zu erstellen, geschieht dies für die meisten Erweiterungen automatisch. Wenn Sie stattdessen die HTML5 WebGL-Kontexterstellungs-API verwenden, müssen Sie explizit wählen, ob WebGL-Erweiterungen automatisch aktiviert werden sollen. Wenn eine Erweiterung zum Zeitpunkt der Kontexterstellung nicht automatisch aktiviert wurde, kann die HTML5 API-Funktion emscripten_webgl_enable_extension verwendet werden, um sie zu aktivieren. Debugging-bezogene Erweiterungen, Entwurfserweiterungen und Anbieter-präfixierte Erweiterungen (MOZ_*, WEBKIT_*) werden niemals automatisch zum Zeitpunkt der Kontexterstellung aktiviert, sondern müssen immer manuell aktiviert werden.
Beim Migrieren von WebGL 1 zu WebGL 2 ist zu beachten, dass einige WebGL 1-Erweiterungen in den Kern von WebGL 2 migriert werden und daher ihre Funktionalität nicht mehr als GL-Erweiterungen beworben wird. Dies bedeutet nicht, dass die Funktionen fehlen würden, sondern dass es möglich ist, diese Funktionen in WebGL 2 zu nutzen, ohne vorher die Anwesenheit einer GL-Erweiterung testen zu müssen.
Die Dateien unter test/third_party/glbook bieten eine Reihe einfacher Beispiele, die nur die WebGL-freundliche Untermenge von OpenGL ES 2.0/3.0 verwenden.
Die anderen Modi werden in verschiedenen Tests abgedeckt, darunter mehrere in test/test_browser.py. Der beste Weg, die Tests zu finden, ist die Suche im Quellcode nach den entsprechenden Compiler-Flags: FULL_ES2, LEGACY_GL_EMULATION usw.
Der Emscripten Fehler-Tracker hat spezifische Labels für OpenGL und OpenGL-Emulation, um verschiedene GL-bezogene Probleme zu verfolgen.
Fußnoten
Clientseitige Arrays fehlen in WebGL, da sie weniger effizient sind als die korrekte Verwendung GPU-seitiger Daten.