5 kEntrypointElementId: 'entrypoint', // The id of the canvas element where we will render
8 kTargetVerticalResolution: 32 + Math
.round(Math
.random() * 1024),
12 kBackgroundColor: [0.811, 0.73, 0.48, 1.0],
13 kRotationValues: [Math
.random(), Math
.random(), Math
.random()],
20 attribute vec4 aVertexPosition;
21 attribute vec4 aColor;
25 uniform mat4 uModelViewMatrix;
26 uniform mat4 uProjectionMatrix;
30 gl_Position = uProjectionMatrix * uModelViewMatrix * aVertexPosition;
37 precision mediump float;
42 gl_FragColor = vColor;
46 // Properties: Animation
50 // Runs on load, Initializes WebGL and starts the animation loop.
55 const canvas
= internals
.initializeCanvas();
56 const {gl
, programInfo
, buffers
} = internals
.initializeWebGL(canvas
);
58 window
.requestAnimationFrame(internals
.animate
.bind(this, gl
, programInfo
, buffers
));
61 // Gets a canvas element and sets up resizing events.
65 const canvas
= document
.getElementById(internals
.kEntrypointElementId
);
66 internals
.resizeCanvas(canvas
);
67 window
.addEventListener('resize', () => internals
.resizeCanvas(canvas
));
72 // Given a canvas, it will initialize the webgl context and set up the shaders.
74 initializeWebGL(canvas
) {
76 const gl
= canvas
.getContext('webgl', {
77 preserveDrawingBuffer: true
79 const shaderProgram
= internals
.initializeShaderProgram(gl
, internals
.kVertexShader
, internals
.kFragmentShader
);
82 program: shaderProgram
,
84 vertexPosition: gl
.getAttribLocation(shaderProgram
, 'aVertexPosition'),
85 vertexColor: gl
.getAttribLocation(shaderProgram
, 'aColor')
88 projectionMatrix: gl
.getUniformLocation(shaderProgram
, 'uProjectionMatrix'),
89 modelViewMatrix: gl
.getUniformLocation(shaderProgram
, 'uModelViewMatrix')
93 const buffers
= internals
.initializeBuffers(gl
);
95 return { gl
, programInfo
, buffers
};
100 resizeCanvas(canvas
) {
102 let width
= window
.innerWidth
;
103 let height
= Math
.round(width
* internals
.kHeightRatio
/ internals
.kWidthRatio
);
105 if (window
.innerHeight
< height
) {
106 height
= window
.innerHeight
;
107 width
= Math
.round(height
* internals
.kWidthRatio
/ internals
.kHeightRatio
);
108 console
.log(width
, height
);
111 canvas
.style
.width
= `${width}px`;
112 canvas
.style
.height
= `${height}px`;
114 canvas
.width
= internals
.kTargetVerticalResolution
* internals
.kWidthRatio
;
115 canvas
.height
= internals
.kTargetVerticalResolution
;
118 // Methods: Shader / GL Related
120 initializeShaderProgram(gl
, vertexShaderSource
, fragmentShaderSource
) {
122 const vertexShader
= internals
.loadShader(gl
, gl
.VERTEX_SHADER
, vertexShaderSource
);
123 const fragmentShader
= internals
.loadShader(gl
, gl
.FRAGMENT_SHADER
, fragmentShaderSource
);
125 const shaderProgram
= gl
.createProgram();
126 gl
.attachShader(shaderProgram
, vertexShader
);
127 gl
.attachShader(shaderProgram
, fragmentShader
);
129 gl
.linkProgram(shaderProgram
);
131 if (!gl
.getProgramParameter(shaderProgram
, gl
.LINK_STATUS
)) {
132 alert(`Unable to initialize shader program: ${gl.getProgramInfoLog(shaderProgram)}`);
136 return shaderProgram
;
139 loadShader(gl
, type
, source
) {
141 const shader
= gl
.createShader(type
);
142 gl
.shaderSource(shader
, source
);
143 gl
.compileShader(shader
);
145 if (!gl
.getShaderParameter(shader
, gl
.COMPILE_STATUS
)) {
146 alert(`Unable to compile shader: ${gl.getShaderInfoLog(shader)}`);
147 gl
.deleteShader(shader
);
154 initializeBuffers(gl
) {
156 const positionBuffer
= gl
.createBuffer();
158 gl
.bindBuffer(gl
.ARRAY_BUFFER
, positionBuffer
);
161 -1.0, 1.0, 1.0, // Front-top-left
162 1.0, 1.0, 1.0, // Front-top-right
163 -1.0, -1.0, 1.0, // Front-bottom-left
164 1.0, -1.0, 1.0, // Front-bottom-right
165 1.0, -1.0, -1.0, // Back-bottom-right
166 1.0, 1.0, 1.0, // Front-top-right
167 1.0, 1.0, -1.0, // Back-top-right
168 -1.0, 1.0, 1.0, // Front-top-left
169 -1.0, 1.0, -1.0, // Back-top-left
170 -1.0, -1.0, 1.0, // Front-bottom-left
171 -1.0, -1.0, -1.0, // Back-bottom-left
172 1.0, -1.0, -1.0, // Back-bottom-right
173 -1.0, 1.0, -1.0, // Back-top-left
174 1.0, 1.0, -1.0 // Back-top-right
177 gl
.bufferData(gl
.ARRAY_BUFFER
,
178 new Float32Array(positions
),
182 position: positionBuffer
190 const matrix
= mat4
.create();
201 // Methods: Animation
205 mat4
.rotate(internals
.modelViewMatrix
, internals
.modelViewMatrix
, internals
.kRotationValues
[0], [1, 0, 0]);
206 mat4
.rotate(internals
.modelViewMatrix
, internals
.modelViewMatrix
, internals
.kRotationValues
[1], [0, 1, 0]);
207 mat4
.rotate(internals
.modelViewMatrix
, internals
.modelViewMatrix
, internals
.kRotationValues
[2], [0, 0, 1]);
210 drawScene(gl
, programInfo
, buffers
) {
212 gl
.clearColor(...internals
.kBackgroundColor
);
214 gl
.enable(gl
.DEPTH_TEST
);
215 gl
.depthFunc(gl
.LEQUAL
);
217 const fieldOfView
= internals
.kFieldOfView
* Math
.PI
/ 180;
218 const aspectRatio
= internals
.kWidthRatio
/ internals
.kHeightRatio
;
219 const projectionMatrix
= mat4
.create();
225 internals
.kNearLimit
,
229 internals
.modelViewMatrix
= internals
.modelViewMatrix
|| internals
.createMatrix();
231 internals
.rotate(internals
.modelViewMatrix
);
234 const numberOfComponents
= 3;
235 const type
= gl
.FLOAT
;
236 const normalize
= false;
240 gl
.bindBuffer(gl
.ARRAY_BUFFER
, buffers
.position
);
241 gl
.vertexAttribPointer(
242 programInfo
.attribLocations
.vertexPosition
,
249 gl
.enableVertexAttribArray(programInfo
.attribLocations
.vertexPosition
);
253 // ATTEMPT TO SEND COLOR DATA
255 const colorBuffer
= gl
.createBuffer();
257 gl
.bindBuffer(gl
.ARRAY_BUFFER
, colorBuffer
);
260 1.0, 0.0, 0.5, 1.0, // Front-top-left
261 1.0, 0.3, 0.8, 1.0, // Front-top-right
262 1.0, 1.0, 0.7, 1.0, // Front-bottom-left
263 0.0, 0.3, 0.5, 1.0, // Front-bottom-right
264 0.0, 0.3, 0.5, 1.0, // Back-bottom-right
265 1.0, 0.3, 0.8, 1.0, // Front-top-right
266 1.0, 0.3, 0.8, 1.0, // Back-top-right
267 1.0, 0.0, 0.5, 1.0, // Front-top-left
268 1.0, 0.0, 0.5, 1.0, // Back-top-left
269 1.0, 1.0, 0.7, 1.0, // Front-bottom-left
270 1.0, 1.0, 0.7, 1.0, // Back-bottom-left
271 0.0, 0.3, 0.5, 1.0, // Back-bottom-right
272 1.0, 0.0, 0.5, 1.0, // Back-top-left
273 1.0, 0.3, 0.8, 1.0 // Back-top-right
276 gl
.bufferData(gl
.ARRAY_BUFFER
,
277 new Float32Array(colors
),
280 const numberOfComponents
= 4;
281 const type
= gl
.FLOAT
;
282 const normalize
= false;
286 gl
.bindBuffer(gl
.ARRAY_BUFFER
, colorBuffer
);
287 gl
.vertexAttribPointer(
288 programInfo
.attribLocations
.vertexColor
,
295 gl
.enableVertexAttribArray(programInfo
.attribLocations
.vertexColor
);
300 gl
.useProgram(programInfo
.program
);
303 programInfo
.uniformLocations
.projectionMatrix
,
308 programInfo
.uniformLocations
.modelViewMatrix
,
310 internals
.modelViewMatrix
315 const vertexCount
= 14;
316 gl
.drawArrays(gl
.TRIANGLE_STRIP
, offset
, vertexCount
);
320 animate(gl
, programInfo
, buffers
, time
) {
322 const delta
= time
- internals
.currentTime
;
323 const interval
= 1000 / internals
.kFPS
;
325 if (delta
>= interval
) {
326 internals
.drawScene(gl
, programInfo
, buffers
, delta
);
327 internals
.currentTime
= time
;
330 window
.requestAnimationFrame(internals
.animate
.bind(this, gl
, programInfo
, buffers
));
334 window
.addEventListener('load', internals
.onLoad
);