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:
- I load my geometry
- I set up two
gl
context, one per canvas
- I call
drawElements
on the first context passing my geometry
- 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,
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?
That should have thrown an error. As Toji said, two WebGLContext
s cannot share resources. There is, however, a proposal for this. Check here. I suspect we'll see something similar in WebGL soon.
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.