注記
この記事は現在作成中です。
Khronos GroupはEGLと呼ばれる仕様を公開しています。これは、(その他のタスクの中でも)グラフィックスコンテキストの作成、レンダリングサーフェスの管理、および異なるKhronos GroupグラフィックスAPI(OpenGL、OpenGL ES、OpenVG)間の相互運用性を処理するAPIです。詳細については、Khronos EGLウェブページを参照してください。
現在、EGLはオペレーティングシステム/グラフィックスドライバベンダー間で広く使用されているわけではありません。最も注目すべき採用例はAndroidアーキテクチャであり、そこでEGLはAndroid NDKを使用する場合の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
を1回以上呼び出して、目的のメインレンダリングターゲットパラメータを表すEGLConfig
を見つけます。EGLConfig
の属性を調べるには、eglGetConfigAttrib
を呼び出します。
この時点で、使用可能なプラットフォーム固有の関数(*X11*、*Win32 API*、*ANativeWindow*)を使用して、レンダリング先のネイティブウィンドウを設定します。Emscriptenの場合、このステップは適用されず、スキップできます。
有効なディスプレイとコンフィグパラメータを使用してeglCreateWindowSurface
を呼び出すことで、メインレンダリングターゲットサーフェース(EGLSurface
)を作成します。ウィンドウと属性リストパラメータをnullに設定します。
eglCreateContext
を呼び出してGLES2レンダリングコンテキスト(EGLContext
)を作成し、続いてeglMakeCurrent
を呼び出してレンダリングコンテキストをアクティブにします。コンテキストの作成時に、コンテキスト属性EGL_CONTEXT_CLIENT_VERSION == 2
を指定します。
これらの手順の後、メインGLES2レンダリングコンテキストを表すEGLオブジェクトEGLDisplay
、EGLConfig
、EGLSurface
、およびEGLContext
のセットが作成されます。
初期化解除時のクリーンアップシーケンスは次のとおりです。
eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT)
を呼び出すことで、現在アクティブなレンダリングコンテキストを解放します。
それを対象にeglDestroyContext
を呼び出すことで、EGLContext
オブジェクトを初期化解除します。
それらを対象にeglDestroySurface
を呼び出すことで、初期化されたすべてのEGLSurface
オブジェクトを破棄します。
eglTerminate(display)
を呼び出すことで、EGLを完全に初期化解除します。
ネイティブレンダリングウィンドウを削除します。このステップはEmscriptenには適用されません。
EGLを使用してWebGLコンテキストを初期化するためのサンプルコードは、emscripten/test/third_party/glbookディレクトリ、より具体的には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
: 実装されていますが、GLES2クライアントAPIのみがサポートされているため、Emscriptenではこれらの関数の有用性はほとんどありません。
eglWaitClient
、eglWaitNative
: ノーオペレーション関数として実装されています。Emscriptenではこれらは意味を持ちません。
eglSwapInterval
: ノーオペレーションスタブとして実装されています。現在、この関数はvsync間隔を設定したり、有効/無効にしたりすることはできません。
eglMakeCurrent
: ノーオペレーションスタブとして実装されています。
eglTerminate
: ノーオペレーション関数スタブとして実装されています。JavaScriptアプリケーションは手動でシャットダウンされることはあまりありませんが、ブラウザを閉じたり、ウェブページを切り替える際に、ブラウザがすべての終了処理を自動的に管理します。したがって、この関数はEmscriptenでは重要な意味を持ちません。
eglGetProcAddress
: 実装済み、実験段階。
現在、次の関数は実装されていません。
eglCreatePbufferSurface
、eglCreatePixmapSurface
、eglCreatePbufferFromClientBuffer
、eglSurfaceAttrib
、eglBindTexImage
、eglReleaseTexImage
、eglWaitGL
、eglCopyBuffers
。
重要
これらの関数をEmscriptenコードで呼び出さないでください。そうしないと、未定義関数の実行を試行した際にアプリケーションが停止します。
現在、EmscriptenはEGL Extension Registryの拡張機能を一切実装していません。