1 /* globals window document mat4 */
7 kEntrypointElementId: 'entrypoint', // The id of the canvas element where we will render
10 kTargetVerticalResolution: 32 + Math
.round(Math
.random() * 1024),
14 kBackgroundColor: [0.811, 0.73, 0.48, 1.0],
15 kRotationValues: [Math
.random(), Math
.random(), Math
.random()],
22 attribute vec4 aVertexPosition;
23 attribute vec4 aColor;
27 uniform mat4 uModelViewMatrix;
28 uniform mat4 uProjectionMatrix;
32 gl_Position = uProjectionMatrix * uModelViewMatrix * aVertexPosition;
39 precision mediump float;
44 gl_FragColor = vColor;
48 // Properties: Animation
52 // Runs on load, Initializes WebGL and starts the animation loop.
57 const canvas
= internals
.initializeCanvas();
58 const { gl
, programInfo
, buffers
} = internals
.initializeWebGL(canvas
);
60 window
.requestAnimationFrame(internals
.animate
.bind(this, gl
, programInfo
, buffers
));
63 // Gets a canvas element and sets up resizing events.
67 const canvas
= document
.getElementById(internals
.kEntrypointElementId
);
68 internals
.resizeCanvas(canvas
);
69 window
.addEventListener('resize', () => internals
.resizeCanvas(canvas
));
74 // Given a canvas, it will initialize the webgl context and set up the shaders.
76 initializeWebGL(canvas
) {
78 const gl
= canvas
.getContext('webgl', {
79 preserveDrawingBuffer: true
81 const shaderProgram
= internals
.initializeShaderProgram(gl
, internals
.kVertexShader
, internals
.kFragmentShader
);
84 program: shaderProgram
,
86 vertexPosition: gl
.getAttribLocation(shaderProgram
, 'aVertexPosition'),
87 vertexColor: gl
.getAttribLocation(shaderProgram
, 'aColor')
90 projectionMatrix: gl
.getUniformLocation(shaderProgram
, 'uProjectionMatrix'),
91 modelViewMatrix: gl
.getUniformLocation(shaderProgram
, 'uModelViewMatrix')
95 const buffers
= internals
.initializeBuffers(gl
);
97 return { gl
, programInfo
, buffers
};
102 resizeCanvas(canvas
) {
104 let width
= window
.innerWidth
;
105 let height
= Math
.round(width
* internals
.kHeightRatio
/ internals
.kWidthRatio
);
107 if (window
.innerHeight
< height
) {
108 height
= window
.innerHeight
;
109 width
= Math
.round(height
* internals
.kWidthRatio
/ internals
.kHeightRatio
);
110 console
.log(width
, height
);
113 canvas
.style
.width
= `${width}px`;
114 canvas
.style
.height
= `${height}px`;
116 canvas
.width
= internals
.kTargetVerticalResolution
* internals
.kWidthRatio
;
117 canvas
.height
= internals
.kTargetVerticalResolution
;
120 // Methods: Shader / GL Related
122 initializeShaderProgram(gl
, vertexShaderSource
, fragmentShaderSource
) {
124 const vertexShader
= internals
.loadShader(gl
, gl
.VERTEX_SHADER
, vertexShaderSource
);
125 const fragmentShader
= internals
.loadShader(gl
, gl
.FRAGMENT_SHADER
, fragmentShaderSource
);
127 const shaderProgram
= gl
.createProgram();
128 gl
.attachShader(shaderProgram
, vertexShader
);
129 gl
.attachShader(shaderProgram
, fragmentShader
);
131 gl
.linkProgram(shaderProgram
);
133 if (!gl
.getProgramParameter(shaderProgram
, gl
.LINK_STATUS
)) {
134 console
.error(`Unable to initialize shader program: ${gl.getProgramInfoLog(shaderProgram)}`);
138 return shaderProgram
;
141 loadShader(gl
, type
, source
) {
143 const shader
= gl
.createShader(type
);
144 gl
.shaderSource(shader
, source
);
145 gl
.compileShader(shader
);
147 if (!gl
.getShaderParameter(shader
, gl
.COMPILE_STATUS
)) {
148 console
.error(`Unable to compile shader: ${gl.getShaderInfoLog(shader)}`);
149 gl
.deleteShader(shader
);
156 initializeBuffers(gl
) {
158 const positionBuffer
= gl
.createBuffer();
160 gl
.bindBuffer(gl
.ARRAY_BUFFER
, positionBuffer
);
163 -1.0, 1.0, 1.0, // Front-top-left
164 1.0, 1.0, 1.0, // Front-top-right
165 -1.0, -1.0, 1.0, // Front-bottom-left
166 1.0, -1.0, 1.0, // Front-bottom-right
167 1.0, -1.0, -1.0, // Back-bottom-right
168 1.0, 1.0, 1.0, // Front-top-right
169 1.0, 1.0, -1.0, // Back-top-right
170 -1.0, 1.0, 1.0, // Front-top-left
171 -1.0, 1.0, -1.0, // Back-top-left
172 -1.0, -1.0, 1.0, // Front-bottom-left
173 -1.0, -1.0, -1.0, // Back-bottom-left
174 1.0, -1.0, -1.0, // Back-bottom-right
175 -1.0, 1.0, -1.0, // Back-top-left
176 1.0, 1.0, -1.0 // Back-top-right
179 gl
.bufferData(gl
.ARRAY_BUFFER
,
180 new Float32Array(positions
),
184 position: positionBuffer
192 const matrix
= mat4
.create();
203 // Methods: Animation
207 mat4
.rotate(internals
.modelViewMatrix
, internals
.modelViewMatrix
, internals
.kRotationValues
[0], [1, 0, 0]);
208 mat4
.rotate(internals
.modelViewMatrix
, internals
.modelViewMatrix
, internals
.kRotationValues
[1], [0, 1, 0]);
209 mat4
.rotate(internals
.modelViewMatrix
, internals
.modelViewMatrix
, internals
.kRotationValues
[2], [0, 0, 1]);
212 drawScene(gl
, programInfo
, buffers
) {
214 gl
.clearColor(...internals
.kBackgroundColor
);
216 gl
.enable(gl
.DEPTH_TEST
);
217 gl
.depthFunc(gl
.LEQUAL
);
219 const fieldOfView
= internals
.kFieldOfView
* Math
.PI
/ 180;
220 const aspectRatio
= internals
.kWidthRatio
/ internals
.kHeightRatio
;
221 const projectionMatrix
= mat4
.create();
227 internals
.kNearLimit
,
231 internals
.modelViewMatrix
= internals
.modelViewMatrix
|| internals
.createMatrix();
233 internals
.rotate(internals
.modelViewMatrix
);
236 const numberOfComponents
= 3;
237 const type
= gl
.FLOAT
;
238 const normalize
= false;
242 gl
.bindBuffer(gl
.ARRAY_BUFFER
, buffers
.position
);
243 gl
.vertexAttribPointer(
244 programInfo
.attribLocations
.vertexPosition
,
251 gl
.enableVertexAttribArray(programInfo
.attribLocations
.vertexPosition
);
255 // ATTEMPT TO SEND COLOR DATA
257 const colorBuffer
= gl
.createBuffer();
259 gl
.bindBuffer(gl
.ARRAY_BUFFER
, colorBuffer
);
262 1.0, 0.0, 0.5, 1.0, // Front-top-left
263 1.0, 0.3, 0.8, 1.0, // Front-top-right
264 1.0, 1.0, 0.7, 1.0, // Front-bottom-left
265 0.0, 0.3, 0.5, 1.0, // Front-bottom-right
266 0.0, 0.3, 0.5, 1.0, // Back-bottom-right
267 1.0, 0.3, 0.8, 1.0, // Front-top-right
268 1.0, 0.3, 0.8, 1.0, // Back-top-right
269 1.0, 0.0, 0.5, 1.0, // Front-top-left
270 1.0, 0.0, 0.5, 1.0, // Back-top-left
271 1.0, 1.0, 0.7, 1.0, // Front-bottom-left
272 1.0, 1.0, 0.7, 1.0, // Back-bottom-left
273 0.0, 0.3, 0.5, 1.0, // Back-bottom-right
274 1.0, 0.0, 0.5, 1.0, // Back-top-left
275 1.0, 0.3, 0.8, 1.0 // Back-top-right
278 gl
.bufferData(gl
.ARRAY_BUFFER
,
279 new Float32Array(colors
),
282 const numberOfComponents
= 4;
283 const type
= gl
.FLOAT
;
284 const normalize
= false;
288 gl
.bindBuffer(gl
.ARRAY_BUFFER
, colorBuffer
);
289 gl
.vertexAttribPointer(
290 programInfo
.attribLocations
.vertexColor
,
297 gl
.enableVertexAttribArray(programInfo
.attribLocations
.vertexColor
);
302 gl
.useProgram(programInfo
.program
);
305 programInfo
.uniformLocations
.projectionMatrix
,
310 programInfo
.uniformLocations
.modelViewMatrix
,
312 internals
.modelViewMatrix
317 const vertexCount
= 14;
318 gl
.drawArrays(gl
.TRIANGLE_STRIP
, offset
, vertexCount
);
322 animate(gl
, programInfo
, buffers
, time
) {
324 const delta
= time
- internals
.currentTime
;
325 const interval
= 1000 / internals
.kFPS
;
327 if (delta
>= interval
) {
328 internals
.drawScene(gl
, programInfo
, buffers
, delta
);
329 internals
.currentTime
= time
;
332 window
.requestAnimationFrame(internals
.animate
.bind(this, gl
, programInfo
, buffers
));
336 window
.addEventListener('load', internals
.onLoad
);