forked from ademch/WebGL
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.js
123 lines (101 loc) · 3.19 KB
/
main.js
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
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
import { SurfaceModel } from "./SurfaceModel.js";
import { ShaderProgram } from "./ShaderProgram.js";
let gl;
let surface;
let program;
let ball;
function getUVSteps() {
return {
u: Number.parseInt(document.getElementById("u-stepper").value, 10),
v: Number.parseInt(document.getElementById("v-stepper").value, 10),
};
}
function initSurface() {
const { u, v } = getUVSteps();
surface = new SurfaceModel("Richmond's Minimal Surface", u, v);
surface.createSurfaceData();
surface.initBuffer(gl);
}
function initShaderProgram() {
program = new ShaderProgram("Basic");
program.init(gl, vertexShaderSource, fragmentShaderSource);
program.use(gl);
}
function setupUIControls() {
const stepperTypes = ["u", "v"];
// biome-ignore lint/complexity/noForEach: <explanation>
stepperTypes.forEach((type) => {
const stepper = document.getElementById(`${type}-stepper`);
const counter = document.getElementById(`${type}-counter`);
if (!stepper) {
console.error(`Stepper element with id '${type}-stepper' not found`);
return;
}
stepper.addEventListener("input", (e) => {
if (counter) {
counter.textContent = e.target.value;
} else {
console.warn(`Counter element with id '${type}-counter' not found`);
}
initSurface();
draw();
});
});
}
function animateLight(time) {
const radius = 10.0;
const speed = 0.001;
const x = radius * Math.cos(time * speed);
const z = radius * Math.sin(time * speed);
const y = 5.0;
if (program) {
gl.uniform3f(program.lightDirectionUni, x, y, z);
draw();
}
requestAnimationFrame(animateLight);
}
function draw() {
gl.clearColor(1, 1, 1, 1);
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
const projection = m4.perspective(Math.PI / 8, 1, 0.1, 100);
const modelView = ball.getViewMatrix();
const rotateToPointZero = m4.axisRotation(
[Math.SQRT1_2, Math.SQRT1_2, 0],
0.7,
);
const translateToPointZero = m4.translation(0, 0, -10);
const matAcc0 = m4.multiply(rotateToPointZero, modelView);
const matAcc1 = m4.multiply(translateToPointZero, matAcc0);
const modelViewProjection = m4.multiply(projection, matAcc1);
gl.uniformMatrix4fv(program.matrixUni, false, modelViewProjection);
const normalMatrix = m4.transpose(m4.inverse(matAcc1));
gl.uniformMatrix4fv(program.normalMatrixUni, false, normalMatrix);
gl.uniform3fv(program.viewPositionUni, [0.0, 0.0, 5.0]);
gl.uniform3f(program.ambientColorUni, 0.2, 0.2, 0.2);
gl.uniform3f(program.diffuseColorUni, 0.7, 0.7, 0.7);
gl.uniform3f(program.specularColorUni, 1.0, 1.0, 1.0);
gl.uniform1f(program.shininessUni, 32.0);
surface.draw(gl, program);
}
function init() {
try {
const canvas = document.querySelector("canvas");
gl = canvas.getContext("webgl");
if (!gl) {
throw "Browser does not support WebGL";
}
ball = new TrackballRotator(canvas, draw, 0);
initShaderProgram();
initSurface();
gl.enable(gl.DEPTH_TEST);
setupUIControls();
draw();
animateLight(0);
} catch (e) {
console.error(`Initialization error: ${e}`);
const errorMessage = document.createElement("p");
errorMessage.textContent = `Sorry, could not initialize the WebGL graphics context: ${e}`;
document.body.appendChild(errorMessage);
}
}
document.addEventListener("DOMContentLoaded", init);