| <canvas width="100" height="100"></canvas> |
| <script> |
| if (window.testRunner) |
| testRunner.dumpAsText(); |
| |
| window.addEventListener("load", function () { |
| const canvas = document.querySelector("canvas"); |
| const gl = canvas.getContext("webgl"); |
| |
| const halfWidth = canvas.width / 2; |
| const halfHeight = canvas.height / 2; |
| |
| function output(txt) { |
| const div = document.createElement("div"); |
| div.textContent = txt; |
| document.body.appendChild(div); |
| } |
| |
| function createShader(type, src) { |
| const shader = gl.createShader(type); |
| gl.shaderSource(shader, src); |
| gl.compileShader(shader); |
| return shader; |
| } |
| |
| function createProgram(vsSrc, fsSrc) { |
| const program = gl.createProgram(); |
| const vs = createShader(gl.VERTEX_SHADER, vsSrc); |
| const fs = createShader(gl.FRAGMENT_SHADER, fsSrc); |
| gl.attachShader(program, vs); |
| gl.attachShader(program, fs); |
| gl.bindAttribLocation(program, 0, 'pos'); |
| gl.linkProgram(program); |
| gl.deleteShader(vs); |
| gl.deleteShader(fs); |
| return program; |
| } |
| |
| const buffer = gl.createBuffer(); |
| gl.bindBuffer(gl.ARRAY_BUFFER, buffer); |
| gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([-3, 1, 1, 1, 1, -3]), gl.STATIC_DRAW); |
| |
| gl.enableVertexAttribArray(0); |
| gl.vertexAttribPointer(0, 2, gl.FLOAT, false, 0, 0); |
| |
| const p1 = createProgram(` |
| attribute vec2 pos; |
| void main(void) { |
| gl_Position = vec4(pos, 0, 1); |
| } |
| `, ` |
| precision mediump float; |
| void main(void) { |
| mat4 m; |
| gl_FragColor = m[0]; |
| } |
| `); |
| |
| gl.useProgram(p1); |
| gl.viewport(0, 0, halfWidth, halfHeight); |
| gl.drawArrays(gl.TRIANGLES, 0, 3); |
| |
| const p2 = createProgram(` |
| attribute vec2 pos; |
| void main(void) { |
| gl_Position = vec4(pos, 0, 1); |
| } |
| `, ` |
| precision mediump float; |
| void main(void) { |
| vec4 v; |
| gl_FragColor = v; |
| } |
| `); |
| |
| gl.useProgram(p2); |
| gl.viewport(0, halfHeight, halfWidth, halfHeight); |
| gl.drawArrays(gl.TRIANGLES, 0, 3); |
| |
| const p3 = createProgram(` |
| attribute vec2 pos; |
| void main(void) { |
| gl_Position = vec4(pos, 0, 1); |
| } |
| `, ` |
| precision mediump float; |
| void main(void) { |
| float s; |
| gl_FragColor = vec4(s, s, s, s); |
| } |
| `); |
| |
| gl.useProgram(p3); |
| gl.viewport(halfWidth, halfHeight, halfWidth, halfHeight); |
| gl.drawArrays(gl.TRIANGLES, 0, 3); |
| |
| const p4 = createProgram(` |
| attribute vec2 pos; |
| void main(void) { |
| gl_Position = vec4(pos, 0, 1); |
| } |
| `, ` |
| precision mediump float; |
| void main(void) { |
| vec2 v; |
| gl_FragColor = vec4(v.x, v.y, v.x + v.y, v.x + v.y); |
| } |
| `); |
| |
| gl.useProgram(p4); |
| gl.viewport(halfWidth, 0, halfWidth, halfHeight); |
| gl.drawArrays(gl.TRIANGLES, 0, 3); |
| |
| let pixels = new Uint8Array(canvas.width * canvas.height * 4); |
| gl.readPixels(0, 0, canvas.width, canvas.height, gl.RGBA, gl.UNSIGNED_BYTE, pixels); |
| let seenNoise = false; |
| pixels.forEach(pixel => { |
| if (pixel) { |
| seenNoise = true; |
| } |
| }); |
| output(seenNoise ? "FAIL: Unitialized values detected" : "PASS"); |
| }, false); |
| </script> |