import { vec3 } from "gl-matrix"; import { Drawer2D } from "./drawer2D"; import { Drawer3D } from "./drawer3D"; import { TriangleDrawer } from "./triangle_drawer"; class InputMap{ private pressedKey:Set; //private mouseLast : [number,number]; private mouseDelta : [number,number]; constructor(){ this.pressedKey = new Set(); this.mouseDelta = [0,0]; } registerHandler(){ const self = this; document.addEventListener("keydown",(ev)=>{ if(self.pressedKey.has(ev.key)){ console.log(ev.key,"pressed"); } self.pressedKey.add(ev.key); }); document.addEventListener("keyup",(ev)=>{ const exist = self.pressedKey.delete(ev.key); if(exist){ console.log(ev.key,"released"); } }); } isPressed(keyname:string){ return this.pressedKey.has(keyname); } } /** get timestamp counter in millisecond*/ function getCurrentTime() : number{ return performance.now(); } const MillisecondPerFrame = 1000/60; export class CanvasApp{ readonly gl: WebGL2RenderingContext; private n : number; renderer: Drawer2D; trenderer : TriangleDrawer; r : Drawer3D; inputMap: InputMap; constructor(gl: WebGL2RenderingContext){ this.gl = gl; this.renderer = new Drawer2D(gl); this.trenderer = new TriangleDrawer(gl); this.r = new Drawer3D(gl); this.inputMap = new InputMap(); this.inputMap.registerHandler(); } intialize():boolean{ this.renderer.prepare(); this.trenderer.prepare(this.gl); this.r.init(); let escPressed = false; document.addEventListener("mousemove",(ev)=>{ if(!escPressed){ this.r.camera.rotateRight(Math.PI / 180.0 * ev.movementX); this.r.camera.rotateUp(Math.PI / 180.0 * ev.movementY); } }); document.addEventListener("keydown",(e)=>{ if(e.key == "Escape"){ escPressed = !escPressed; } }); this.gl.clearColor(0,0,0,0); this.gl.clearDepth(1); this.gl.enable(this.gl.DEPTH_TEST); //this.gl.enable(this.gl.CULL_FACE); return true; } handleInput(){ const Speed = 0.5; let forward = this.r.camera.forward; let right = this.r.camera.right; vec3.scale(forward,forward,Speed); vec3.scale(right,right,Speed); if(this.inputMap.isPressed("d")){ vec3.add(this.r.camera.pos,this.r.camera.pos,right); } if(this.inputMap.isPressed("a")){ const r = vec3.create(); vec3.negate(r,right); vec3.add(this.r.camera.pos,this.r.camera.pos,r); } if(this.inputMap.isPressed("w")){ vec3.add(this.r.camera.pos,this.r.camera.pos,forward); } if(this.inputMap.isPressed("s")){ const f = vec3.create(); vec3.negate(f,forward); vec3.add(this.r.camera.pos,this.r.camera.pos,f); } } startRun(synctime = 0){ const beforeLoop = getCurrentTime(); this.loop(); const afterLoop = getCurrentTime(); const delta = afterLoop - beforeLoop - synctime; const delay = (delta < MillisecondPerFrame) ? (MillisecondPerFrame - delta) : 0; setTimeout((()=>{ const afterWait = getCurrentTime(); this.startRun(afterWait - afterLoop - delay); }).bind(this),delay); } loop(){ this.handleInput(); } startDraw(){ this.drawScene(0); } drawScene(time:DOMHighResTimeStamp){ this.gl.viewport(0,0,this.gl.canvas.width,this.gl.canvas.height); this.gl.clear(this.gl.COLOR_BUFFER_BIT|this.gl.DEPTH_BUFFER_BIT); //this.renderer.draw(this.gl,{}); //this.trenderer.draw(this.gl,{}); this.r.draw(this.gl,{}); requestAnimationFrame(this.drawScene.bind(this)); } };