title: Clearing WebGL context for new program
body: <p>So what I am trying to do is creating one canvas which can serve different user programs (i.e., not only new shaders, but new objects, transformations, etc.). By clicking on the program the current WebGL context should be cleared and a completely new program loaded into the old context. That is my current approach and I am not sure if it's feasible.. any advice on that?</p>
  
  <p>For now, whenever a new program is selected, javascript will discard the old program.js and append a new one into the DOM. I have been trying to clean up the context (unbinding buffers and textures) after the user changes to a new program. However I have been encountered with side effects due to asynchronous execution of javascript: after unloading the buffers there are still draw calls left from the old program. For now I am also unaware, if it is possible to clean the old uniforms and attributes.</p>
  
  <p>Is what I am trying to do possible? Or should I create a whole new canvas and context whenever a program is changed? My guess would be that this would fill up the memory quite fast. What would you guys say is the best approach for my idea?</p>
  
  <p>EDIT: I give you a quick overview how my program functions for now.</p>
  
  <p>The initial init() function that is only called once:</p>
  
  <pre><code>var select = document.getElementById('program-list');
  userProgram = select.options[select.selectedIndex].value;
  
  console.log('Initializing WebGL with user program: ' + userProgram);
  
  canvas = document.getElementById('graphics-surface');
  gl = canvas.getContext('webgl'); // create GL context
  
  if (!gl) {
      console.log('WebGL not supported, falling back on experimental-webgl');
      gl = canvas.getContext('experimental-webgl');
      alert('Your browser does not support WegGL.');
  }
  
  gl.clearColor(0.0, 0.0, 0.0, 1.0);
  gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
  
  gl.enable(gl.DEPTH_TEST);
  gl.enable(gl.CULL_FACE);
  gl.frontFace(gl.CCW);
  gl.cullFace(gl.BACK);
  
  RunDemo(userProgram);
  </code></pre>
  
  <p>So actually a program.js is what will get delted and a new program2.js appended as a  onchange in a HTML ≤select>.</p>
  
  <pre><code>var changeProgram = function (elem) {
  
     changing = true;
  
     CleanUpDemo();
  
     document.getElementById('program-src').remove();
     console.log('program removed');
  
     userProgram = elem.value;
     appendSrc(userProgram);
  
     switch (userProgram) {
         ...
     }
  
     changing = false;
     RunDemo(userProgram);
  };
  </code></pre>
  
  <p>The cleanup function in program.js:</p>
  
  <pre><code>gl.bindTexture(gl.TEXTURE_2D, null);
  gl.bindBuffer(gl.ARRAY_BUFFER, null);
  gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null);
  gl.bindRenderbuffer(gl.RENDERBUFFER, null);
  gl.bindFramebuffer(gl.FRAMEBUFFER, null);
  
  gl.deleteTexture(texture);
  gl.deleteBuffer(vbo);
  gl.deleteBuffer(ibo);
  gl.deleteBuffer(normalsBuffer);
  gl.deleteRenderbuffer(someRenderbuffer);
  gl.deleteFramebuffer(someFramebuffer);
  gl.deleteProgram(program);
  gl.deleteShader(fragmentShader);
  gl.deleteShader(vertexShader);
  </code></pre>
  
  <p>A program will look like this:</p>
  
  <pre><code>var InitProgram = function () {
     ... // meshes, textures and shaders are loaded from file and passed to RunProgram()
     RunProgram(vshText, fshText, img, modelObj);
  };
  
  var RunProgram = function (vertexShaderText, fragmentShaderText, textureImg, modelFile) {
      ... // load shaders, meshes, textures, attribs and uniforms to gpu
      var loop = function () {
          if(!changing) { // added this flag to help with asynchronous calls, doesn't work of course
              gl.drawElements(gl.TRIANGLES, indices.length, gl.UNSIGNED_SHORT, 0);
          }
          requestAnimationFrame(loop);
      }
      requestAnimationFrame(loop);
  };
  </code></pre>
  
  <p>2nd EDIT: Here is a screenshot from my UI
  <a href="https://i.stack.imgur.com/3ArTf.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/3ArTf.png" alt="enter image description here"></a></p>