Performance refactor
This commit is contained in:
		
							
								
								
									
										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 => {
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user