-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtest.html
More file actions
108 lines (93 loc) · 3.35 KB
/
Copy pathtest.html
File metadata and controls
108 lines (93 loc) · 3.35 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
<canvas id="canvas" width="400" height="400"></canvas>
<script>
const canvas = document.getElementById('canvas');
/** @type {WebGLRenderingContext} */
const gl = canvas.getContext('webgl');
if (!gl) throw new Error('WebGL not supported');
const vshader = `
attribute vec2 a_position; // x, y (clip-space -1..1)
attribute float a_pointSize; // size in pixels
attribute vec3 a_color; // r,g,b
varying vec3 v_color;
void main() {
gl_Position = vec4(a_position, 0.0, 1.0);
gl_PointSize = a_pointSize;
v_color = a_color;
}
`;
const fshader = `
precision mediump float;
varying vec3 v_color;
void main() {
gl_FragColor = vec4(v_color, 1.0);
}
`;
function compileShader(src, type) {
const s = gl.createShader(type);
gl.shaderSource(s, src);
gl.compileShader(s);
if (!gl.getShaderParameter(s, gl.COMPILE_STATUS)) {
console.error(gl.getShaderInfoLog(s));
throw new Error('Shader compile failed');
}
return s;
}
const vs = compileShader(vshader, gl.VERTEX_SHADER);
const fs = compileShader(fshader, gl.FRAGMENT_SHADER);
const program = gl.createProgram();
gl.attachShader(program, vs);
gl.attachShader(program, fs);
gl.linkProgram(program);
if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
throw new Error('Program link failed: ' + gl.getProgramInfoLog(program));
}
gl.useProgram(program);
// Attribute locations
const posLoc = gl.getAttribLocation(program, 'a_position');
const sizeLoc = gl.getAttribLocation(program, 'a_pointSize');
const colLoc = gl.getAttribLocation(program, 'a_color');
// Create interleaved buffer
const POINT_COUNT = 200;
const componentsPerVertex = 6; // 2 + 1 + 3
const data = new Float32Array(POINT_COUNT * componentsPerVertex);
for (let i = 0; i < POINT_COUNT; ++i) {
const base = i * componentsPerVertex;
data[base + 0] = (Math.random() * 2 - 1); // x
data[base + 1] = (Math.random() * 2 - 1); // y
data[base + 2] = 4 + Math.random() * 20; // size
data[base + 3] = Math.random(); // r
data[base + 4] = Math.random(); // g
data[base + 5] = Math.random(); // b
}
const vbo = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, vbo);
gl.bufferData(gl.ARRAY_BUFFER, data, gl.DYNAMIC_DRAW);
const FLOAT_SIZE = 4;
const stride = componentsPerVertex * FLOAT_SIZE;
// position: 2 floats, offset 0
gl.enableVertexAttribArray(posLoc);
gl.vertexAttribPointer(posLoc, 2, gl.FLOAT, false, stride, 0);
// size: 1 float, offset after 2 floats
gl.enableVertexAttribArray(sizeLoc);
gl.vertexAttribPointer(sizeLoc, 1, gl.FLOAT, false, stride, 2 * FLOAT_SIZE);
// color: 3 floats, offset after 3 floats (2 pos + 1 size)
gl.enableVertexAttribArray(colLoc);
gl.vertexAttribPointer(colLoc, 3, gl.FLOAT, false, stride, 3 * FLOAT_SIZE);
gl.viewport(0, 0, gl.canvas.width, gl.canvas.height);
gl.clearColor(0.0, 0.0, 0.0, 1.0);
gl.clear(gl.COLOR_BUFFER_BIT);
gl.drawArrays(gl.POINTS, 0, POINT_COUNT);
function animate() {
for (let i = 0; i < POINT_COUNT; ++i) {
const base = i * componentsPerVertex;
data[base + 0] += 0.002 * (Math.sin(i + performance.now() * 0.001));
if (data[base + 0] > 1.2) data[base + 0] = -1.2;
}
gl.bindBuffer(gl.ARRAY_BUFFER, vbo);
gl.bufferSubData(gl.ARRAY_BUFFER, 0, data);
gl.clear(gl.COLOR_BUFFER_BIT);
gl.drawArrays(gl.LINE_STRIP, 0, POINT_COUNT);
requestAnimationFrame(animate);
}
requestAnimationFrame(animate);
</script>