WebGL: support for multiple <canvas> elements.

We now annotate the JS wrapper for Engine with a GL context handle.

This is fairly hacky because emscripten hides its internal GL object
from JavaScript, and it does not provide a mechanism to pass JS objects
into inline assembly.
This commit is contained in:
Philip Rideout
2021-04-02 12:26:56 -07:00
parent 7d604cd05b
commit c2fabbf9d9
2 changed files with 35 additions and 5 deletions

View File

@@ -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::

View File

@@ -472,16 +472,27 @@ register_vector<const MaterialInstance*>("MaterialInstanceVector");
class_<Engine>("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]