webgl_game/src/js/script.ts

192 lines
4.8 KiB
TypeScript

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"));
})();