docs: function makePointsProgram(gl, data) {
    let vertexProgram = vertexProgramCache.get(gl)
    if (!vertexProgram) {
      let vertexShader = gl_utils.compile(gl, gl.VERTEX_SHADER, vertexShaderSrc);
      let fragmentShader = gl_utils.compile(gl, gl.FRAGMENT_SHADER, fragmentShaderSrc);
      vertexProgram = gl_utils.link(gl, vertexShader, fragmentShader);
      vertexProgramCache.set(gl, vertexProgram);
    }
  
    let locations = gl_utils.getLocations(gl, vertexProgram);
  
    var buffer = gl.createBuffer();
    if (!buffer) throw new Error('failed to create a nodesBuffer');
    gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
    gl.bufferData(gl.ARRAY_BUFFER, data.byteLength, gl.DYNAMIC_DRAW);
  
    var pointTexture = createCircleTexture(gl);
  
    var api = {
      draw,
      updateData,
      dispose
    };
    return api;
  
    function updateData(newData) {
      data = newData;
    }
  
    function dispose() {
      // For some reason disposing the buffer results in unbindable
      // buffer for the lines program (that is created after this scene is disposed).
      // gl.deleteBuffer(buffer);
      gl.deleteProgram(vertexProgram);
      gl.deleteTexture(pointTexture);
      vertexProgramCache.delete(gl);
    }
  
    function draw(transform, screen, count) {
      gl.useProgram(vertexProgram);
  
      var bpe = data.BYTES_PER_ELEMENT;
  
      if (transform) {
        gl.uniformMatrix4fv(locations.uniforms.uTransform, false, transform.getArray());
      }
      gl.uniform2f(locations.uniforms.uScreenSize, screen.width, screen.height);
      gl.bindTexture(gl.TEXTURE_2D, pointTexture);
  
      gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
      gl.bufferData(gl.ARRAY_BUFFER, data, gl.DYNAMIC_DRAW);
  
      gl.vertexAttribPointer(locations.attributes.aPosition, 2, gl.FLOAT, false, bpe * 6, 0)
      gl.enableVertexAttribArray(locations.attributes.aPosition)
  
      gl.vertexAttribPointer(locations.attributes.aPointSize, 1, gl.FLOAT, false, bpe * 6, 2 * bpe)
      gl.enableVertexAttribArray(locations.attributes.aPointSize)
  
      gl.vertexAttribPointer(locations.attributes.aColor, 3, gl.FLOAT, false, bpe * 6, 3 * bpe)
      gl.enableVertexAttribArray(locations.attributes.aColor);
      gl.drawArrays(gl.POINTS, 0, count);
    }
  }