const canvas = document.getElementById('glCanvas');
const gl = canvas.getContext('webgl');
gl.enable(gl.DEPTH_TEST);
const vsSource = `
attribute vec4 aVertexPosition;
attribute vec4 aVertexColor;
uniform mat4 uModelViewMatrix;
uniform mat4 uProjectionMatrix;
varying lowp vec4 vColor;
void main() {
gl_Position = uProjectionMatrix * uModelViewMatrix * aVertexPosition;
vColor = aVertexColor;
}
`;
const fsSource = `
varying lowp vec4 vColor;
void main() {
gl_FragColor = vColor;
}
`;
function initShaderProgram(gl, vsSource, fsSource) {
const vertexShader = loadShader(gl, gl.VERTEX_SHADER, vsSource);
const fragmentShader = loadShader(gl, gl.FRAGMENT_SHADER, fsSource);
const shaderProgram = gl.createProgram();
gl.attachShader(shaderProgram, vertexShader);
gl.attachShader(shaderProgram, fragmentShader);
gl.linkProgram(shaderProgram);
return shaderProgram;
}
function loadShader(gl, type, source) {
const shader = gl.createShader(type);
gl.shaderSource(shader, source);
gl.compileShader(shader);
return shader;
}
// Cube vertices
const positions = [
-0.5, -0.5, 0.5, 0.5, -0.5, 0.5, 0.5, 0.5, 0.5, -0.5, 0.5, 0.5,
-0.5, -0.5, -0.5, -0.5, 0.5, -0.5, 0.5, 0.5, -0.5, 0.5, -0.5, -0.5,
];
const colors = [
1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1,
0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
];
const indices = [0,1,2, 0,2,3, 4,5,6, 4,6,7, 0,3,5, 0,5,4, 1,7,6, 1,6,2, 3,2,6, 3,6,5, 0,4,7, 0,7,1];
const positionBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(positions), gl.STATIC_DRAW);
const colorBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(colors), gl.STATIC_DRAW);
const indexBuffer = gl.createBuffer();
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer);
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indices), gl.STATIC_DRAW);
const shaderProgram = initShaderProgram(gl, vsSource, fsSource);
const vertexPosition = gl.getAttribLocation(shaderProgram, 'aVertexPosition');
const vertexColor = gl.getAttribLocation(shaderProgram, 'aVertexColor');
const projectionMatrix = gl.getUniformLocation(shaderProgram, 'uProjectionMatrix');
const modelViewMatrix = gl.getUniformLocation(shaderProgram, 'uModelViewMatrix');
let rotation = 0;
function perspective(fov, aspect, near, far) {
const f = 1.0 / Math.tan(fov / 2);
return [f/aspect,0,0,0, 0,f,0,0, 0,0,(far+near)/(near-far),-1, 0,0,(2*far*near)/(near-far),0];
}
function render() {
rotation += 0.01;
gl.clearColor(0.0, 0.0, 0.0, 1.0);
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
const proj = perspective(Math.PI / 4, 1, 0.1, 100);
const c = Math.cos(rotation), s = Math.sin(rotation);
const mv = [c,0,s,0, 0,1,0,0, -s,0,c,0, 0,0,-3,1];
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
gl.vertexAttribPointer(vertexPosition, 3, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(vertexPosition);
gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer);
gl.vertexAttribPointer(vertexColor, 4, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(vertexColor);
gl.useProgram(shaderProgram);
gl.uniformMatrix4fv(projectionMatrix, false, proj);
gl.uniformMatrix4fv(modelViewMatrix, false, mv);
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer);
gl.drawElements(gl.TRIANGLES, 36, gl.UNSIGNED_SHORT, 0);
requestAnimationFrame(render);
}
render();