2

When gl.drawArrays is called sequentially, it draws over the top of the previous graphics on the canvas. However, when I put it inside a setInterval() it clears the canvas before redrawing.

code that draws the rectangles on top of each other:

for(var i =0; i < 10; i++) {
    setRectangle(gl, Math.random()*100, Math.random()*100, 20, 20);
    gl.drawArrays(gl.TRIANGLES, 0, 6); 
}

code that erases the canvas each time a new rectangle is drawn:

interval = setInterval(() => {
    setRectangle(gl, Math.random()*100, Math.random()*100, 20, 20);
    gl.drawArrays(gl.TRIANGLES, 0, 6); 
}, 500);

Here's a complete fiddle containing the above code.

I'm making a game that involves real time manipulation of a large image (using the phaser.js library for the game loop if that makes any difference). I would like to be able to just redraw only the needed portions of the image rather than redraw the entire image every animation cycle.

Why does the webgl canvas clear like this? Can I keep it from clearing?

  • Here's some answers the cover the same area. http://stackoverflow.com/questions/9491417/when-webgl-decide-to-update-the-display, http://stackoverflow.com/questions/27746091/preservedrawingbuffer-false-is-it-worth-the-effort, http://stackoverflow.com/questions/7156971/webgl-readpixels-is-always-returning-0-0-0-0, http://stackoverflow.com/questions/32556939/saving-canvas-to-image-via-canvas-todataurl-results-in-black-rectangle, http://stackoverflow.com/questions/27812153/why-is-renderingcontext-drawelements-clearing-the-screen-before-it-draws – gman Jan 17 '16 at 08:37

1 Answers1

1

Change line 51 to var gl = getWebGLContext(document.getElementById("canvas"), {preserveDrawingBuffer: true}); fiddle.

Warning: last time I checked turning this on for firefox will cause it to slow down considerably.

WacławJasper
  • 3,284
  • 14
  • 19
  • 1
    Aha! That's perfect. Dude, thanks! :) Followup question: why does `gl.preserveDrawingBuffer = true;` not work? – vaporizationator Jan 16 '16 at 20:34
  • What do you mean it not work? If you mean why you cant just set it on the gl context after it is created it is because it is a webgl specific thing and the webgl api is designed to mirror the opengl es api. Also its what the spec says https://www.khronos.org/registry/webgl/specs/latest/1.0/ search for `preserveDrawingBuffer` – WacławJasper Jan 16 '16 at 20:38
  • Yeah, that was my question. Thanks for the link, that's helpful. – vaporizationator Jan 16 '16 at 22:21
  • 1
    Begs the question of why is the buffer preserved in the for loop but not in the interval ... lowlevel #IDontKnowJavaScript question – Wylie Kulik Jun 11 '16 at 15:46
  • Section 2.2 of [the spec](https://www.khronos.org/registry/webgl/specs/latest/1.0/#2.2) covers when it's cleared. TL;DR it's cleared after being compositied – gman Mar 07 '18 at 11:31