'use strict';
function main() {
const canvas = document.getElementById('cube-context');
const gl = canvas.getContext('webgl2');
if (!gl) {
return;
}
canvas.classList.remove('hide');
const vertexShaderSrc = `#version 300 es
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;
in vec3 vtx_position;
in vec3 vtx_normal;
in vec3 vtx_color;
out vec3 frg_position;
out vec3 frg_normal;
out vec3 frg_color;
void main() {
frg_position = vec3(model * vec4(vtx_position, 1.0));
frg_normal = mat3(transpose(inverse(model))) * vtx_normal;
gl_Position = projection * view * vec4(frg_position, 1.0);
frg_color = vtx_color;
}
`;
const fragmentShaderSrc = `#version 300 es
precision highp float;
const vec3 light_position = vec3(1.2, 1.0, 2.0);
const vec3 light_color = vec3(1.0, 1.0, 1.0);
in vec3 frg_position;
in vec3 frg_normal;
in vec3 frg_color;
out vec4 final_color;
void main() {
vec3 ambient = 0.1 * light_color;
vec3 light_direction = normalize(light_position - frg_position);
vec3 normal = normalize(frg_normal);
vec3 diffuse = max(dot(normal, light_direction), 0.0) * light_color;
vec3 view_direction = normalize(vec3(0, 0, 2.0) - frg_position);
vec3 reflect_direction = reflect(-light_direction, normal);
vec3 specular = 0.5 * pow(max(dot(view_direction, reflect_direction), 0.0), 32.0) *
light_color;
vec3 result = specular + diffuse + ambient;
final_color = vec4(result * frg_color, 1.0);
}
`;
const vertexShader = gl.createShader(gl.VERTEX_SHADER);
gl.shaderSource(vertexShader, vertexShaderSrc);
gl.compileShader(vertexShader);
console.log(gl.getShaderInfoLog(vertexShader));
const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(fragmentShader, fragmentShaderSrc);
gl.compileShader(fragmentShader);
console.log(gl.getShaderInfoLog(fragmentShader));
const graphicsProgram = gl.createProgram();
gl.attachShader(graphicsProgram, vertexShader);
gl.attachShader(graphicsProgram, fragmentShader);
gl.linkProgram(graphicsProgram);
const modelUni = gl.getUniformLocation(graphicsProgram, 'model');
const viewUni = gl.getUniformLocation(graphicsProgram, 'view');
const projectionUni = gl.getUniformLocation(graphicsProgram,'projection');
const positionAttr = gl.getAttribLocation(graphicsProgram, 'vtx_position');
const normalAttr = gl.getAttribLocation(graphicsProgram, 'vtx_normal');
const colorAttr = gl.getAttribLocation(graphicsProgram, 'vtx_color');
const vertices = [
-0.5, -0.5, -0.5, 0.0, 0.0, -1.0, 1.0, 0.0, 0.0,
0.5, -0.5, -0.5, 0.0, 0.0, -1.0, 1.0, 0.0, 0.0,
0.5, 0.5, -0.5, 0.0, 0.0, -1.0, 1.0, 0.0, 0.0,
0.5, 0.5, -0.5, 0.0, 0.0, -1.0, 1.0, 0.0, 0.0,
-0.5, 0.5, -0.5, 0.0, 0.0, -1.0, 1.0, 0.0, 0.0,
-0.5, -0.5, -0.5, 0.0, 0.0, -1.0, 1.0, 0.0, 0.0,
-0.5, -0.5, 0.5, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0,
0.5, -0.5, 0.5, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0,
0.5, 0.5, 0.5, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0,
0.5, 0.5, 0.5, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0,
-0.5, 0.5, 0.5, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0,
-0.5, -0.5, 0.5, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0,
-0.5, 0.5, 0.5, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0,
-0.5, 0.5, -0.5, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0,
-0.5, -0.5, -0.5, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0,
-0.5, -0.5, -0.5, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0,
-0.5, -0.5, 0.5, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0,
-0.5, 0.5, 0.5, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0,
0.5, 0.5, 0.5, 1.0, 0.0, 0.0, 1.0, 0.0, 1.0,
0.5, 0.5, -0.5, 1.0, 0.0, 0.0, 1.0, 0.0, 1.0,
0.5, -0.5, -0.5, 1.0, 0.0, 0.0, 1.0, 0.0, 1.0,
0.5, -0.5, -0.5, 1.0, 0.0, 0.0, 1.0, 0.0, 1.0,
0.5, -0.5, 0.5, 1.0, 0.0, 0.0, 1.0, 0.0, 1.0,
0.5, 0.5, 0.5, 1.0, 0.0, 0.0, 1.0, 0.0, 1.0,
-0.5, -0.5, -0.5, 0.0, -1.0, 0.0, 1.0, 1.0, 0.0,
0.5, -0.5, -0.5, 0.0, -1.0, 0.0, 1.0, 1.0, 0.0,
0.5, -0.5, 0.5, 0.0, -1.0, 0.0, 1.0, 1.0, 0.0,
0.5, -0.5, 0.5, 0.0, -1.0, 0.0, 1.0, 1.0, 0.0,
-0.5, -0.5, 0.5, 0.0, -1.0, 0.0, 1.0, 1.0, 0.0,
-0.5, -0.5, -0.5, 0.0, -1.0, 0.0, 1.0, 1.0, 0.0,
-0.5, 0.5, -0.5, 0.0, 1.0, 0.0, 0.0, 1.0, 1.0,
0.5, 0.5, -0.5, 0.0, 1.0, 0.0, 0.0, 1.0, 1.0,
0.5, 0.5, 0.5, 0.0, 1.0, 0.0, 0.0, 1.0, 1.0,
0.5, 0.5, 0.5, 0.0, 1.0, 0.0, 0.0, 1.0, 1.0,
-0.5, 0.5, 0.5, 0.0, 1.0, 0.0, 0.0, 1.0, 1.0,
-0.5, 0.5, -0.5, 0.0, 1.0, 0.0, 0.0, 1.0, 1.0,
];
const vao = gl.createVertexArray();
gl.bindVertexArray(vao);
const vbo = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, vbo);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);
gl.enableVertexAttribArray(positionAttr);
gl.vertexAttribPointer(positionAttr, 3, gl.FLOAT, false, 36, 0);
gl.enableVertexAttribArray(normalAttr);
gl.vertexAttribPointer(normalAttr, 3, gl.FLOAT, false, 36, 12)
gl.enableVertexAttribArray(colorAttr);
gl.vertexAttribPointer(colorAttr, 3, gl.FLOAT, false, 36, 24);
gl.enable(gl.DEPTH_TEST);
gl.enable(gl.BLEND);
const projection = glm.perspective(glm.radians(90.0), 4.0 / 3.0, 0.1, 100.0).elements;
const cameraPos = glm.vec3([0, 0, 2]);
const cameraUp = glm.vec3([0, 1, 0]);
const view = glm.lookAt(cameraPos, glm.vec3(), cameraUp).elements;
let model = glm.mat4();
let last = Date.now();
let dt = 0;
const drawScene = () => {
gl.bindVertexArray(vao);
gl.useProgram(graphicsProgram);
gl.uniformMatrix4fv(projectionUni, false, projection);
gl.uniformMatrix4fv(viewUni, false, view);
model = glm.rotate(model, glm.radians(30.0) * dt, glm.vec3(1.0, 0.0, 0.0));
model = glm.rotate(model, glm.radians(30.0) * dt, glm.vec3(0.0, 1.0, 0.0));
gl.uniformMatrix4fv(modelUni, false, model.elements);
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
gl.drawArrays(gl.TRIANGLES, 0, vertices.length / 9);
requestAnimationFrame(drawScene);
dt = (Date.now() - last) / 1000;
last = Date.now();
};
requestAnimationFrame(drawScene);
}
main();