Multiple Canvas in Typescript

Hi all

I’m trying to update my engine to show multiple scene and multiple canvas (one scene by canvas).
However, I got some issue during this update. That’s why I’m trying firstly to implement it in Playground.

I found the following existing Playground that I modified a bit: https://playground.babylonjs.com/#L1TX4W#27

Then, I tried to translate it in Typescript. However, I don’t succeed to make it works : https://playground.babylonjs.com/#LU92X9#18

I suppose there is some concept I don’t understand or I don’t know. Can you help me to do so ?

Brett

Perhaps @Evgeni_Popov can lend his expertise to this one?

You just forgot to add si = nofScene; at the end of refactorEngine:

https://playground.babylonjs.com/#LU92X9#19

1 Like

Thank you @Evgeni_Popov for the update, and sorry to not find it myself.

I updated my previous exemple because, as I said, I would like to use one engine with multiple canvas.

Here is the updated and working playground with 2 engines (the default one, plus ‘engine2’) and multiple canvas (the default one, plus the floatting-ones): https://playground.babylonjs.com/#LU92X9#33

Here is a non-working playground with 1 engine (only the default one) and multiple canvas : https://playground.babylonjs.com/#LU92X9#34
As you can see in the last example, all the sub canvas show the same render as the main canvas.

Brett

There are two things:

  • you should stop the default render loop before setting a new one
  • the canvas size is not correctly taken into account when rendering in the view canvas => problem in the engine

https://playground.babylonjs.com/#LU92X9#37

I have overcome the second problem by overriding the engine.resize method. However, I think we will need to find a better solution for this one.

To @Deltakosh:

The multi canvas code is doing this to set the parent canvas size to the size of the current view canvas:

parent.width = canvas.clientWidth;
parent.height = canvas.clientHeight;
this.resize(true);

Then, engine.resize is doing:

public resize(forceSetSize = false): void {
    let width: number;
    let height: number;

    if (DomManagement.IsWindowObjectExist()) {
        width = this._renderingCanvas ? (this._renderingCanvas.clientWidth || this._renderingCanvas.width) : window.innerWidth;
        height = this._renderingCanvas ? (this._renderingCanvas.clientHeight || this._renderingCanvas.height) : window.innerHeight;
    } else {
        width = this._renderingCanvas ? this._renderingCanvas.width : 100;
        height = this._renderingCanvas ? this._renderingCanvas.height : 100;
    }

    this.setSize(width / this._hardwareScalingLevel, height / this._hardwareScalingLevel, forceSetSize);
}

The thing is that this._renderingCanvas.clientWidth (and clientHeight) is still the old main canvas size, it is not updated with the value we set in width yet: I think it’s because we would need a roundtrip to the browser so that it updates clientWidth with the right value? So, we end up having the main rendering canvas still the same size and not updated with our view canvas size.

Maybe we should simply pass to engine.resize the width/height values we want to set when called from the multi view canvas code?

1 Like

Thank you @Evgeni_Popov
I set my current issue as solved and continue to play with multi canvas