| <style> |
| canvas { |
| width: 100px; |
| height: 100px; |
| border: 1px green solid; |
| } |
| </style> |
| <body> |
| <p>Ensure if an image buffer is reused for a webgl texture, it will be cleared before drawing.</p> |
| <canvas width="100" height="100"></canvas> |
| <script> |
| (function() { |
| const canvas = document.querySelector('canvas'); |
| const gl = canvas.getContext("webgl"); |
| const program = createProgram(gl); |
| gl.useProgram(program); |
| |
| createTextureBuffer(program, gl, new Float32Array([ 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1]), "a_texCoord"); |
| |
| const images = [ |
| 'data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" height="100" width="100"><rect width="100%" height="100%" fill="green"/></svg>', |
| 'data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" height="100" width="100"><rect x="25%" y="25%" width="50%" height="50%" fill="green"/></svg>', |
| ]; |
| |
| const promises = []; |
| for (var index = 0; index < images.length; ++index) |
| promises.push(drawTexture(program, gl, images[index])); |
| |
| if (window.testRunner) { |
| testRunner.waitUntilDone(); |
| Promise.all(promises).then(() => { |
| testRunner.notifyDone(); |
| }); |
| } |
| })(); |
| |
| function createProgram(gl) { |
| const vsSource = ` |
| attribute vec4 a_position; |
| uniform vec2 u_resolution; |
| attribute vec2 a_texCoord; |
| varying vec2 v_texCoord; |
| |
| void main() { |
| gl_Position = a_position; |
| v_texCoord = a_texCoord; |
| } |
| `; |
| |
| const fsSource = ` |
| precision mediump float; |
| |
| uniform sampler2D u_sampler; |
| varying vec2 v_texCoord; |
| |
| void main() { |
| gl_FragColor = texture2D(u_sampler, v_texCoord); |
| } |
| `; |
| |
| const vertexShader = loadShader(gl, gl.VERTEX_SHADER, vsSource); |
| const fragmentShader = loadShader(gl, gl.FRAGMENT_SHADER, fsSource); |
| |
| const program = gl.createProgram(); |
| gl.attachShader(program, vertexShader); |
| gl.attachShader(program, fragmentShader); |
| gl.linkProgram(program); |
| return program; |
| } |
| |
| function loadShader(gl, type, source) { |
| const shader = gl.createShader(type); |
| gl.shaderSource(shader, source); |
| gl.compileShader(shader); |
| return shader; |
| } |
| |
| function drawTexture(program, gl, url) { |
| return loadTexture(gl, url).then(function() { |
| createTextureBuffer(program, gl, new Float32Array([-1, -1, 1, -1, -1, 1, -1, 1, 1, -1, 1, 1]), "a_position"); |
| gl.drawArrays(gl.TRIANGLES, 0, 6); |
| }); |
| } |
| |
| function loadTexture(gl, url) { |
| return new Promise((resolve) => { |
| const image = new Image(); |
| image.onload = function() { |
| const texture = gl.createTexture(); |
| gl.bindTexture(gl.TEXTURE_2D, texture); |
| gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image); |
| 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); |
| gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR); |
| gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR); |
| resolve(); |
| }; |
| image.src = url; |
| }); |
| } |
| |
| function createTextureBuffer(program, gl, bufferData, positionAttribute) { |
| const buffer = gl.createBuffer(); |
| gl.bindBuffer(gl.ARRAY_BUFFER, buffer); |
| gl.bufferData(gl.ARRAY_BUFFER, bufferData, gl.STATIC_DRAW); |
| |
| const positionLocation = gl.getAttribLocation(program, positionAttribute); |
| gl.enableVertexAttribArray(positionLocation); |
| gl.vertexAttribPointer(positionLocation, 2, gl.FLOAT, false, 0, 0); |
| } |
| </script> |
| </body> |