1<!DOCTYPE html>
2<head>
3<title>WebGL drawing</title>
4<style>
5canvas {
6 width: 100px;
7 height: 100px;
8}
9</style>
10</head>
11<script id="vertexShaderSource" type="text/glsl">
12attribute vec4 a_position;
13varying vec2 v_texturePosition;
14
15void main() {
16 v_texturePosition = vec2((a_position.x + 1.0) / 2.0, (a_position.y + 1.0) / 2.0);
17 gl_Position = a_position;
18}
19</script>
20<script id="fragmentShaderSource" type="text/glsl">
21precision mediump float;
22
23varying vec2 v_texturePosition;
24
25uniform sampler2D texture;
26
27void main() {
28 gl_FragColor = texture2D(texture, v_texturePosition);
29}
30</script>
31<script>
32let texture;
33let gl;
34let textureUniform;
35let NUMBER_OF_PAINTS_REMAINING = 60;
36
37function signalReady() {
38 window.location = "callback:isReady";
39}
40
41function signalFinished() {
42 window.location = "callback:didFinishPainting";
43}
44
45function loadColorIntoTexture(r, g, b, a) {
46 gl.bindTexture(gl.TEXTURE_2D, texture);
47 gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, new Uint8Array([r, g, b, a]));
48}
49
50function draw() {
51 gl.clear(gl.COLOR_BUFFER_BIT);
52
53 gl.activeTexture(gl.TEXTURE0);
54 gl.bindTexture(gl.TEXTURE_2D, texture);
55
56 gl.drawArrays(gl.TRIANGLES, 0, 6);
57
58 if (NUMBER_OF_PAINTS_REMAINING--) {
59 window.requestAnimationFrame(draw);
60 } else {
61 signalFinished();
62 }
63};
64
65function run() {
66
67 let canvas = document.querySelector("canvas");
68 canvas.width = 100;
69 canvas.height = 100;
70
71 gl = canvas.getContext("webgl");
72
73 gl.clearColor(0, 0, 1, 1);
74
75 let vertexShader = gl.createShader(gl.VERTEX_SHADER);
76
77 gl.shaderSource(vertexShader, document.getElementById("vertexShaderSource").textContent);
78
79 gl.compileShader(vertexShader);
80 if (!gl.getShaderParameter(vertexShader, gl.COMPILE_STATUS)) {
81 // We failed to compile. Output to the console and quit.
82 console.error("Vertex Shader failed to compile.");
83 console.log(gl.getShaderInfoLog(vertexShader));
84 return;
85 }
86
87 let fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
88 gl.shaderSource(fragmentShader, document.getElementById("fragmentShaderSource").textContent);
89 gl.compileShader(fragmentShader);
90 if (!gl.getShaderParameter(fragmentShader, gl.COMPILE_STATUS)) {
91 console.error("Fragment Shader failed to compile.");
92 console.log(gl.getShaderInfoLog(fragmentShader));
93 return;
94 }
95
96 let program = gl.createProgram();
97 gl.attachShader(program, vertexShader);
98 gl.attachShader(program, fragmentShader);
99 gl.linkProgram(program);
100
101 if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
102 console.error("Unable to link shaders into program.");
103 return;
104 }
105
106 gl.useProgram(program);
107
108 let textureUniform = gl.getUniformLocation(program, "texture");
109
110 let positionAttribute = gl.getAttribLocation(program, "a_position");
111 gl.enableVertexAttribArray(positionAttribute);
112
113 let vertices = new Float32Array([
114 -1, -1,
115 1, -1,
116 1, 1,
117 1, 1,
118 -1, 1,
119 -1, -1
120 ]);
121
122 let quadBuffer = gl.createBuffer();
123
124 gl.bindBuffer(gl.ARRAY_BUFFER, quadBuffer);
125 gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);
126
127 texture = gl.createTexture();
128 loadColorIntoTexture(0, 128, 255, 255);
129
130 gl.bindBuffer(gl.ARRAY_BUFFER, quadBuffer);
131 gl.vertexAttribPointer(positionAttribute, 2, gl.FLOAT, false, 0, 0);
132
133 gl.uniform1i(textureUniform, 0);
134
135 signalReady();
136}
137
138window.addEventListener("load", run, false);
139</script>
140<body>
141 <canvas></canvas>
142</body>