import $ from 'jquery'; import vsSource from './shaders/shader.vert'; import fsSource4 from './shaders/texture.frag'; import {fetchObj, updateObj} from './objutils'; import {initShaderProgram} from './shaders'; import {loadTexture} from './texture'; import {initMatrices} from './matrix'; import {initVertexAttribs} from './vertexattrib'; import {uiUpdateParams, uiUpdateTexture, uiUpdateObject, uiUpdateShader} from './uijquery'; main(); /** * The program purpose is encapsulated in a main function */ async function main() { const context: any = { gl: null, texture: null, params: null, buffers: null, programInfo: null, shaderProgram: null, fragmentShader: null, vertexShader: null, }; const canvas: any = document.querySelector('#glCanvas')!; context.gl = canvas.getContext('webgl'); if (context.gl == null) { canvas.parentNode.removeChild(canvas); document.getElementById('root')!.insertAdjacentHTML('beforeend', `

Unable to initialize WebGL. Your browser or machine may not support it.

`); } const data = await fetchObj('/static/objs/racer.obj'); const distance: any = $('#distance').val(); const distanceFine: any = $('#distancefine').val(); const instanceNumber: any = $('#instance').val(); context.params = { distance: parseFloat(distance) + parseFloat(distanceFine), circleSize: $('#circlesize').val(), fov: $('#fov').val(), length: 0, avg: { x: 0, y: 0, z: 0, }, range: 0, rot: { x: $('#rotx').val(), y: $('#roty').val(), z: $('#rotz').val(), }, rotSpeed: $('#rotspeed').val(), instanceNumber: parseInt(instanceNumber), squareRotation: 0, }; [context.buffers, context.params] = updateObj( context.gl, data, context.buffers, context.params, true); initShaderProgram(context, vsSource, fsSource4); context.programInfo = { program: context.shaderProgram, attribLocations: { vertexPosition: context.gl.getAttribLocation(context.shaderProgram, 'aVertexPosition'), vertexNormal: context.gl.getAttribLocation(context.shaderProgram, 'aVertexNormal'), textureCoord: context.gl.getAttribLocation(context.shaderProgram, 'aTextureCoord'), }, uniformLocations: { projectionMatrix: context.gl.getUniformLocation( context.shaderProgram, 'uProjectionMatrix'), viewMatrix: context.gl.getUniformLocation( context.shaderProgram, 'uviewMatrix'), modelMatrix: context.gl.getUniformLocation( context.shaderProgram, 'umodelMatrix'), normalModelMatrix: context.gl.getUniformLocation( context.shaderProgram, 'unormalModelMatrix'), uSampler: context.gl.getUniformLocation( context.shaderProgram, 'uSampler'), }, }; context.texture = loadTexture(context.gl, '/static/textures/racer.png'); let then = 0; let changed = false; /** * Draws the scene repeatedly * @param {number} now the current time */ function render(now: any) { now *= 0.001; const deltaTime = now - then; context.params.squareRotation += deltaTime * context.params.rotSpeed; if (now >= 1 && changed == false) { changed = true; } then = now; drawScene(context.gl, context.programInfo, context.buffers, context.params, context.texture); requestAnimationFrame(render); } uiUpdateParams(context.params); uiUpdateTexture(context); uiUpdateObject(context); uiUpdateShader(context); requestAnimationFrame(render); } /** * Draw a webgl scene * @param {any} gl the WebGL context * @param {any} programInfo WebGL program information * @param {any} buffers the buffers to draw * @param {number} params various parameterss * @param {any} texture the texture to load */ function drawScene(gl: any, programInfo: any, buffers: any, params: any, texture: any) { gl.clearColor(0.0, 0.0, 0.0, 1.0); gl.clearDepth(1.0); gl.enable(gl.DEPTH_TEST); gl.depthFunc(gl.LEQUAL); gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); initVertexAttribs(gl, programInfo, buffers); gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, buffers.indices); gl.useProgram(programInfo.program); gl.activeTexture(gl.TEXTURE0); gl.bindTexture(gl.TEXTURE_2D, texture); gl.uniform1i(programInfo.uniformLocations.uSampler, 0); const [ projectionMatrix, viewMatrix, modelMatrix, normalModelMatrix, ] = initMatrices(gl, params); for (let i = 0; i < params.instanceNumber; i++) { gl.uniformMatrix4fv( programInfo.uniformLocations.projectionMatrix, false, projectionMatrix); gl.uniformMatrix4fv( programInfo.uniformLocations.viewMatrix, false, viewMatrix); gl.uniformMatrix4fv( programInfo.uniformLocations.modelMatrix, false, modelMatrix[i]); gl.uniformMatrix4fv( programInfo.uniformLocations.normalModelMatrix, false, normalModelMatrix[i]); const vertexCount = params.length; const type = gl.UNSIGNED_SHORT; const offset = 0; gl.drawElements(gl.TRIANGLES, vertexCount, type, offset); } }