Performance refactor
This commit is contained in:
parent
80284baf2e
commit
7bc7b64c8b
146
index.js
146
index.js
@ -53,7 +53,9 @@ void main() {
|
||||
* @param {WebGLRenderingContext} gl
|
||||
*/
|
||||
function draw(gl, params, objects) {
|
||||
gl.clearColor(0.6, 0.8, 1.0, 1.0);
|
||||
const skyColor = [0.6, 0.8, 1.0];
|
||||
|
||||
gl.clearColor(...skyColor, 1.0);
|
||||
gl.clearDepth(1.0);
|
||||
gl.enable(gl.DEPTH_TEST);
|
||||
gl.depthFunc(gl.LEQUAL);
|
||||
@ -65,55 +67,32 @@ function draw(gl, params, objects) {
|
||||
|
||||
const camrot = params.camera.orientation;
|
||||
const campos = params.camera.position;
|
||||
const viewMat = se3.product(
|
||||
const viewMatrix = se3.product(
|
||||
se3.rotxyz(-camrot[0], -camrot[1], -camrot[2]),
|
||||
se3.translation(-campos[0], -campos[1], -campos[2])
|
||||
);
|
||||
|
||||
for (const {program, texture, position, orientation, geometry} of objects) {
|
||||
// load those ahead of time
|
||||
const viewLoc = gl.getUniformLocation(program, 'uView');
|
||||
const modelLoc = gl.getUniformLocation(program, 'uModel');
|
||||
const projLoc = gl.getUniformLocation(program, 'uProjection');
|
||||
const samplerLoc = gl.getUniformLocation(program, 'uSampler');
|
||||
const fogColorLoc = gl.getUniformLocation(program, 'uFogColor');
|
||||
const lightDirectionLoc = gl.getUniformLocation(program, 'uLightDirection');
|
||||
const ambiantLoc = gl.getUniformLocation(program, 'uAmbiantLight');
|
||||
let lastGlContext;
|
||||
|
||||
const positionLoc = gl.getAttribLocation(program, 'aPosition');
|
||||
const normalLoc = gl.getAttribLocation(program, 'aNormal');
|
||||
const textureLoc = gl.getAttribLocation(program, 'aTextureCoord');
|
||||
for (const {glContext, position, orientation, geometry} of objects) {
|
||||
if (glContext !== lastGlContext) {
|
||||
glContext.setupScene({
|
||||
projectionMatrix: params.projMatrix,
|
||||
viewMatrix,
|
||||
fogColor: skyColor,
|
||||
lightDirection: params.lightDirection,
|
||||
ambiantLightAmount: params.ambiantLight,
|
||||
});
|
||||
}
|
||||
|
||||
//const mvMatrix = se3.product(se3.translation(...position), se3.rotxyz(...orientation));
|
||||
const mvMatrix = se3.identity();
|
||||
lastGlContext = glContext;
|
||||
|
||||
gl.useProgram(program);
|
||||
|
||||
gl.uniformMatrix4fv(viewLoc, false, new Float32Array(viewMat));
|
||||
gl.uniformMatrix4fv(modelLoc, false, new Float32Array(mvMatrix));
|
||||
gl.uniformMatrix4fv(projLoc, false, new Float32Array(params.projMatrix));
|
||||
gl.uniform3f(fogColorLoc, 0.6, 0.8, 1.0);
|
||||
gl.uniform3f(lightDirectionLoc, ...params.lightDirection);
|
||||
gl.uniform1f(ambiantLoc, params.ambiantLight);
|
||||
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, geometry.glBuffer);
|
||||
|
||||
gl.vertexAttribPointer(positionLoc, 3, gl.FLOAT, false, 20, 0);
|
||||
gl.enableVertexAttribArray(positionLoc);
|
||||
|
||||
gl.vertexAttribPointer(normalLoc, 3, gl.BYTE, true, 20, 12);
|
||||
gl.enableVertexAttribArray(normalLoc);
|
||||
|
||||
gl.vertexAttribPointer(textureLoc, 2, gl.UNSIGNED_SHORT, true, 20, 16);
|
||||
gl.enableVertexAttribArray(textureLoc);
|
||||
|
||||
gl.activeTexture(gl.TEXTURE0);
|
||||
gl.bindTexture(gl.TEXTURE_2D, texture);
|
||||
gl.uniform1i(samplerLoc, 0);
|
||||
|
||||
gl.drawArrays(gl.TRIANGLES, 0, geometry.numVertices);
|
||||
// gl.bindTexture(gl.TEXTURE_2D, null);
|
||||
// gl.drawArrays(gl.LINE_STRIP, 0, geometry.numVertices);
|
||||
glContext.drawObject({
|
||||
position,
|
||||
orientation,
|
||||
glBuffer: geometry.glBuffer,
|
||||
numVertices: geometry.numVertices,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -180,7 +159,7 @@ function handleKeys(params) {
|
||||
});
|
||||
}
|
||||
|
||||
function getObjects(world, z, x, program, texture) {
|
||||
function getObjects(world, z, x, glContext) {
|
||||
return world.chunks
|
||||
.filter(chunk => {
|
||||
if (chunk.position.z < z - 8 * 16) return false;
|
||||
@ -197,9 +176,8 @@ function getObjects(world, z, x, program, texture) {
|
||||
.map(chunk => ({
|
||||
position: [0.0, 0.0, 0.0],
|
||||
orientation: [0.0, 0.0, 0.0],
|
||||
program,
|
||||
geometry: chunk.buffer,
|
||||
texture,
|
||||
glContext,
|
||||
}));
|
||||
}
|
||||
|
||||
@ -239,7 +217,7 @@ function tick(time, gl, params) {
|
||||
}
|
||||
}
|
||||
|
||||
const objects = getObjects(params.world, campos[2], campos[0], params.program, params.texture);
|
||||
const objects = getObjects(params.world, campos[2], campos[0], params.worldGl);
|
||||
draw(gl, params, objects);
|
||||
|
||||
const dt = (time - stuff.lastFrameTime) * 0.001;
|
||||
@ -324,6 +302,74 @@ function checkCollision(curPos, newPos, world) {
|
||||
// [x] better controls
|
||||
// [ ] save the world (yay) to local storage (bah)
|
||||
|
||||
async function initWorldGl(gl) {
|
||||
const program = makeProgram(gl, TEST_VSHADER, TEST_FSHADER);
|
||||
const texture = await loadTexture(gl, 'texture.png');
|
||||
|
||||
// load those ahead of time
|
||||
const viewLoc = gl.getUniformLocation(program, 'uView');
|
||||
const modelLoc = gl.getUniformLocation(program, 'uModel');
|
||||
const projLoc = gl.getUniformLocation(program, 'uProjection');
|
||||
const samplerLoc = gl.getUniformLocation(program, 'uSampler');
|
||||
const fogColorLoc = gl.getUniformLocation(program, 'uFogColor');
|
||||
const lightDirectionLoc = gl.getUniformLocation(program, 'uLightDirection');
|
||||
const ambiantLoc = gl.getUniformLocation(program, 'uAmbiantLight');
|
||||
|
||||
const positionLoc = gl.getAttribLocation(program, 'aPosition');
|
||||
const normalLoc = gl.getAttribLocation(program, 'aNormal');
|
||||
const textureLoc = gl.getAttribLocation(program, 'aTextureCoord');
|
||||
|
||||
const setupScene = (sceneParams) => {
|
||||
const {
|
||||
projectionMatrix,
|
||||
viewMatrix,
|
||||
fogColor,
|
||||
lightDirection,
|
||||
ambiantLightAmount,
|
||||
} = sceneParams;
|
||||
|
||||
gl.useProgram(program);
|
||||
|
||||
gl.uniformMatrix4fv(projLoc, false, new Float32Array(projectionMatrix));
|
||||
gl.uniformMatrix4fv(viewLoc, false, new Float32Array(viewMatrix));
|
||||
gl.uniform3fv(fogColorLoc, fogColor);
|
||||
gl.uniform3fv(lightDirectionLoc, lightDirection);
|
||||
gl.uniform1f(ambiantLoc, ambiantLightAmount);
|
||||
|
||||
// doing this here because it's the same for all world stuff
|
||||
gl.uniformMatrix4fv(modelLoc, false, new Float32Array(se3.identity()));
|
||||
gl.uniform1i(samplerLoc, 0);
|
||||
};
|
||||
|
||||
const drawObject = (objectParams) => {
|
||||
const {
|
||||
glBuffer,
|
||||
numVertices,
|
||||
} = objectParams;
|
||||
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, glBuffer);
|
||||
|
||||
gl.vertexAttribPointer(positionLoc, 3, gl.FLOAT, false, 20, 0);
|
||||
gl.enableVertexAttribArray(positionLoc);
|
||||
|
||||
gl.vertexAttribPointer(normalLoc, 3, gl.BYTE, true, 20, 12);
|
||||
gl.enableVertexAttribArray(normalLoc);
|
||||
|
||||
gl.vertexAttribPointer(textureLoc, 2, gl.UNSIGNED_SHORT, true, 20, 16);
|
||||
gl.enableVertexAttribArray(textureLoc);
|
||||
|
||||
gl.activeTexture(gl.TEXTURE0);
|
||||
gl.bindTexture(gl.TEXTURE_2D, texture);
|
||||
|
||||
gl.drawArrays(gl.TRIANGLES, 0, numVertices);
|
||||
};
|
||||
|
||||
return {
|
||||
setupScene,
|
||||
drawObject,
|
||||
};
|
||||
}
|
||||
|
||||
async function main() {
|
||||
const canvas = document.querySelector('#game');
|
||||
const gl = canvas.getContext('webgl');
|
||||
@ -333,8 +379,7 @@ async function main() {
|
||||
return;
|
||||
}
|
||||
|
||||
const program = makeProgram(gl, TEST_VSHADER, TEST_FSHADER);
|
||||
const texture = await loadTexture(gl, 'texture.png');
|
||||
const worldGl = await initWorldGl(gl);
|
||||
|
||||
const params = {
|
||||
projMatrix: se3.perspective(Math.PI / 3, canvas.clientWidth / canvas.clientHeight, 0.1, 100.0),
|
||||
@ -345,12 +390,11 @@ async function main() {
|
||||
},
|
||||
keys: new Set(),
|
||||
world: makeWorld(),
|
||||
texture,
|
||||
program,
|
||||
lightDirection: [-0.2, -0.5, 0.4],
|
||||
ambiantLight: 0.7,
|
||||
flying: false,
|
||||
isOnGround: false,
|
||||
worldGl,
|
||||
}
|
||||
|
||||
document.querySelector('#lightx').oninput = e => {
|
||||
|
Loading…
Reference in New Issue
Block a user