import { initializeContext, Vec3, Mat4, Vec2 } from "./common.js"; import { Graphics, fullscreenCanvas, Texture, Camera } from "./graphics.js"; import * as drawing from "./draw.js"; import * as wasm from "./wasm.js"; import { Input } from "./input.js"; import {Grid, Tile, tree} from "./world.js"; const vertexShader = `#version 300 es in vec3 a_position; in vec2 a_tex_position; in vec4 a_color; out vec2 v_tex_position; out vec4 v_color; uniform mat4 u_matrix; uniform bool u_isTex; uniform bool u_isIso; mat4 Iso = mat4( 1, -1, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 ); void main() { vec4 orthographic; if (u_isIso) { vec4 isometric = Iso * vec4(a_position.xyz, 1.0); orthographic = u_matrix * isometric; } else { orthographic = u_matrix * vec4(a_position.xyz, 1.0); } gl_Position = orthographic; if (u_isTex) { v_tex_position = a_tex_position; } else { v_color = a_color; } } `; const fragmentShader = `#version 300 es precision highp float; in vec2 v_tex_position; in vec4 v_color; out vec4 outColor; uniform bool u_isTex; uniform sampler2D u_texture; void main() { if (u_isTex) { outColor = texture(u_texture, v_tex_position); } else { outColor = v_color; } } `; function draw(gfx: Graphics, camera: Camera, dt: number, grid: Grid) { gfx.clear(0, 0, 0, 0); camera.update(dt); let zoom = 2; let right = gfx.ctx.canvas.width * zoom; let left = -right * zoom; let top = gfx.ctx.canvas.height * zoom; let bottom = -top * zoom; let near = -100; let far = 100; let mo = Mat4.orthographic(left, right, bottom, top, near, far); let mt = Mat4.translate(camera.position); let m = mo.multNew(mt); gfx.ctx.uniformMatrix4fv( gfx.getUniform("u_matrix"), false, m.splat() ); //let exts = new Vec3(50, 50, 20); //for (let i = 0; i < 10; ++i) { // for (let j = 0; j < 10; ++j) { // if ((i + j) % 2) // drawing.drawIsometricCube(gfx, new Vec3(exts.x * i, 1000 - exts.y * j, 0), exts, [1, 0, 1, 1], TileEdge.None); // else // drawing.drawIsometricCube(gfx, new Vec3(exts.x * i, 1000 - exts.y * j, 0), exts, [1, 1, 0, 1], TileEdge.None); // } //} drawing.drawIsometricGrid(gfx, grid); } function addDefaultKeybinds(input: Input, camera: Camera) { input.addKeyAction("KeyA", [], camera, (c) => { c.movement.x = 0; }, (c) => { c.movement.x = 1; }); input.addKeyAction("KeyD", [], camera, (c) => { c.movement.y = 0; }, (c) => { c.movement.y = -1; }); input.addKeyAction("KeyW", [], camera, (c) => { c.movement.z = 0; }, (c) => { c.movement.z = -1; }); input.addKeyAction("KeyS", [], camera, (c) => { c.movement.w = 0; }, (c) => { c.movement.w = 1; }); } (async () => { const canvasId = "game"; const ctx = initializeContext(canvasId); if (ctx === null) return; const gfx = new Graphics(ctx, vertexShader, fragmentShader); fullscreenCanvas(gfx, canvasId); const a_position = gfx.createAttribute("a_position"); a_position.format(3, gfx.ctx.FLOAT, false, 0, 0); const a_color = gfx.createAttribute("a_color"); a_color.format(4, gfx.ctx.FLOAT, false, 0, 0); const a_tex_position = gfx.createAttribute("a_tex_position"); a_tex_position.format(2, gfx.ctx.FLOAT, false, 0, 0); gfx.createUniform("u_matrix"); gfx.createUniform("u_isTex"); gfx.createUniform("u_isIso"); //let city = await Texture.load(ctx, "../../assets/genetica/rt/City Night.jpg"); //let wall = await Texture.load(ctx, "../../assets/wall.png"); let camera = new Camera(new Vec3(0, 0, 0)); let grid = new Grid(new Vec3(-800, 0, 0), 100, 20, 20, 10); grid.fillLayer(new Tile([0, 0, 1, 1]), 0); for (let i = 0; i < 5; i++) { tree(grid, new Vec2(Math.floor(Math.random() * 19), Math.floor(Math.random() * 19))); } let prevTimestamp = 0; const frame = (timestamp: number) => { const deltaTime = (timestamp - prevTimestamp)/1000; prevTimestamp = timestamp; fullscreenCanvas(gfx, "game"); draw(gfx, camera, deltaTime, grid); window.requestAnimationFrame(frame); } window.requestAnimationFrame((timestamp) => { prevTimestamp = timestamp; window.requestAnimationFrame(frame); }); let input = new Input(); addDefaultKeybinds(input, camera); let wasmgl: wasm.WASMGL = new wasm.WASMGL(await wasm.loadWasmModule("./src/wasm/module.wasm")); })();