diff --git a/package-lock.json b/package-lock.json index 19c5334..7622304 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1303,6 +1303,12 @@ "integrity": "sha512-3c+yGKvVP5Y9TYBEibGNR+kLtijnj7mYrXRg+WpFb2X9xm04g/DXYkfg4hmzJQosc9snFNUPkbYIhu+KAm6jJw==", "dev": true }, + "@types/lodash": { + "version": "4.14.165", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.165.tgz", + "integrity": "sha512-tjSSOTHhI5mCHTy/OOXYIhi2Wt1qcbHmuXD1Ha7q70CgI/I71afO4XtLb/cVexki1oVYchpul/TOuu3Arcdxrg==", + "dev": true + }, "@types/mime": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/@types/mime/-/mime-2.0.3.tgz", @@ -3888,8 +3894,7 @@ "lodash": { "version": "4.17.20", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz", - "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==", - "dev": true + "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==" }, "loose-envify": { "version": "1.4.0", diff --git a/package.json b/package.json index 7cb3576..2f4f5ba 100644 --- a/package.json +++ b/package.json @@ -42,6 +42,7 @@ "@babel/runtime-corejs3": "^7.12.5", "@types/express": "^4.17.9", "@types/jquery": "^3.5.4", + "@types/lodash": "^4.14.165", "@types/react": "^17.0.0", "@types/react-dom": "^17.0.0", "@typescript-eslint/eslint-plugin": "^4.8.1", @@ -66,6 +67,7 @@ "express": "^4.17.1", "gl-mat4": "^1.2.0", "jquery": "^3.5.1", + "lodash": "^4.17.20", "react": "^17.0.1", "react-dom": "^17.0.1" } diff --git a/public/css/style.css b/public/css/style.css index 61c89ec..a523d7e 100644 --- a/public/css/style.css +++ b/public/css/style.css @@ -32,4 +32,9 @@ input[type=number] { #ui { display: inline-block; vertical-align: top; +} + +#pushtoscene { + height: 50px; + width: 150px; } \ No newline at end of file diff --git a/src/client/draw.ts b/src/client/draw.ts index 549867c..9cb8846 100644 --- a/src/client/draw.ts +++ b/src/client/draw.ts @@ -1,4 +1,4 @@ -import {initMatrices} from './matrix'; +import {initMatrices, initModelAndNormalMatrices} from './matrix'; import {initVertexAttribs} from './vertexattrib'; /** @@ -8,6 +8,7 @@ import {initVertexAttribs} from './vertexattrib'; * @param {any} buffers the buffers to draw * @param {number} params various parameterss * @param {any} texture the texture to load + * @param {Array} scene the scene array * @param {number} now the current time */ export function drawScene(gl: any, @@ -15,6 +16,7 @@ export function drawScene(gl: any, buffers: any, params: any, texture: any, + scene: Array, now: number) { gl.clearColor(0.0, 0.0, 0.0, 1.0); gl.clearDepth(1.0); @@ -36,7 +38,6 @@ export function drawScene(gl: any, modelMatrix, normalMatrix, ] = initMatrices(gl, params); - for (let i = 0; i < params.instanceNumber; i++) { gl.uniformMatrix4fv( programInfo.uniformLocations.projectionMatrix, @@ -59,4 +60,41 @@ export function drawScene(gl: any, const offset = 0; gl.drawElements(gl.TRIANGLES, vertexCount, type, offset); } + + for (let i = 0; i < scene.length; i++) { + initVertexAttribs(gl, scene[i].programInfo, scene[i].buffers); + gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, scene[i].buffers.indices); + gl.useProgram(scene[i].programInfo.program); + gl.activeTexture(gl.TEXTURE0); + gl.bindTexture(gl.TEXTURE_2D, scene[i].texture); + gl.uniform1i(scene[i].programInfo.uniformLocations.uSampler, 0); + gl.uniform1f(scene[i].programInfo.uniformLocations.time, now); + + const [ + modelMatrix, + normalMatrix, + ] = initModelAndNormalMatrices(scene[i].params); + for (let j = 0; j < scene[i].params.instanceNumber; j++) { + gl.uniformMatrix4fv( + scene[i].programInfo.uniformLocations.projectionMatrix, + false, + projectionMatrix); + gl.uniformMatrix4fv( + scene[i].programInfo.uniformLocations.viewMatrix, + false, + viewMatrix); + gl.uniformMatrix4fv( + scene[i].programInfo.uniformLocations.modelMatrix, + false, + modelMatrix[j]); + gl.uniformMatrix4fv( + scene[i].programInfo.uniformLocations.normalMatrix, + false, + normalMatrix[j]); + const vertexCount = scene[i].params.len; + const type = gl.UNSIGNED_SHORT; + const offset = 0; + gl.drawElements(gl.TRIANGLES, vertexCount, type, offset); + } + } } diff --git a/src/client/init.ts b/src/client/init.ts index 7faf2fe..9385f39 100644 --- a/src/client/init.ts +++ b/src/client/init.ts @@ -85,6 +85,12 @@ export async function initCache(context: any) { wall: null, }, }; + context.obj = { + positions: racerObj.positions, + indices: racerObj.indices, + normals: racerObj.normals, + uvs: racerObj.uvs, + }; context.params.len = racerObj.indices.length; context.params.range = racerObj.range; context.texture = racerTexture; diff --git a/src/client/main.ts b/src/client/main.ts index 0c4edc2..cf3296a 100644 --- a/src/client/main.ts +++ b/src/client/main.ts @@ -10,7 +10,8 @@ import {initCache, initParams, setProgramInfo} from './init'; import {uiUpdateParams, uiUpdateTexture, uiUpdateObject, - uiUpdateShader} from './uijquery'; + uiUpdateShader, + uiUpdateScene} from './uijquery'; import {initUX} from './ux'; import {updateCamera} from './camera'; @@ -22,6 +23,7 @@ main(); async function main() { const context: any = { gl: null, + obj: null, texture: null, params: null, buffers: null, @@ -30,6 +32,7 @@ async function main() { fragmentShader: null, vertexShader: null, cache: null, + scene: [], }; const canvas: any = document.querySelector('#glCanvas')!; context.gl = canvas.getContext('webgl2'); @@ -68,6 +71,7 @@ async function main() { context.buffers, context.params, context.texture, + context.scene, now); requestAnimationFrame(render); } @@ -75,6 +79,7 @@ async function main() { uiUpdateTexture(context); uiUpdateObject(context); uiUpdateShader(context); + uiUpdateScene(context); initUX(context, canvas); requestAnimationFrame(render); } diff --git a/src/client/matrix.ts b/src/client/matrix.ts index 69f5926..b1e8b20 100644 --- a/src/client/matrix.ts +++ b/src/client/matrix.ts @@ -1,6 +1,66 @@ // @ts-ignore import mat4 from 'gl-mat4'; +/** + * Initializes matrices for the scene + * @param {any} params various parameters + * @return {Array} the matrices + */ +export function initModelAndNormalMatrices(params: any) { + const normalMatrix = []; + const modelMatrix = []; + for (let i = 0; i < params.instanceNumber; i++) { + const normalMatrixTemplate = mat4.create(); + const modelMatrixTemplate = mat4.create(); + let addx = 0; + let addy = 0; + if (i % 3 == 1) { + addx = Math.floor(i / 9 + 1) * params.range * 1.5; + } else if (i % 3 == 2) { + addx = -Math.floor(i / 9 + 1) * params.range * 1.5; + } + if (i % 9 > 5) { + addy = Math.floor(i / 9 + 1) * params.range * 1.5; + } else if (i % 9 > 2 && i % 9 < 6) { + addy = -Math.floor(i / 9 + 1) * params.range * 1.5; + } + mat4.translate(modelMatrixTemplate, + modelMatrixTemplate, + [ + params.circleSize * Math.cos(params.squareRotation) + addx + + params.pos.x, + params.circleSize * Math.sin(params.squareRotation) + addy + + params.pos.y, + params.pos.z, + ]); + mat4.rotateY(modelMatrixTemplate, + modelMatrixTemplate, + params.rot.y); + mat4.rotateZ(modelMatrixTemplate, + modelMatrixTemplate, + params.rot.z); + mat4.rotateX(modelMatrixTemplate, + modelMatrixTemplate, + params.rot.x); + mat4.rotateY(modelMatrixTemplate, + modelMatrixTemplate, + params.squareRotation); + mat4.scale(modelMatrixTemplate, + modelMatrixTemplate, + [ + params.scale.x, + params.scale.y, + params.scale.z, + ]); + mat4.invert(normalMatrixTemplate, modelMatrixTemplate); + mat4.transpose(normalMatrixTemplate, normalMatrixTemplate); + normalMatrix.push(normalMatrixTemplate); + modelMatrix.push(modelMatrixTemplate); + } + return [modelMatrix, normalMatrix]; +} + + /** * Initializes matrices for the scene * @param {any} gl the WebGL context diff --git a/src/client/objutils.ts b/src/client/objutils.ts index ffd1a0e..d2e9e8d 100644 --- a/src/client/objutils.ts +++ b/src/client/objutils.ts @@ -13,6 +13,20 @@ export async function fetchObj(url: string) { return data; } +/** + * Pushes a new obj file to the gl buffer + * @param {any} context the program context + * @param {any} obj the obj file to push + * @return {any} the initiated buffers + */ +export function pushBuffersToScene( + context: any, + obj: any) { + return initBuffers(context.gl, + obj.positions, obj.indices, obj.normals, obj.uvs); +} + + /** * Pushes a new obj file to the gl buffer * @param {any} context the program context @@ -24,6 +38,12 @@ export function loadObjBuffers( if (context.buffers != null) { deleteBuffers(context.gl, context.buffers); } + context.obj = { + positions: obj.positions, + indices: obj.indices, + normals: obj.normals, + uvs: obj.uvs, + }; context.buffers = initBuffers(context.gl, obj.positions, obj.indices, obj.normals, obj.uvs); } diff --git a/src/client/uijquery.ts b/src/client/uijquery.ts index e74856f..668560c 100644 --- a/src/client/uijquery.ts +++ b/src/client/uijquery.ts @@ -1,7 +1,9 @@ import $ from 'jquery'; +import _ from 'lodash'; import {loadTexture} from './texture'; import {fetchObj, loadObj, loadObjBuffers} from './objutils'; import {changeFragmentShader} from './shaders'; +import {initBuffers} from './buffers'; import vsSource from './shaders/shader.vert'; import blackandwhite from './shaders/blackandwhite.frag'; @@ -11,6 +13,28 @@ import texture from './shaders/texture.frag'; import sobel from './shaders/sobel.frag'; import fractal from './shaders/fractal.frag'; +/** + * UI block to update scene + * @param {any} context the program context + */ +export function uiUpdateScene(context: any) { + $('#pushtoscene').on('click', () => { + context.scene.push({ + buffers: initBuffers(context.gl, + context.obj.positions, + context.obj.indices, + context.obj.normals, + context.obj.uvs), + texture: context.texture, + params: _.cloneDeep(context.params), + programInfo: _.cloneDeep(context.programInfo), + shaderProgram: _.cloneDeep(context.shaderProgram), + fragmentShader: _.cloneDeep(context.fragmentShader), + vertexShader: _.cloneDeep(context.vertexShader), + }); + }); +} + /** * UI block for updating parameters * @param {any} params the parameters to be tweaked diff --git a/views/index.ejs b/views/index.ejs index 1696e89..f54038f 100644 --- a/views/index.ejs +++ b/views/index.ejs @@ -104,6 +104,9 @@ +
+ +