192 lines
4.8 KiB
TypeScript
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"));
|
|
})();
|