diff --git a/web/filament-js/extensions.js b/web/filament-js/extensions.js index 32d6938812..baaf47c7fc 100644 --- a/web/filament-js/extensions.js +++ b/web/filament-js/extensions.js @@ -73,16 +73,35 @@ Filament.loadClassExtensions = function() { // Create the WebGL 2.0 context. const ctx = canvas.getContext("webgl2", options); - Filament.glOptions = options; - Filament.glContext = ctx; // Enable all desired extensions by calling getExtension on each one. ctx.getExtension('WEBGL_compressed_texture_s3tc'); ctx.getExtension('WEBGL_compressed_texture_astc'); ctx.getExtension('WEBGL_compressed_texture_etc'); + // These transient globals are used temporarily during Engine construction. + window.filament_glOptions = options; + window.filament_glContext = ctx; + // Register the GL context with emscripten and create the Engine. - return Filament.Engine._create(); + const engine = Filament.Engine._create(); + + // Annotate the engine with the GL context to support multiple canvases. + engine.context = window.filament_glContext; + engine.handle = window.filament_contextHandle; + + // Ensure that we do not pollute the global namespace. + delete window.filament_glOptions; + delete window.filament_glContext; + delete window.filament_contextHandle; + + return engine; + }; + + Filament.Engine.prototype.execute = function() { + window.filament_contextHandle = this.handle; + this._execute(); + delete window.filament_contextHandle; }; /// createMaterial ::method:: diff --git a/web/filament-js/jsbindings.cpp b/web/filament-js/jsbindings.cpp index 33a7c27cc9..7ddcf6a781 100644 --- a/web/filament-js/jsbindings.cpp +++ b/web/filament-js/jsbindings.cpp @@ -472,16 +472,27 @@ register_vector("MaterialInstanceVector"); class_("Engine") .class_function("_create", (Engine* (*)()) [] { EM_ASM_INT({ - const handle = GL.registerContext(Filament.glContext, Filament.glOptions); + const options = window.filament_glOptions; + const context = window.filament_glContext; + const handle = GL.registerContext(context, options); + window.filament_contextHandle = handle; GL.makeContextCurrent(handle); }); return Engine::create(); }, allow_raw_pointers()) + + .function("_execute", EMBIND_LAMBDA(void, (Engine* engine), { + EM_ASM_INT({ + const handle = window.filament_contextHandle; + GL.makeContextCurrent(handle); + }); + engine->execute(); + }), allow_raw_pointers()) + /// destroy ::static method:: Destroys an engine instance and cleans up resources. /// engine ::argument:: the instance to destroy .class_function("destroy", (void (*)(Engine*)) [] (Engine* engine) { Engine::destroy(&engine); }, allow_raw_pointers()) - .function("execute", &Engine::execute) /// getTransformManager ::method:: /// ::retval:: an instance of [TransformManager]