]> git.r.bdr.sh - rbdr/lissajous/blob - lib/systems/webgl_renderer.js
8535fde64e6d073ec72d04f1f3d4e2c6bb7047a8
[rbdr/lissajous] / lib / systems / webgl_renderer.js
1 import { System } from '@serpentity/serpentity';
2 import Drawable from '../nodes/drawable';
3 import { initializeShaderProgram, initializeBuffers } from '../webgl_utils';
4
5 const internals = {
6 kWidthRatio: 2.76,
7 kHeightRatio: 1,
8 kTargetVerticalResolution: 32 + Math.round(Math.random() * 1024),
9 kVertexShader: `
10
11 attribute vec3 aVertexPosition;
12 void main() {
13 gl_Position = vec4(aVertexPosition.xy, 0.0, 1.0);
14 gl_PointSize = 10.0; // Set the point size
15 }
16 `,
17
18 kFragmentShader: `
19
20 precision mediump float;
21 uniform vec4 uColor;
22 void main() {
23 gl_FragColor = uColor;
24 }
25 `
26 };
27
28 export default class WebGLRenderer extends System {
29
30 constructor(canvasId) {
31
32 super();
33 this.canvasId = canvasId;
34 }
35
36 added(engine){
37
38 // Set up canvas
39 const canvas = document.getElementById(this.canvasId);
40 window.addEventListener('resize', () => this._resizeCanvas(canvas));
41
42 // Set up WebGL
43 const gl = canvas.getContext('webgl', {
44 preserveDrawingBuffer: true
45 });
46 this.gl = gl;
47
48 const shaderProgram = initializeShaderProgram(
49 gl,
50 internals.kVertexShader,
51 internals.kFragmentShader
52 );
53
54 this.programInfo = {
55 program: shaderProgram,
56 attribLocations: {
57 vertexPosition: gl.getAttribLocation(shaderProgram, 'aVertexPosition')
58 },
59 uniformLocations: {
60 color: gl.getUniformLocation(shaderProgram, 'uColor')
61 }
62 };
63
64 this.buffers = initializeBuffers(gl);
65 this._resizeCanvas(canvas);
66
67 this.points = engine.getNodes(Drawable);
68 }
69
70 removed(engine){
71
72 this.points = undefined;
73 }
74
75 update(){
76
77 const {gl, programInfo, buffers} = this;
78
79 gl.useProgram(programInfo.program);
80
81 {
82 const color = [1, 1, 1, 1];
83 gl.uniform4fv(programInfo.uniformLocations.color, color);
84 }
85
86 const positions = [];
87 for (const point of this.points) {
88 positions.push(point.position.x, point.position.y, point.position.z);
89 positions.push(
90 point.position.prevX || point.position.x,
91 point.position.prevY || point.position.y,
92 point.position.prevZ || point.position.z
93 );
94 point.position.prevX = point.position.x;
95 point.position.prevY = point.position.y;
96 point.position.prevZ = point.position.z;
97 }
98
99 gl.bindBuffer(gl.ARRAY_BUFFER, buffers.position);
100 gl.bufferData(gl.ARRAY_BUFFER,
101 new Float32Array(positions),
102 gl.STATIC_DRAW);
103
104 {
105 const numberOfComponents = 3;
106 const type = gl.FLOAT;
107 const normalize = false;
108 const stride = 0;
109 const offset = 0;
110
111 gl.bindBuffer(gl.ARRAY_BUFFER, buffers.position);
112 gl.vertexAttribPointer(
113 programInfo.attribLocations.vertexPosition,
114 numberOfComponents,
115 type,
116 normalize,
117 stride,
118 offset
119 );
120 gl.enableVertexAttribArray(programInfo.attribLocations.vertexPosition);
121 }
122
123 {
124 gl.lineWidth(2);
125 gl.drawArrays(gl.LINES, 0, this.points.nodes.length * 2);
126 }
127 }
128
129 _resizeCanvas(canvas) {
130
131 console.log('Resizing Canvas');
132 let width = window.innerWidth;
133 let height = Math.round(width * internals.kHeightRatio / internals.kWidthRatio);
134
135 if (window.innerHeight < height) {
136 height = window.innerHeight;
137 width = Math.round(height * internals.kWidthRatio / internals.kHeightRatio);
138 console.log(width, height);
139 }
140
141 canvas.style.width = `${width}px`;
142 canvas.style.height = `${height}px`;
143
144 canvas.width = internals.kTargetVerticalResolution * internals.kWidthRatio;
145 canvas.height = internals.kTargetVerticalResolution;
146
147 this.gl.viewport(0, 0, canvas.width, canvas.height);
148 }
149 };