Avatar

stwind

software engineer
2 public vals
Joined January 29, 2023

Testing WebGL

A minimal template for writing shaders.

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
export async function WebGLTest(request: Request): Promise<Response> {
const vs = `#version 300 es
precision highp float;
layout(location=0) in vec2 position;
layout(location=1) in vec2 texcoord;
out vec2 v_texcoord;
void main() {
v_texcoord = texcoord;
gl_Position = vec4(position, 0.0, 1.0);
}`;
const fs = `#version 300 es
precision highp float;
in vec2 v_texcoord;
layout(location=0) out vec4 fragColor;
void main() {
fragColor = vec4(v_texcoord, 1.,1.);
}`;
return new Response(
`
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0" />
<title>WebGL</title>
<style>
*,*::before,*::after {
box-sizing: border-box;
}
* {
margin: 0;
}
html,body {
overflow: hidden;
}
#canvas {
width: 100vw;
height: 100dvh;
touch-action: none;
}
</style>
</head>
<body>
<canvas id="canvas" />
<script>
"use strict";
const compileShader = (gl, type, source) => {
const shader = gl.createShader(type);
gl.shaderSource(shader, source);
gl.compileShader(shader);
if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
const msg = gl.getShaderInfoLog(shader);
gl.deleteShader(shader);
throw new Error(msg);
}
return shader;
};
const createProgram = (gl, vs, fs) => {
const vert = compileShader(gl, gl.VERTEX_SHADER, vs);
const frag = compileShader(gl, gl.FRAGMENT_SHADER, fs);
const program = gl.createProgram();
gl.attachShader(program, vert);
gl.attachShader(program, frag);
gl.linkProgram(program);
if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
const msg = gl.getProgramInfoLog(program);
gl.deleteProgram(program);
throw new Error(msg);
}
gl.detachShader(program, vert);
gl.deleteShader(vert);
gl.detachShader(program, frag);
gl.deleteShader(frag);
return program;
};
const canvas = document.getElementById("canvas");
const gl = canvas.getContext("webgl2", { antialias: true, alpha: true, powerPreference: "high-performance" });
const program = createProgram(gl, \`${vs}\`,\`${fs}\`);
gl.useProgram(program);
gl.bindBuffer(gl.ARRAY_BUFFER, gl.createBuffer());
gl.bufferData(gl.ARRAY_BUFFER, Float32Array.of(-1, 1, -1, -1, 1, 1, 1, -1), gl.STATIC_DRAW);
gl.enableVertexAttribArray(0);
gl.vertexAttribPointer(0, 2, gl.FLOAT, false, 0, 0);
gl.bindBuffer(gl.ARRAY_BUFFER, gl.createBuffer());
gl.bufferData(gl.ARRAY_BUFFER, Float32Array.of(0, 1, 0, 0, 1, 1, 1, 0), gl.STATIC_DRAW);
gl.enableVertexAttribArray(1);
gl.vertexAttribPointer(1, 2, gl.FLOAT, false, 0, 0);
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
const trio = {
substance: `
Set A
Label A $e=mc^2$
`,
style: `
canvas {
width = 150
height = 150
}
forall Set A {
center = (0, 0)
Circle {
center: center
r: 50
}
Equation {
center: center
string: A.label
}
}`,
domain: "type Set",
variation: "test",
};
export const penrose = (req: Request): Response =>
new Response(
`
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0" />
<title>WebGL</title>
<style>
*,*::before,*::after {
box-sizing: border-box;
}
* {
margin: 0;
}
</style>
</head>
<body>
<script type="importmap">{
"imports": {
"@penrose/core": "https://ga.jspm.io/npm:@penrose/core@3.2.0/dist/index.js"
},
"scopes": {
"https://ga.jspm.io/": {
"@datastructures-js/queue": "https://ga.jspm.io/npm:@datastructures-js/queue@4.2.3/index.js",
"@penrose/optimizer": "https://ga.jspm.io/npm:@penrose/optimizer@3.2.0/dist/index.js",
"consola": "https://ga.jspm.io/npm:consola@2.15.3/dist/consola.browser.js",
"crypto": "https://ga.jspm.io/npm:@jspm/core@2.0.1/nodelibs/browser/crypto.js",
"immutable": "https://ga.jspm.io/npm:immutable@4.3.1/dist/immutable.es.js",
"lodash": "https://ga.jspm.io/npm:lodash@4.17.21/lodash.js",
"mathjax-full/js/": "https://ga.jspm.io/npm:mathjax-full@3.2.2/js/",
"mhchemparser/dist/mhchemParser.js": "https://ga.jspm.io/npm:mhchemparser@4.2.1/dist/mhchemParser.js",
"moo": "https://ga.jspm.io/npm:moo@0.5.2/moo.js",
"nearley": "https://ga.jspm.io/npm:nearley@2.20.1/lib/nearley.js",
"poly-partition": "https://ga.jspm.io/npm:poly-partition@1.0.2/lib/index.js",
"seedrandom": "https://ga.jspm.io/npm:seedrandom@3.0.5/index.js",
"true-myth": "https://ga.jspm.io/npm:true-myth@4.1.1/dist/cjs/index.js"
}
}
}
</script>
<script type="module">
import { compile, optimize, toSVG, showError } from "@penrose/core";
const compiled = await compile(${JSON.stringify(trio)});
if (compiled.isErr()) console.error(showError(compiled.error));
const optimized = optimize(compiled.value);
if (optimized.isErr()) console.error(showError(optimized.error));
document.getElementById("penrose").appendChild(await toSVG(optimized.value));
</script>
<div id="penrose"></div>
</body>
</html>
`,
{ headers: { "Content-Type": "text/html" } },
);
Next