kiss3d
kiss3d copied to clipboard
Support multiple WebGL contexts
Right now, kiss3d only supports rendering to a single <canvas>
element. I have a use case where I'd like to embed multiple instances of kiss3d on the same page (a blog post that goes through implementing a 3d simulation).
I've identified a few blockers:
-
WebGLCanvas always looks for a single canvas on the page (
#canvas
). This can be worked around on the JavaScript side by changing the id of the target canvas before creating the window, and then changing it back afterwards. - WebGLContext does the same thing. Now this one is more complicated to work around because kiss3d only ever keeps a single context in memory. One solution to this is to instantiate one WASM module per canvas (+ the trick for supporting multiple canvases).
- Mouse and keyboard events are relayed to all canvases because they all listen on window. As a temporary fix on my fork, I've added the following check inside the event handlers:
if e.target()
.and_then(|target| <CanvasElement>::try_from(target).ok())
.map_or(true, |canvas| canvas != edata.canvas)
{
return;
}
EDIT: For the last point, a better solution is to add event listeners to the canvas element directly (except for window resize / mouse up / mouse move (which needs to be modified to support the pointer leaving the canvas).
I just realized that the PR #207 I am working on is related to this issue, at least it solves the third point. The first two points however I don't have a need for them yet.
I do have a case of closing the existing Kiss3d window and opening a new window thus reusing the same canvas. It currently works but I do wonder how much memory is leaked from not cleaning up the canvas WebGL context properly. Keeping the context as a part of the Kiss3d canvas would allow for proper cleanup, or at least allow the canvas element to be removed to allow for the context to be garbage-collected.