Video Texture

You may use video files in place of image files. texImage2D() then fetches the current video frame for the texture image. For the video to play in the texture, texImage2D() must be called repeatedly.


flush() forces the execution of GL commands in finite time.

This example uses requestAnimationFrame() to call texImage2D() repeatedly.
RESETRUNFULL
<!DOCTYPE html><html><head>
<script src="/shared/webgl-library.js"></script>
<script id="shader-vs" type="x-shader/x-vertex">
   attribute vec4 a_Position;
   attribute vec2 a_TexCoord;
   varying vec2 v_TexCoord;
   void main() {
      gl_Position = a_Position;
      v_TexCoord = a_TexCoord;
   }
</script>
<script id="shader-fs" type="x-shader/x-fragment">
   #ifdef GL_ES
   precision mediump float;
   #endif
   uniform sampler2D u_Sampler;
   varying vec2 v_TexCoord;
   void main() {
      gl_FragColor = texture2D(u_Sampler, v_TexCoord);
   }
</script>
<script>
function WebGLStart() {
   var canvas = document.getElementById('cv');
   var gl = canvas.getContext('webgl');
   initShaders(gl, "shader-vs", "shader-fs");
   var n=initVertexBuffers(gl);
   gl.clearColor(0.0, 0.0, 0.0, 1.0);

   var bunny_video = document.createElement('video');
   bunny_video.src = '/shared/movie.webm';
   bunny_video.autoplay=true;
   
   var texture = gl.createTexture();
   gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);
   gl.bindTexture(gl.TEXTURE_2D,  texture);
   gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
   gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S,gl.CLAMP_TO_EDGE );
   gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T,gl.CLAMP_TO_EDGE );
   var refresh_texture = function (){
      gl.bindTexture(gl.TEXTURE_2D, texture);
      gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA,
                              gl.UNSIGNED_BYTE, bunny_video);
   }
   var animate = function (time){
      gl.clear(gl.COLOR_BUFFER_BIT);
      if (bunny_video.currentTime>0) {
         gl.activeTexture(gl.TEXTURE0);
         refresh_texture();
      }
      gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
      gl.flush();
      window.requestAnimationFrame(animate);
   }
   bunny_video.oncanplaythrough = ()=>animate(0);
}
function initVertexBuffers(gl) {
   var verticesTexCoords = new Float32Array([     // Vertex coordinate --> Texture coordinate
     -0.9, 0.9,   0.0, 1.0,
     -0.9,-0.9,   0.0, 0.0,
      0.9, 0.9,   1.0, 1.0,
      0.9,-0.9,   1.0, 0.0,
   ]);
   var n = 4;
   
   var vertexTexCoordBuffer = gl.createBuffer();
   gl.bindBuffer(gl.ARRAY_BUFFER, vertexTexCoordBuffer);
   gl.bufferData(gl.ARRAY_BUFFER, verticesTexCoords,gl.STATIC_DRAW);
   
   var FSIZE = verticesTexCoords.BYTES_PER_ELEMENT;
   
   var a_Position = gl.getAttribLocation(gl.program,'a_Position');
   gl.vertexAttribPointer(a_Position,2,gl.FLOAT,false,FSIZE*4, 0);
   gl.enableVertexAttribArray(a_Position);
  
   var a_TexCoord=gl.getAttribLocation(gl.program,'a_TexCoord');
   gl.vertexAttribPointer(a_TexCoord, 2, gl.FLOAT, false,FSIZE * 4, FSIZE * 2);
   gl.enableVertexAttribArray(a_TexCoord);
   
   return n;
}
</script>
</head>
<body>
   <button onclick="WebGLStart()">Start</button><br/>
   <canvas id="cv" style="border: none;" width="500" height="500"></canvas>
</body></html>