diff --git a/src/client/init.ts b/src/client/init.ts
index 9385f39..861cd82 100644
--- a/src/client/init.ts
+++ b/src/client/init.ts
@@ -100,30 +100,31 @@ export async function initCache(context: any) {
* Set the program info
* @param {any} context the program context
*/
-export function setProgramInfo(context: any) {
- context.programInfo = {
- program: context.shaderProgram,
+export function setProgramInfo(context: any,
+ shaderProgram: any) {
+ return {
+ program: shaderProgram,
attribLocations: {
- vertexPosition: context.gl.getAttribLocation(context.shaderProgram,
+ vertexPosition: context.gl.getAttribLocation(shaderProgram,
'aVertexPosition'),
- vertexNormal: context.gl.getAttribLocation(context.shaderProgram,
+ vertexNormal: context.gl.getAttribLocation(shaderProgram,
'aVertexNormal'),
- textureCoord: context.gl.getAttribLocation(context.shaderProgram,
+ textureCoord: context.gl.getAttribLocation(shaderProgram,
'aTextureCoord'),
},
uniformLocations: {
projectionMatrix: context.gl.getUniformLocation(
- context.shaderProgram, 'uProjectionMatrix'),
+ shaderProgram, 'uProjectionMatrix'),
viewMatrix: context.gl.getUniformLocation(
- context.shaderProgram, 'uviewMatrix'),
+ shaderProgram, 'uviewMatrix'),
modelMatrix: context.gl.getUniformLocation(
- context.shaderProgram, 'umodelMatrix'),
+ shaderProgram, 'umodelMatrix'),
normalMatrix: context.gl.getUniformLocation(
- context.shaderProgram, 'unormalMatrix'),
+ shaderProgram, 'unormalMatrix'),
uSampler: context.gl.getUniformLocation(
- context.shaderProgram, 'uSampler'),
+ shaderProgram, 'uSampler'),
time: context.gl.getUniformLocation(
- context.shaderProgram, 'time'),
+ shaderProgram, 'time'),
},
};
}
diff --git a/src/client/main.ts b/src/client/main.ts
index cf3296a..d7da37e 100644
--- a/src/client/main.ts
+++ b/src/client/main.ts
@@ -29,8 +29,10 @@ async function main() {
buffers: null,
programInfo: null,
shaderProgram: null,
- fragmentShader: null,
- vertexShader: null,
+ shaders: {
+ frag: null,
+ vert: null,
+ },
cache: null,
scene: [],
};
@@ -46,9 +48,9 @@ async function main() {
initParams(context);
await initCache(context);
- loadObjBuffers(context, context.cache.objs.racer);
- initShaderProgram(context, vsSource, texture);
- setProgramInfo(context);
+ context.buffers = loadObjBuffers(context, context.buffers, context.cache.objs.racer);
+ [context.shaderProgram, context.shaders.vert, context.shaders.frag] = initShaderProgram(context, context.shaderProgram, context.shaders.frag, context.shaders.vert, vsSource, texture);
+ context.programInfo = setProgramInfo(context, context.shaderProgram);
// context.texture = loadTexture(context.gl, '/static/textures/racer.png');
let then = 0;
let changed = false;
diff --git a/src/client/objutils.ts b/src/client/objutils.ts
index d2e9e8d..e702381 100644
--- a/src/client/objutils.ts
+++ b/src/client/objutils.ts
@@ -34,9 +34,10 @@ export function pushBuffersToScene(
*/
export function loadObjBuffers(
context: any,
+ buffers: any,
obj: any) {
- if (context.buffers != null) {
- deleteBuffers(context.gl, context.buffers);
+ if (buffers != null) {
+ deleteBuffers(context.gl, buffers);
}
context.obj = {
positions: obj.positions,
@@ -44,7 +45,7 @@ export function loadObjBuffers(
normals: obj.normals,
uvs: obj.uvs,
};
- context.buffers = initBuffers(context.gl,
+ return initBuffers(context.gl,
obj.positions, obj.indices, obj.normals, obj.uvs);
}
diff --git a/src/client/shaders.ts b/src/client/shaders.ts
index 6fbca1b..4cd76c4 100644
--- a/src/client/shaders.ts
+++ b/src/client/shaders.ts
@@ -7,26 +7,30 @@ import {setProgramInfo} from './init';
* @param {string} fsSource the fragment shader source
*/
export function initShaderProgram(context: any,
+ shaderProgram: any,
+ fragmentShader: any,
+ vertexShader: any,
vsSource: string,
fsSource: string) {
- context.vertexShader = loadShader(context.gl,
+ vertexShader = loadShader(context.gl,
context.gl.VERTEX_SHADER, vsSource);
- context.fragmentShader = loadShader(context.gl,
+ fragmentShader = loadShader(context.gl,
context.gl.FRAGMENT_SHADER, fsSource);
// Create the shader program
- context.shaderProgram = context.gl.createProgram();
- context.gl.attachShader(context.shaderProgram, context.vertexShader);
- context.gl.attachShader(context.shaderProgram, context.fragmentShader);
- context.gl.linkProgram(context.shaderProgram);
+ shaderProgram = context.gl.createProgram();
+ context.gl.attachShader(shaderProgram, vertexShader);
+ context.gl.attachShader(shaderProgram, fragmentShader);
+ context.gl.linkProgram(shaderProgram);
// If creating the shader program failed, alert
- if (!context.gl.getProgramParameter(context.shaderProgram,
+ if (!context.gl.getProgramParameter(shaderProgram,
context.gl.LINK_STATUS)) {
alert('Unable to initialize the shader program: ' +
- context.gl.getProgramInfoLog(context.shaderProgram));
- context.shaderProgram = null;
+ context.gl.getProgramInfoLog(shaderProgram));
+ shaderProgram = null;
}
+ return [shaderProgram, vertexShader, fragmentShader];
}
/**
@@ -59,9 +63,14 @@ export function loadShader(gl: any, type: any, source: string) {
* @param {string} vsSource current vsSource
*/
export function changeFragmentShader(context: any,
+ programInfo: any,
+ shaderProgram: any,
+ fragmentShader: any,
+ vertexShader: any,
fsSource: string,
vsSource: string) {
- context.gl.deleteShader(context.fragmentShader);
- initShaderProgram(context, vsSource, fsSource);
- setProgramInfo(context);
+ context.gl.deleteShader(fragmentShader);
+ [shaderProgram, vertexShader, fragmentShader] = initShaderProgram(context, shaderProgram, fragmentShader, vertexShader, vsSource, fsSource);
+ programInfo = setProgramInfo(context, shaderProgram);
+ return [programInfo, shaderProgram, vertexShader, fragmentShader];
}
diff --git a/src/client/uijquery.ts b/src/client/uijquery.ts
index 668560c..b0d120a 100644
--- a/src/client/uijquery.ts
+++ b/src/client/uijquery.ts
@@ -29,8 +29,269 @@ export function uiUpdateScene(context: any) {
params: _.cloneDeep(context.params),
programInfo: _.cloneDeep(context.programInfo),
shaderProgram: _.cloneDeep(context.shaderProgram),
- fragmentShader: _.cloneDeep(context.fragmentShader),
- vertexShader: _.cloneDeep(context.vertexShader),
+ shaders: _.cloneDeep(context.shaders),
+ });
+ let instanceRadioString;
+ if ($('input[name=instance]:checked', '#instanceoptions').val() ==
+ 'normal') {
+ instanceRadioString = `
+
+
+
+
+ `;
+ } else if (
+ ($('input[name=instance]:checked', '#instanceoptions').val() ==
+ 'one')) {
+ instanceRadioString = `
+
+
+
+
+ `;
+ } else {
+ instanceRadioString = `
+
+
+
+
+ `;
+ }
+ $('.scene-block').append(`
+
+
Change shader:
+
+
+
+
+
+
+
+
+
Change instances number:
+
+
+
+
+
+
+
Change rotation:
+
X:
+
+
Y:
+
+
Z:
+
+
+
+
Change scale:
+
X:
+
+
Y:
+
+
Z:
+
+
+
+
Translate:
+
X:
+
+
Y:
+
+
Z:
+
+
+
+
Change object:
+
+
+
+
+
+
+
+
Change texture:
+
+
+
+
+
+
+
`);
+ $('#' + context.scene.length + 't_wall').on('click', (event) => {
+ const n = parseInt(event.target.id.split('t')[0]);
+ if (context.cache.textures.wall == null) {
+ context.cache.textures.wall = loadTexture(context.gl,
+ '/static/textures/wall.png');
+ }
+ context.scene[n - 1].texture = context.cache.textures.wall;
+ });
+ $('#' + context.scene.length + 't_ice').on('click', (event) => {
+ const n = parseInt(event.target.id.split('t')[0]);
+ if (context.cache.textures.ice == null) {
+ context.cache.textures.ice = loadTexture(context.gl,
+ '/static/textures/ice.png');
+ }
+ context.scene[n - 1].texture = context.cache.textures.ice;
+ });
+ $('#' + context.scene.length + 't_fox').on('click', (event) => {
+ const n = parseInt(event.target.id.split('t')[0]);
+ if (context.cache.textures.fox == null) {
+ context.cache.textures.fox = loadTexture(context.gl,
+ '/static/textures/fox.png');
+ }
+ context.scene[n - 1].texture = context.cache.textures.fox;
+ });
+ $('#' + context.scene.length + 't_racer').on('click', (event) => {
+ const n = parseInt(event.target.id.split('t')[0]);
+ if (context.cache.textures.racer == null) {
+ context.cache.textures.racer = loadTexture(context.gl,
+ '/static/textures/racer.png');
+ }
+ context.scene[n - 1].texture = context.cache.textures.racer;
+ });
+ $('#' + context.scene.length + 't_racer_wireframe').on('click',
+ (event) => {
+ const n = parseInt(event.target.id.split('t')[0]);
+ if (context.cache.textures.racerWireframe == null) {
+ context.cache.textures.racerWireframe = loadTexture(
+ context.gl,
+ '/static/textures/racer_wireframe.png');
+ }
+ context.scene[n - 1].texture = context.cache.textures.racerWireframe;
+ });
+ $('#' + context.scene.length + 'instanceoptions input').on('change', (event) => {
+ const n = parseInt(event.target.attributes[2].nodeValue!.split('instance')[0]);
+ if ($('input[name=' + n + 'instance]:checked', '#' + n + 'instanceoptions').val() ==
+ 'normal') {
+ context.scene[n - 1].params.instanceNumber = parseFloat($('#' + n + 'instance').val());
+ } else if (
+ ($('input[name=' + n + 'instance]:checked', '#' + n + 'instanceoptions').val() ==
+ 'one')) {
+ context.scene[n - 1].params.instanceNumber = 1;
+ } else {
+ context.scene[n - 1].params.instanceNumber = 0;
+ }
+ });
+ $('#' + context.scene.length + 'instance').on('input', (event) => {
+ const n = parseInt(event.target.id.split('instance')[0]);
+ if ($('input[name=' + n + 'instance]:checked', '#' + n + 'instanceoptions').val() ==
+ 'normal') {
+ context.scene[n - 1].params.instanceNumber = parseFloat($('#' + n + 'instance').val());
+ }
+ });
+ $('#' + context.scene.length + 'rotx').on('input', (event) => {
+ const n = parseInt(event.target.id.split('rot')[0]);
+ console.log(n);
+ context.scene[n - 1].params.rot.x = parseFloat($('#' + n + 'rotx').val());
+ });
+ $('#' + context.scene.length + 'roty').on('input', (event) => {
+ const n = parseInt(event.target.id.split('rot')[0]);
+ context.scene[n - 1].params.rot.y = parseFloat($('#' + n + 'roty').val());
+ });
+ $('#' + context.scene.length + 'rotz').on('input', (event) => {
+ const n = parseInt(event.target.id.split('rot')[0]);
+ context.scene[n - 1].params.rot.z = parseFloat($('#' + n + 'rotz').val());
+ });
+ $('#' + context.scene.length + 'posx').on('input', (event) => {
+ const n = parseInt(event.target.id.split('pos')[0]);
+ context.scene[n - 1].params.pos.x = parseFloat($('#' + n + 'posx').val());
+ });
+ $('#' + context.scene.length + 'posy').on('input', (event) => {
+ const n = parseInt(event.target.id.split('pos')[0]);
+ context.scene[n - 1].params.pos.y = parseFloat($('#' + n + 'posy').val());
+ });
+ $('#' + context.scene.length + 'posz').on('input', (event) => {
+ const n = parseInt(event.target.id.split('pos')[0]);
+ context.scene[n - 1].params.pos.z = parseFloat($('#' + n + 'posz').val());
+ });
+ $('#' + context.scene.length + 'scalex').on('input', (event) => {
+ const n = parseInt(event.target.id.split('scale')[0]);
+ console.log(n);
+ console.log(parseFloat($('#' + n + 'scalex').val()));
+ context.scene[n - 1].params.scale.x = parseFloat($('#' + n + 'scalex').val());
+ });
+ $('#' + context.scene.length + 'scaley').on('input', (event) => {
+ const n = parseInt(event.target.id.split('scale')[0]);
+ context.scene[n - 1].params.scale.y = parseFloat($('#' + n + 'scaley').val());
+ });
+ $('#' + context.scene.length + 'scalez').on('input', (event) => {
+ const n = parseInt(event.target.id.split('scale')[0]);
+ context.scene[n - 1].params.scale.z = parseFloat($('#' + n + 'scalez').val());
+ });
+ $('#' + context.scene.length + 's_blackandwhite').on('click', function(event) {
+ const n = parseInt(event.target.id.split('s')[0]);
+ [context.scene[n - 1].programInfo, context.scene[n - 1].shaderProgram, context.scene[n - 1].shaders.vert, context.scene[n - 1].shaders.frag] = changeFragmentShader(context, context.scene[n - 1].programInfo, context.scene[n - 1].shaderProgram, context.scene[n - 1].shaders.frag, context.scene[n - 1].shaders.vert, blackandwhite, vsSource);
+ });
+ $('#' + context.scene.length + 's_color').on('click', function(event) {
+ const n = parseInt(event.target.id.split('s')[0]);
+ [context.scene[n - 1].programInfo, context.scene[n - 1].shaderProgram, context.scene[n - 1].shaders.vert, context.scene[n - 1].shaders.frag] = changeFragmentShader(context, context.scene[n - 1].programInfo, context.scene[n - 1].shaderProgram, context.scene[n - 1].shaders.frag, context.scene[n - 1].shaders.vert, colored, vsSource);
+ });
+ $('#' + context.scene.length + 's_grey').on('click', function(event) {
+ const n = parseInt(event.target.id.split('s')[0]);
+ [context.scene[n - 1].programInfo, context.scene[n - 1].shaderProgram, context.scene[n - 1].shaders.vert, context.scene[n - 1].shaders.frag] = changeFragmentShader(context, context.scene[n - 1].programInfo, context.scene[n - 1].shaderProgram, context.scene[n - 1].shaders.frag, context.scene[n - 1].shaders.vert, grey, vsSource);
+ });
+ $('#' + context.scene.length + 's_texture').on('click', function(event) {
+ const n = parseInt(event.target.id.split('s')[0]);
+ [context.scene[n - 1].programInfo, context.scene[n - 1].shaderProgram, context.scene[n - 1].shaders.vert, context.scene[n - 1].shaders.frag] = changeFragmentShader(context, context.scene[n - 1].programInfo, context.scene[n - 1].shaderProgram, context.scene[n - 1].shaders.frag, context.scene[n - 1].shaders.vert, texture, vsSource);
+ });
+ $('#' + context.scene.length + 's_sobel').on('click', function(event) {
+ const n = parseInt(event.target.id.split('s')[0]);
+ [context.scene[n - 1].programInfo, context.scene[n - 1].shaderProgram, context.scene[n - 1].shaders.vert, context.scene[n - 1].shaders.frag] = changeFragmentShader(context, context.scene[n - 1].programInfo, context.scene[n - 1].shaderProgram, context.scene[n - 1].shaders.frag, context.scene[n - 1].shaders.vert, sobel, vsSource);
+ });
+ $('#' + context.scene.length + 's_fractal').on('click', function(event) {
+ const n = parseInt(event.target.id.split('s')[0]);
+ [context.scene[n - 1].programInfo, context.scene[n - 1].shaderProgram, context.scene[n - 1].shaders.vert, context.scene[n - 1].shaders.frag] = changeFragmentShader(context, context.scene[n - 1].programInfo, context.scene[n - 1].shaderProgram, context.scene[n - 1].shaders.frag, context.scene[n - 1].shaders.vert, fractal, vsSource);
+ });
+ $('#' + context.scene.length + 'o_sphere').on('click', async function(event) {
+ const n = parseInt(event.target.id.split('o')[0]);
+ if (context.cache.objs.sphere == null) {
+ const data = await fetchObj('/static/objs/sphere.obj');
+ context.cache.objs.sphere = loadObj(data);
+ }
+ context.scene[n - 1].buffers = loadObjBuffers(context, context.scene[n - 1].buffers, context.cache.objs.sphere);
+ context.scene[n - 1].params.len = context.cache.objs.sphere.indices.length;
+ context.scene[n - 1].params.range = context.cache.objs.sphere.range;
+ });
+ $('#' + context.scene.length + 'o_teapot').on('click', async function(event) {
+ const n = parseInt(event.target.id.split('o')[0]);
+ if (context.cache.objs.teapot == null) {
+ const data = await fetchObj('/static/objs/teapot.obj');
+ context.cache.objs.teapot = loadObj(data);
+ }
+ context.scene[n - 1].buffers = loadObjBuffers(context, context.scene[n - 1].buffers, context.cache.objs.teapot);
+ context.scene[n - 1].params.len = context.cache.objs.teapot.indices.length;
+ context.scene[n - 1].params.range = context.cache.objs.teapot.range;
+ });
+ $('#' + context.scene.length + 'o_fox').on('click', async function(event) {
+ const n = parseInt(event.target.id.split('o')[0]);
+ if (context.cache.objs.fox == null) {
+ const data = await fetchObj('/static/objs/fox.obj');
+ context.cache.objs.fox = loadObj(data);
+ }
+ context.scene[n - 1].buffers = loadObjBuffers(context, context.scene[n - 1].buffers, context.cache.objs.fox);
+ context.scene[n - 1].params.len = context.cache.objs.fox.indices.length;
+ context.scene[n - 1].params.range = context.cache.objs.fox.range;
+ });
+ $('#' + context.scene.length + 'o_mecha').on('click', async function(event) {
+ const n = parseInt(event.target.id.split('o')[0]);
+ if (context.cache.objs.mecha == null) {
+ const data = await fetchObj('/static/objs/mecha.obj');
+ context.cache.objs.mecha = loadObj(data);
+ }
+ context.scene[n - 1].buffers = loadObjBuffers(context, context.scene[n - 1].buffers, context.cache.objs.mecha);
+ context.scene[n - 1].params.len = context.cache.objs.mecha.indices.length;
+ context.scene[n - 1].params.range = context.cache.objs.mecha.range;
+ });
+ $('#' + context.scene.length + 'o_racer').on('click', async function(event) {
+ const n = parseInt(event.target.id.split('o')[0]);
+ if (context.cache.objs.racer == null) {
+ const data = await fetchObj('/static/objs/racer.obj');
+ context.cache.objs.racer = loadObj(data);
+ }
+ context.scene[n - 1].buffers = loadObjBuffers(context, context.scene[n - 1].buffers, context.cache.objs.racer);
+ context.scene[n - 1].params.len = context.cache.objs.racer.indices.length;
+ context.scene[n - 1].params.range = context.cache.objs.racer.range;
});
});
}
@@ -163,7 +424,7 @@ export function uiUpdateObject(context: any) {
const data = await fetchObj('/static/objs/sphere.obj');
context.cache.objs.sphere = loadObj(data);
}
- loadObjBuffers(context, context.cache.objs.sphere);
+ context.buffers = loadObjBuffers(context, context.buffers, context.cache.objs.sphere);
context.params.len = context.cache.objs.sphere.indices.length;
context.params.range = context.cache.objs.sphere.range;
});
@@ -172,7 +433,7 @@ export function uiUpdateObject(context: any) {
const data = await fetchObj('/static/objs/teapot.obj');
context.cache.objs.teapot = loadObj(data);
}
- loadObjBuffers(context, context.cache.objs.teapot);
+ context.buffers = loadObjBuffers(context, context.buffers, context.cache.objs.teapot);
context.params.len = context.cache.objs.teapot.indices.length;
context.params.range = context.cache.objs.teapot.range;
});
@@ -181,7 +442,7 @@ export function uiUpdateObject(context: any) {
const data = await fetchObj('/static/objs/fox.obj');
context.cache.objs.fox = loadObj(data);
}
- loadObjBuffers(context, context.cache.objs.fox);
+ context.buffers = loadObjBuffers(context, context.buffers, context.cache.objs.fox);
context.params.len = context.cache.objs.fox.indices.length;
context.params.range = context.cache.objs.fox.range;
});
@@ -190,7 +451,7 @@ export function uiUpdateObject(context: any) {
const data = await fetchObj('/static/objs/mecha.obj');
context.cache.objs.mecha = loadObj(data);
}
- loadObjBuffers(context, context.cache.objs.mecha);
+ context.buffers = loadObjBuffers(context, context.buffers, context.cache.objs.mecha);
context.params.len = context.cache.objs.mecha.indices.length;
context.params.range = context.cache.objs.mecha.range;
});
@@ -199,7 +460,7 @@ export function uiUpdateObject(context: any) {
const data = await fetchObj('/static/objs/racer.obj');
context.cache.objs.racer = loadObj(data);
}
- loadObjBuffers(context, context.cache.objs.racer);
+ context.buffers = loadObjBuffers(context, context.buffers, context.cache.objs.racer);
context.params.len = context.cache.objs.racer.indices.length;
context.params.range = context.cache.objs.racer.range;
});
@@ -211,21 +472,21 @@ export function uiUpdateObject(context: any) {
*/
export function uiUpdateShader(context: any) {
$('#s_blackandwhite').on('click', function() {
- changeFragmentShader(context, blackandwhite, vsSource);
+ [context.programInfo, context.shaderProgram, context.shaders.vert, context.shaders.frag] = changeFragmentShader(context, context.programInfo, context.shaderProgram, context.shaders.frag, context.shaders.vert, blackandwhite, vsSource);
});
$('#s_color').on('click', function() {
- changeFragmentShader(context, colored, vsSource);
+ [context.programInfo, context.shaderProgram, context.shaders.vert, context.shaders.frag] = changeFragmentShader(context, context.programInfo, context.shaderProgram, context.shaders.frag, context.shaders.vert, colored, vsSource);
});
$('#s_grey').on('click', function() {
- changeFragmentShader(context, grey, vsSource);
+ [context.programInfo, context.shaderProgram, context.shaders.vert, context.shaders.frag] = changeFragmentShader(context, context.programInfo, context.shaderProgram, context.shaders.frag, context.shaders.vert, grey, vsSource);
});
$('#s_texture').on('click', function() {
- changeFragmentShader(context, texture, vsSource);
+ [context.programInfo, context.shaderProgram, context.shaders.vert, context.shaders.frag] = changeFragmentShader(context, context.programInfo, context.shaderProgram, context.shaders.frag, context.shaders.vert, texture, vsSource);
});
$('#s_sobel').on('click', function() {
- changeFragmentShader(context, sobel, vsSource);
+ [context.programInfo, context.shaderProgram, context.shaders.vert, context.shaders.frag] = changeFragmentShader(context, context.programInfo, context.shaderProgram, context.shaders.frag, context.shaders.vert, sobel, vsSource);
});
$('#s_fractal').on('click', function() {
- changeFragmentShader(context, fractal, vsSource);
+ [context.programInfo, context.shaderProgram, context.shaders.vert, context.shaders.frag] = changeFragmentShader(context, context.programInfo, context.shaderProgram, context.shaders.frag, context.shaders.vert, fractal, vsSource);
});
}
diff --git a/views/index.ejs b/views/index.ejs
index f54038f..efbd019 100644
--- a/views/index.ejs
+++ b/views/index.ejs
@@ -107,6 +107,8 @@
+
+