113 lines
4.3 KiB
HTML
113 lines
4.3 KiB
HTML
<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>
|