Hinweis
Dieser Artikel befindet sich im Aufbau.
Die Khronos Group veröffentlicht eine Spezifikation namens EGL, eine API, die (neben anderen Aufgaben) die Erstellung von Grafikkontexten, die Verwaltung von Rendering-Oberflächen und die Interoperabilität zwischen verschiedenen Grafik-APIs der Khronos Group (OpenGL, OpenGL ES, OpenVG) handhabt. Detaillierte Informationen finden Sie auf der Khronos EGL-Webseite.
Derzeit wird EGL nicht sehr weit verbreitet über Betriebssysteme/Grafiktreiber-Anbieter hinweg eingesetzt. Die bemerkenswerteste Annahme findet sich in der Android-Architektur, wo EGL die primäre Methode zur Erstellung von Rendering-Kontexten für OpenGL ES 1&2 bei Verwendung des Android NDK ist. Auch Mesa hat eine Implementierung der EGL-Spezifikation in seinem Grafiktreiber.
Emscripten bietet auch eine Implementierung der EGL v1.4 Spezifikation. Dies ermöglicht C/C++-Client-Code, eine (nahezu) einheitliche Codebasis für die Erstellung eines GLES2 (WebGL)-Rendering-Kontexts über Web, Linux (mit Mesa) und Android NDK hinweg zu verwenden. Die Implementierung der EGL-Spezifikation in Emscripten ist nicht perfekt, siehe das Ende dieser Seite für eine Statusübersicht.
Etwas enttäuschend ist EGL keine selbstgenügsame Komplettlösung zur Initialisierung von GLES2-Grafik-Rendering (auf jeder Plattform, nicht nur Emscripten) und zur Überwachung verschiedener damit verbundener Aufgaben. Die Spezifikation ist in ihrem Umfang begrenzt und es fehlen einige Funktionen. Insbesondere kann EGL bei den folgenden Aufgaben nicht helfen
Erstellen eines Renderfensters. Die EGL-Spezifikation legt nicht fest, wie ein Zielfenster erstellt wird, in das gerendert werden soll. Man muss plattformspezifische native Fenstersystemfunktionen (X11, Win32 API, ANativeWindow) verwenden, um zuerst ein Renderfenster zu erstellen.
Festlegen der Renderfenstergröße in beliebigen Pixelschritten. EGL hat keine Funktionalität, um eine gewünschte Größe für das Haupt-Renderfenster anzufordern oder es zu ändern.
Festlegen eines Vollbild-Videomodus/Bildschirmauflösung. EGL kann nicht verwendet werden, um zu steuern, ob in einem Fenster- oder Vollbildmodus gerendert werden soll oder um zwischen diesen zur Laufzeit zu wechseln.
Daher gibt es für jede Plattform, einschließlich Emscripten, plattformspezifische Mittel, um diese Aufgaben auszuführen.
In der Webumgebung ist WebGL die Technologie, die für 3D-beschleunigtes Rendering verwendet wird. WebGL ist nahezu identisch mit GLES2, und da EGL für WebGL überhaupt nicht gilt, werden für alle Zwecke auf dieser Seite die Begriffe WebGL und GLES2 austauschbar verwendet. Um also einen WebGL-Kontext zu erstellen, verwendet man EGL und erstellt laut seiner Formulierung einen GLES2-Kontext.
Führen Sie die folgenden Schritte aus, um einen GLES2-Kontext mit EGL zu erstellen
Rufen Sie einen Handle zu einem EGLDisplay-Objekt ab, indem Sie eglGetDisplay aufrufen.
Initialisieren Sie EGL auf diesem Display, indem Sie eglInitialize aufrufen.
Rufen Sie eglGetConfigs und/oder eglChooseConfig ein- oder mehrmals auf, um das EGLConfig zu finden, das die gewünschten Haupt-Renderzielparameter darstellt. Um die Attribute eines EGLConfig zu untersuchen, rufen Sie eglGetConfigAttrib auf.
An diesem Punkt würde man alle verfügbaren plattformspezifischen Funktionen (X11, Win32 API, ANativeWindow) verwenden, um ein natives Fenster zum Rendern einzurichten. Für Emscripten entfällt dieser Schritt und kann übersprungen werden.
Erstellen Sie eine Haupt-Renderzieloberfläche (EGLSurface), indem Sie eglCreateWindowSurface mit einem gültigen Display und Konfigurationsparametern aufrufen. Setzen Sie Fenster- und Attributlistenparameter auf null.
Erstellen Sie einen GLES2-Rendering-Kontext (EGLContext), indem Sie eglCreateContext aufrufen, gefolgt von einem Aufruf von eglMakeCurrent, um den Rendering-Kontext zu aktivieren. Geben Sie beim Erstellen des Kontexts das Kontextattribut EGL_CONTEXT_CLIENT_VERSION == 2 an.
Nach diesen Schritten verfügen Sie über einen Satz von EGL-Objekten EGLDisplay, EGLConfig, EGLSurface und EGLContext, die den Haupt-GLES2-Rendering-Kontext darstellen.
Die Reihenfolge der Bereinigung bei der Deinitialisierung ist wie folgt
Geben Sie den derzeit aktiven Rendering-Kontext frei, indem Sie eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT) aufrufen.
Deinitialisieren Sie das EGLContext-Objekt, indem Sie eglDestroyContext darauf aufrufen.
Zerstören Sie alle initialisierten EGLSurface-Objekte, indem Sie eglDestroySurface darauf aufrufen.
Deinitialisieren Sie EGL vollständig, indem Sie eglTerminate(display) aufrufen.
Löschen Sie das native Rendering-Fenster. Dieser Schritt gilt nicht für Emscripten.
Beispielcode für die Verwendung von EGL zur Initialisierung eines WebGL-Kontexts finden Sie in den Beispielanwendungen im Verzeichnis emscripten/test/third_party/glbook, genauer gesagt in der Datei esUtil.c.
Dieser Abschnitt listet alle EGL v1.4-Funktionen auf und beschreibt ihren aktuellen Implementierungsstatus in Emscripten.
eglInitialize, eglGetConfigs, eglQueryContext, eglQueryString, eglQuerySurface, eglGetCurrentContext, glGetCurrentSurface, eglGetCurrentDisplay, eglReleaseThread, eglDestroySurface, eglDestroyContext: Implementiert und sollte gemäß der EGL v1.4-Spezifikation funktionieren.
eglSwapBuffers: Implementiert, aber diese Funktion kann das Swap-Verhalten unter WebGL nicht wirklich steuern. Der Aufruf dieser Funktion ist unter Emscripten optional. In WebGL werden die Inhalte des Displays immer erst dann auf dem Bildschirm angezeigt, wenn der Code seine Ausführung an den Browser zurückgibt, d.h. wenn Sie von dem Tick-Callback-Handler zurückkehren, den Sie an emscripten_set_main_loop() übergeben haben. Die Funktion eglSwapBuffers kann jedoch weiterhin verwendet werden, um zu erkennen, wann ein GL-Kontextverlustereignis auftritt.
eglGetDisplay: Gemäß der Spezifikation implementiert. Emscripten verwendet keine mehreren EGLNativeDisplayType-Objekte, daher übergeben Sie hier EGL_DEFAULT_DISPLAY. Emscripten ignoriert derzeit tatsächlich jeden hier übergebenen Wert zu Zwecken der Linux-Emulation, aber Sie sollten sich in Zukunft nicht darauf verlassen.
eglGetError: Gemäß der Spezifikation implementiert.
Wichtig
Gemäß der Spezifikation meldet eglGetError den einzelnen letzten Fehler und nicht die Liste aller vorherigen Fehler. Rufen Sie diese Funktion nicht in einer Schleife auf, wie Sie glGetError aufrufen würden.
eglChooseConfig: Als Stub implementiert, aber diese Funktion führt keine Suche/Filterung durch und ist momentan identisch mit eglGetConfigs (Issue #643).
eglGetConfigAttrib: Implementiert. Abfragen der Attribute EGL_BUFFER_SIZE, EGL_ALPHA_SIZE, EGL_BLUE_SIZE, EGL_GREEN_SIZE, EGL_RED_SIZE, EGL_DEPTH_SIZE und EGL_STENCIL_SIZE geben derzeit festcodierte Standardwerte zurück (Issue #644). Die Attribute EGL_MIN_SWAP_INTERVAL und EGL_MAX_SWAP_INTERVAL haben derzeit keine Funktion. Rufen Sie stattdessen emscripten_set_main_loop() auf, um die Aktualisierungsrate der Hauptschleife anzugeben.
eglCreateWindowSurface: Implementiert, außer dass es nicht möglich ist, diese Funktion mehrmals aufzurufen, um mehrere Renderfenster zu erstellen.
eglCreateContext: Als Stub implementiert. Es ist nicht möglich, diese Funktion mehrmals aufzurufen, um mehrere Kontexte zu erstellen.
eglBindAPI, eglQueryAPI: Implementiert, obwohl diese Funktionen auf Emscripten wenig Nutzen haben, da nur die GLES2-Client-API unterstützt wird.
eglWaitClient, eglWaitNative: Als No-Op-Funktionen implementiert. Diese haben keine Bedeutung auf Emscripten.
eglSwapInterval: Als No-Op-Stub implementiert. Derzeit kann diese Funktion das VSync-Intervall nicht einstellen oder aktivieren/deaktivieren.
eglMakeCurrent: Als No-Op-Stub implementiert.
eglTerminate: Als No-Op-Funktions-Stub implementiert. JavaScript-Apps werden nicht oft manuell heruntergefahren, aber beim Schließen des Browsers oder Wechseln der Webseite verwaltet der Browser alle Aufräumarbeiten automatisch. Daher hat diese Funktion in Emscripten keine kritische Bedeutung.
eglGetProcAddress: Implementiert, experimentell.
Die folgenden Funktionen sind derzeit nicht implementiert
eglCreatePbufferSurface, eglCreatePixmapSurface, eglCreatePbufferFromClientBuffer, eglSurfaceAttrib, eglBindTexImage, eglReleaseTexImage, eglWaitGL, eglCopyBuffers.
Wichtig
Rufen Sie diese Funktionen in Emscripten-Code **nicht** auf, da die Anwendung sonst beim Versuch, eine undefinierte Funktion auszuführen, angehalten wird.
Derzeit implementiert Emscripten keine Erweiterungen im EGL Extension Registry.