window.addEventListener('load', () => { 'use strict'
function main() { const canvas = document.getElementById('world') const gl = initGL(canvas) const shaderProgram = initShader(gl) const vertexBuffers = initBuffers(gl)
gl.clearColor(0, 0, 0, 1) gl.enable(gl.DEPTH_TEST) gl.enable(gl.CULL_FACE) gl.cullFace(gl.BACK)
let rx = 0, ry = 0, rz = 0 const modelMatrix = mat4.create() const tick = () => { requestAnimationFrame(tick)
rx += 0.02 ry += 0.03 rz += 0.05 mat4.identity(modelMatrix) mat4.rotateX(modelMatrix, modelMatrix, rx) mat4.rotateY(modelMatrix, modelMatrix, ry) mat4.rotateZ(modelMatrix, modelMatrix, rz)
drawScene(gl, shaderProgram, vertexBuffers, modelMatrix) } requestAnimationFrame(tick) }
function drawScene(gl, shaderProgram, vertexBuffers, modelMatrix) { gl.viewport(0, 0, gl.viewportWidth, gl.viewportHeight) gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT)
gl.useProgram(shaderProgram)
const pMatrix = mat4.create() mat4.perspective(pMatrix, 45, gl.viewportWidth / gl.viewportHeight, 0.1, 100.0) gl.uniformMatrix4fv(shaderProgram.uPMatrix, false, pMatrix)
const mvMatrix = mat4.create() mat4.identity(mvMatrix) mat4.translate(mvMatrix, mvMatrix, [0.0, 0.0, -5.0])
mat4.multiply(mvMatrix, mvMatrix, modelMatrix) gl.uniformMatrix4fv(shaderProgram.uMVMatrix, false, mvMatrix)
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffers.aVertexPosition) gl.vertexAttribPointer(shaderProgram.aVertexPosition, vertexBuffers.aVertexPosition.itemSize, gl.FLOAT, false, 0, 0) gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffers.aVertexColor) gl.vertexAttribPointer(shaderProgram.aVertexColor, vertexBuffers.aVertexColor.itemSize, gl.FLOAT, false, 0, 0)
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, vertexBuffers.indexBuffer) gl.drawElements(gl.TRIANGLES, vertexBuffers.indexBuffer.numItems, gl.UNSIGNED_SHORT, 0) }
function initShader(gl) { const shader_vs_src = ` attribute vec3 aVertexPosition; attribute vec4 aVertexColor;
uniform mat4 uMVMatrix; uniform mat4 uPMatrix;
varying vec4 vColor;
void main() { gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0); vColor = aVertexColor; }` const shader_fs_src = ` precision mediump float;
varying vec4 vColor;
void main() { gl_FragColor = vColor; }`
const shaderProgram = createShaderProgram( gl, compileShader(gl, gl.VERTEX_SHADER, shader_vs_src), compileShader(gl, gl.FRAGMENT_SHADER, shader_fs_src)) if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) { alert('Could not initialise shaders') }
shaderProgram.aVertexPosition = gl.getAttribLocation(shaderProgram, 'aVertexPosition') gl.enableVertexAttribArray(shaderProgram.aVertexPosition)
shaderProgram.aVertexColor = gl.getAttribLocation(shaderProgram, 'aVertexColor') gl.enableVertexAttribArray(shaderProgram.aVertexColor)
shaderProgram.uPMatrix = gl.getUniformLocation(shaderProgram, 'uPMatrix') shaderProgram.uMVMatrix = gl.getUniformLocation(shaderProgram, 'uMVMatrix')
return shaderProgram }
function initBuffers(gl) { const positionBuffer = gl.createBuffer() gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer) const positions = [ -1.0,-1.0, 1.0, 1.0,-1.0, 1.0, 1.0, 1.0, 1.0, -1.0, 1.0, 1.0, -1.0,-1.0,-1.0, -1.0, 1.0,-1.0, 1.0, 1.0,-1.0, 1.0,-1.0,-1.0, -1.0, 1.0,-1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0,-1.0, -1.0,-1.0,-1.0, 1.0,-1.0,-1.0, 1.0,-1.0, 1.0, -1.0,-1.0, 1.0, 1.0,-1.0,-1.0, 1.0, 1.0,-1.0, 1.0, 1.0, 1.0, 1.0,-1.0, 1.0, -1.0,-1.0,-1.0, -1.0,-1.0, 1.0, -1.0, 1.0, 1.0, -1.0, 1.0,-1.0, ] gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(positions), gl.STATIC_DRAW) positionBuffer.itemSize = 3 positionBuffer.numItems = positions.length / positionBuffer.itemSize
const colorBuffer = gl.createBuffer() gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer) 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, 0,0,1,1, 0,0,1,1, 0,0,1,1, 0,0,1,1, 1,1,0,1, 1,1,0,1, 1,1,0,1, 1,1,0,1, 0,1,1,1, 0,1,1,1, 0,1,1,1, 0,1,1,1, 1,0,1,1, 1,0,1,1, 1,0,1,1, 1,0,1,1, ] gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(colors), gl.STATIC_DRAW) colorBuffer.itemSize = 4 colorBuffer.numItems = colors.length / colorBuffer.itemSize
const indexBuffer = gl.createBuffer() gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer) const indices = [ 0, 1, 2, 0, 2, 3, 4, 5, 6, 4, 6, 7, 8, 9, 10, 8, 10, 11, 12, 13, 14, 12, 14, 15, 16, 17, 18, 16, 18, 19, 20, 21, 22, 20, 22, 23, ] gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indices), gl.STATIC_DRAW) indexBuffer.itemSize = 1 indexBuffer.numItems = indices.length / indexBuffer.itemSize
return { aVertexPosition: positionBuffer, aVertexColor: colorBuffer, indexBuffer: indexBuffer, } }
const mvMatrixStack = []
function pushMatrix(mtx) { const copy = mat4.create() mat4.set(mtx, copy) mvMatrixStack.push(copy) }
function popMatrix() { if (mvMatrixStack.length == 0) { throw "Invalid popMatrix!" } return mvMatrixStack.pop() }
function initGL(canvas) { let gl try { gl = canvas.getContext('experimental-webgl') gl.viewportWidth = canvas.width gl.viewportHeight = canvas.height } catch (e) { } if (!gl) { alert('Could not initialise WebGL, sorry :-(') } return gl }
function createShaderProgram(gl, vertexShader, fragmentShader) { const shaderProgram = gl.createProgram() gl.attachShader(shaderProgram, vertexShader) gl.attachShader(shaderProgram, fragmentShader) gl.linkProgram(shaderProgram) return shaderProgram }
function compileShader(gl, type, src) { const shader = gl.createShader(type) gl.shaderSource(shader, src) gl.compileShader(shader) if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) { alert(gl.getShaderInfoLog(shader)) return null } return shader }
main() })
|