Drawing in WebGL using preserveDrawingBuffer

by Gregg Tavares

HTML

<script src="https://twgljs.org/dist/4.x/twgl.js"></script>
<script id="2d-vertex-shader" type="foo">
attribute vec2 v_position;
uniform vec2 u_offset;
    
void main() {
    gl_Position = vec4(v_position + u_offset, 0, 1);
}
</script>
<script id="2d-fragment-shader" type="foo">
precision mediump float;
void main() {
    gl_FragColor = vec4(0, 1, 0, 1);  
}
</script>
<canvas id="canvas" width="400" height="300"></canvas>

CSS

canvas {
    border: 1px solid black;
}

JavaScript

main();
function main() {
    const canvas = document.getElementById("canvas");
    const gl = canvas.getContext("webgl", {preserveDrawingBuffer:true});
    if (!gl) {
        alert("no WebGL");
        return;
    }
    
    const program = twgl.createProgram(gl, ["2d-vertex-shader", "2d-fragment-shader"]);
    gl.useProgram(program);
    
    const positionLoc = gl.getAttribLocation(program, "v_position");
    const offsetLoc = gl.getUniformLocation(program, "u_offset");
    
    var res = 1;
    setupQuad(gl, res, positionLoc);
    
    canvas.addEventListener('mousemove', draw, false);
    
    function draw(event) {
      var info = getEventInfo(event);
      var m = getRelativeCoordinates(info);
      // convert mouse coords to clipspace since that's what this
      // particlar shader is using. See 
      // http://games.greggman.com/game/webgl-fundamentals/
      // for how to use pixels instead of clipspace. 
      var x = m.x / gl.canvas.width * 2 - 1;
      var y = m.y / gl.canvas.height * -2 + 1;  // flip y
        
      drawBrush(x, y);
    }
    
    function drawBrush(x, y) {
      gl.uniform2f(offsetLoc, x, y);
        
      gl.drawElements(gl.TRIANGLES, res * res * 6, gl.UNSIGNED_SHORT, 0);
    }
    
    drawBrush(0, 0);
    console.log(gl.getError());
}


function setupQuad(gl, gridRes, positionLoc) {
  var scale = 0.05;
  var objects = [];

  var vertsAcross = gridRes + 1;
  var numVerts = vertsAcross * vertsAcross;
  var positions = new Float32Array(numVerts * 2);
  var indices = new Uint16Array(6 * gridRes * gridRes);
  var poffset = 0;

  for (var zz = 0; zz <= gridRes; ++zz) {
    for (var xx = 0; xx <= gridRes; ++xx) {
      var u = xx / gridRes;
      var v = zz / gridRes;
      positions[poffset + 0] = (-1 + 2 * u) * scale;
      positions[poffset + 1] = (-1 + 2 * v) * scale;
      poffset += 2;
    }
  }
    
  var tbase = 0;
  for (var zz = 0; zz < gridRes; ++zz) {
    var index = zz * vertsAcross;
    for (var xx = 0; xx < gridRes;...