Is it possible to have two WebGL contexts on the s

2020-02-26 04:59发布

问题:

I am trying to draw the same WebGL scene using two canvases side-by-side. Is it possible? So far I haven't been lucky.

The idea goes as follows:

  1. I load my geometry
  2. I set up two gl context, one per canvas
  3. I call drawElements on the first context passing my geometry
  4. I call drawElements on the second context passing my geometry

Results: Only the first invocation is successful. The second context executes gl.clear correctly but no geometry is displayed.

What am I missing? is this a spec constrain? or a limitation in the Firefox and Safari's implementations?

Thanks,

回答1:

Yes, you can have more than one WebGL context on a page, but each context must manage it's own resources. You cannot create buffers or textures on one context and then use them on the other, so to use this approach if you wanted to render the same scene you would need to load all your resources twice.

That's certainly doable, but it will be very memory intensive (as you might imagine). A better solution would be to create a context that is 2x the width you need and use gl.viewport and gl.scissor to render to half of it for each view of the scene.

Or, make a full viewport size canvas and use the scissor/viewport settings to match other html elements. See this Q&A: How can we have display of same objects in two canvas in webgl?



回答2:

That should have thrown an error. As Toji said, two WebGLContexts cannot share resources. There is, however, a proposal for this. Check here. I suspect we'll see something similar in WebGL soon.



回答3:

I use multiple WebGL contexts on a single page by assigning the same class to the canvasses that should render the WebGL content, and putting something specific in the canvas inner html:

function specific(what) {
    switch (what) {
    case 'front':
        //do something
        break;
    case 'side':
        //do something else
        break;
    }
}

function webGLStart() {
    var canvasArray = document.getElementsByClassName("webGLcanvas");
    for (var index = 0; index < canvasArray.length; ++index) {
        initWebGlContext();
        specific(canvasArray[index].innerHTML);
    }
}

</script>
</head>

<body onload="webGLStart();">
    <canvas class="webGLcanvas">front</canvas>
    <canvas class="webGLcanvas">side</canvas>
</body>

You can find a working example here.

As earlier answers (Toji and Chris Broadfoot) explained, you need to keep in mind that you cannot share resources between WebGL contexts.

edit: code is now available on github.



标签: webgl