aboutsummaryrefslogtreecommitdiff
path: root/lib/systems/webgl_renderer.js
diff options
context:
space:
mode:
Diffstat (limited to 'lib/systems/webgl_renderer.js')
-rw-r--r--lib/systems/webgl_renderer.js149
1 files changed, 149 insertions, 0 deletions
diff --git a/lib/systems/webgl_renderer.js b/lib/systems/webgl_renderer.js
new file mode 100644
index 0000000..8535fde
--- /dev/null
+++ b/lib/systems/webgl_renderer.js
@@ -0,0 +1,149 @@
+import { System } from '@serpentity/serpentity';
+import Drawable from '../nodes/drawable';
+import { initializeShaderProgram, initializeBuffers } from '../webgl_utils';
+
+const internals = {
+ kWidthRatio: 2.76,
+ kHeightRatio: 1,
+ kTargetVerticalResolution: 32 + Math.round(Math.random() * 1024),
+ kVertexShader: `
+
+ attribute vec3 aVertexPosition;
+ void main() {
+ gl_Position = vec4(aVertexPosition.xy, 0.0, 1.0);
+ gl_PointSize = 10.0; // Set the point size
+ }
+ `,
+
+ kFragmentShader: `
+
+ precision mediump float;
+ uniform vec4 uColor;
+ void main() {
+ gl_FragColor = uColor;
+ }
+ `
+};
+
+export default class WebGLRenderer extends System {
+
+ constructor(canvasId) {
+
+ super();
+ this.canvasId = canvasId;
+ }
+
+ added(engine){
+
+ // Set up canvas
+ const canvas = document.getElementById(this.canvasId);
+ window.addEventListener('resize', () => this._resizeCanvas(canvas));
+
+ // Set up WebGL
+ const gl = canvas.getContext('webgl', {
+ preserveDrawingBuffer: true
+ });
+ this.gl = gl;
+
+ const shaderProgram = initializeShaderProgram(
+ gl,
+ internals.kVertexShader,
+ internals.kFragmentShader
+ );
+
+ this.programInfo = {
+ program: shaderProgram,
+ attribLocations: {
+ vertexPosition: gl.getAttribLocation(shaderProgram, 'aVertexPosition')
+ },
+ uniformLocations: {
+ color: gl.getUniformLocation(shaderProgram, 'uColor')
+ }
+ };
+
+ this.buffers = initializeBuffers(gl);
+ this._resizeCanvas(canvas);
+
+ this.points = engine.getNodes(Drawable);
+ }
+
+ removed(engine){
+
+ this.points = undefined;
+ }
+
+ update(){
+
+ const {gl, programInfo, buffers} = this;
+
+ gl.useProgram(programInfo.program);
+
+ {
+ const color = [1, 1, 1, 1];
+ gl.uniform4fv(programInfo.uniformLocations.color, color);
+ }
+
+ const positions = [];
+ for (const point of this.points) {
+ positions.push(point.position.x, point.position.y, point.position.z);
+ positions.push(
+ point.position.prevX || point.position.x,
+ point.position.prevY || point.position.y,
+ point.position.prevZ || point.position.z
+ );
+ point.position.prevX = point.position.x;
+ point.position.prevY = point.position.y;
+ point.position.prevZ = point.position.z;
+ }
+
+ gl.bindBuffer(gl.ARRAY_BUFFER, buffers.position);
+ gl.bufferData(gl.ARRAY_BUFFER,
+ new Float32Array(positions),
+ gl.STATIC_DRAW);
+
+ {
+ const numberOfComponents = 3;
+ const type = gl.FLOAT;
+ const normalize = false;
+ const stride = 0;
+ const offset = 0;
+
+ gl.bindBuffer(gl.ARRAY_BUFFER, buffers.position);
+ gl.vertexAttribPointer(
+ programInfo.attribLocations.vertexPosition,
+ numberOfComponents,
+ type,
+ normalize,
+ stride,
+ offset
+ );
+ gl.enableVertexAttribArray(programInfo.attribLocations.vertexPosition);
+ }
+
+ {
+ gl.lineWidth(2);
+ gl.drawArrays(gl.LINES, 0, this.points.nodes.length * 2);
+ }
+ }
+
+ _resizeCanvas(canvas) {
+
+ console.log('Resizing Canvas');
+ let width = window.innerWidth;
+ let height = Math.round(width * internals.kHeightRatio / internals.kWidthRatio);
+
+ if (window.innerHeight < height) {
+ height = window.innerHeight;
+ width = Math.round(height * internals.kWidthRatio / internals.kHeightRatio);
+ console.log(width, height);
+ }
+
+ canvas.style.width = `${width}px`;
+ canvas.style.height = `${height}px`;
+
+ canvas.width = internals.kTargetVerticalResolution * internals.kWidthRatio;
+ canvas.height = internals.kTargetVerticalResolution;
+
+ this.gl.viewport(0, 0, canvas.width, canvas.height);
+ }
+};