|
<!DOCTYPE html> |
|
<meta charset="utf-8"> |
|
<canvas width="960" height="500"></canvas> |
|
<script id="vertex-shader" type="x-shader/x-vertex"> |
|
|
|
attribute vec2 a_position; |
|
|
|
uniform mat3 u_matrix; |
|
|
|
void main(void) { |
|
gl_Position = vec4((u_matrix * vec3(a_position, 1)).xy, 0, 1); |
|
} |
|
|
|
</script> |
|
<script id="fragment-shader" type="x-shader/x-fragment"> |
|
|
|
void main(void) { |
|
gl_FragColor = vec4(0, 1, 0, 1); |
|
} |
|
|
|
</script> |
|
<script> |
|
|
|
// Select the canvas from the document and extract its dimensions. |
|
var canvas = document.querySelector("canvas"), |
|
width = +canvas.getAttribute("width"), |
|
height = +canvas.getAttribute("height"); |
|
|
|
// Create the WebGL context, with fallback for experimental support. |
|
var context = canvas.getContext("webgl") |
|
|| canvas.getContext("experimental-webgl"); |
|
|
|
// Compile the vertex shader. |
|
var vertexShader = context.createShader(context.VERTEX_SHADER); |
|
context.shaderSource(vertexShader, document.querySelector("#vertex-shader").textContent); |
|
context.compileShader(vertexShader); |
|
if (!context.getShaderParameter(vertexShader, context.COMPILE_STATUS)) throw new Error(context.getShaderInfoLog(vertexShader)); |
|
|
|
// Compile the fragment shader. |
|
var fragmentShader = context.createShader(context.FRAGMENT_SHADER); |
|
context.shaderSource(fragmentShader, document.querySelector("#fragment-shader").textContent); |
|
context.compileShader(fragmentShader); |
|
if (!context.getShaderParameter(fragmentShader, context.COMPILE_STATUS)) throw new Error(context.getShaderInfoLog(fragmentShader)); |
|
|
|
// Link and use the program. |
|
var program = context.createProgram(); |
|
context.attachShader(program, vertexShader); |
|
context.attachShader(program, fragmentShader); |
|
context.linkProgram(program); |
|
if (!context.getProgramParameter(program, context.LINK_STATUS)) throw new Error(context.getProgramInfoLog(program)); |
|
context.useProgram(program); |
|
|
|
// Define the matrix transformation from normalized [±1,±1] to screen coordinates. |
|
var matrixUniform = context.getUniformLocation(program, "u_matrix"); |
|
context.uniformMatrix3fv(matrixUniform, false, [ |
|
2 / width, 0, 0, |
|
0, -2 / height, 0, |
|
-1, 1, 1 |
|
]); |
|
|
|
// Define the positions (as vec2) of the square that covers the canvas. |
|
var positionBuffer = context.createBuffer(); |
|
context.bindBuffer(context.ARRAY_BUFFER, positionBuffer); |
|
context.bufferData(context.ARRAY_BUFFER, new Float32Array([ |
|
0, 0, |
|
width, 0, |
|
width, height, |
|
0, height |
|
]), context.STATIC_DRAW); |
|
|
|
// Bind the position buffer to the position attribute. |
|
var positionAttribute = context.getAttribLocation(program, "a_position"); |
|
context.enableVertexAttribArray(positionAttribute); |
|
context.vertexAttribPointer(positionAttribute, 2, context.FLOAT, false, 0, 0); |
|
|
|
// Draw the square! |
|
context.drawArrays(context.TRIANGLE_FAN, 0, 4); |
|
|
|
</script> |
🙏