-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathTriangle.tsx
95 lines (79 loc) · 2.37 KB
/
Triangle.tsx
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
import { useEffect, useRef } from 'react';
import { Tucunare, mat4, vec4, FragmentShader, VertexShader } from 'tucunare';
import { MAX_CANVAS_SIZE } from '../constants';
export const Triangle = () => {
const canvasRef = useRef<HTMLCanvasElement>(null);
useEffect(() => {
if (!canvasRef.current) {
return;
}
const canvas = canvasRef.current;
const context = canvas.getContext('2d');
if (!context) {
return;
}
const resizeCanvas = () => {
canvas.width =
window.innerWidth < MAX_CANVAS_SIZE
? window.innerWidth
: MAX_CANVAS_SIZE;
canvas.height =
window.innerHeight < MAX_CANVAS_SIZE
? window.innerHeight
: MAX_CANVAS_SIZE;
};
resizeCanvas();
const tc = new Tucunare(canvas);
tc.setClearColor(0, 0, 0, 1);
tc.backFaceCullingEnabled = false;
let projectionMatrix: mat4;
const camera = new vec4(0, 0, 3, 1);
const viewMatrix = mat4.translate(-camera.x, -camera.y, -camera.z);
let rotation = 0;
const windowResized = () => {
resizeCanvas();
tc.resize();
projectionMatrix = mat4.perspectiveAspectRatio(
canvas.width / canvas.height,
75,
0.1,
1000,
);
};
window.onresize = windowResized;
windowResized();
const points = [
new vec4(-1, -1, 0, 1), // bottom left
new vec4(1, -1, 0, 1), // bottom right
new vec4(0, 1, 0, 1), // top middle
];
const colors = [
new vec4(1, 0, 0, 1), // red
new vec4(0, 1, 0, 1), // green
new vec4(0, 0, 1, 1), // blue
];
const draw = () => {
tc.clear();
const modelMatrix = mat4.rotateY(rotation);
const mvp = projectionMatrix.multiply(viewMatrix.multiply(modelMatrix));
const vertShader: VertexShader = (inputs) => ({
position: mvp.multiplyVec4(inputs.point as vec4),
outputs: {
color: inputs.color,
},
});
const fragShader: FragmentShader = (inputs) => inputs.color as vec4;
tc.drawTriangles(
{ point: points, color: colors },
vertShader,
fragShader,
);
// flush the buffer to the canvas
tc.flush();
rotation = (rotation + 1.5) % 360;
};
const interval = setInterval(draw, 1000 / 60);
return () => clearInterval(interval);
}, []);
return <canvas ref={canvasRef}></canvas>;
};