import { Vec2 } from "./common.js"; import { Graphics } from "./graphics.js"; const vertexShader = `#version 300 es in vec2 a_position; in vec4 a_color; out vec4 color; uniform vec2 u_resolution; void main() { vec2 clipSpace = (a_position / u_resolution) * 2.0 - 1.0; color = a_color; gl_Position = vec4(clipSpace.xy, 0.0, 1.0); } `; const fragmentShader = `#version 300 es precision highp float; in vec4 color; out vec4 outColor; void main() { outColor = color; } `; function initializeContext(canvasId: string): WebGL2RenderingContext | null { const canvas = document.getElementById(canvasId) as HTMLCanvasElement; const ctx = canvas.getContext("webgl2", {antialias: false}); return ctx; } function drawTriangle(gfx: Graphics, positions: [Vec2, Vec2, Vec2]) { const a_position = gfx.getAttribute("a_position"); const a_color = gfx.getAttribute("a_color"); const points: Array = [ positions[0].x, positions[0].y, positions[1].x, positions[1].y, positions[2].x, positions[2].y, ] const color: Array = [ 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, ]; a_position.data(gfx.ctx, points, gfx.ctx.STATIC_DRAW); a_color.data(gfx.ctx, color, gfx.ctx.STATIC_DRAW); gfx.ctx.drawArrays(gfx.ctx.TRIANGLES, 0, 3); } function drawTriangleExts(gfx: Graphics, position: Vec2, exts: Vec2) { const a_position = gfx.getAttribute("a_position"); const a_color = gfx.getAttribute("a_color"); const points: Array = [ position.x, position.y, position.x + exts.x, position.y, position.x, position.y + exts.y, ] const color: Array = [ 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, ]; a_position.data(gfx.ctx, points, gfx.ctx.STATIC_DRAW); a_color.data(gfx.ctx, color, gfx.ctx.STATIC_DRAW); gfx.ctx.drawArrays(gfx.ctx.TRIANGLES, 0, 3); } function drawRectangle(gfx: Graphics, position: Vec2, exts: Vec2) { const a_position = gfx.getAttribute("a_position"); const a_color = gfx.getAttribute("a_color"); const points: Array = [ position.x, position.y, position.x + exts.x, position.y, position.x, position.y + exts.y, position.x + exts.x, position.y + exts.y, position.x + exts.x, position.y, position.x, position.y + exts.y, ] const color: Array = [ 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, ]; a_position.data(gfx.ctx, points, gfx.ctx.STATIC_DRAW); a_color.data(gfx.ctx, color, gfx.ctx.STATIC_DRAW); gfx.ctx.drawArrays(gfx.ctx.TRIANGLES, 0, 6); } function drawCircle(gfx: Graphics, position: Vec2, radius: number) { const points: Array = new Array(); const precision = 40; const angle = 2.0*Math.PI/precision; let a = 0; for (let i = 0; i < precision; ++i) { var vec = Vec2.angle(a); vec.mult(radius); a += angle; points.push(vec); } for (let i = 0; i < points.length; i++) { const current = points[i]; const next = points[(i + 1) % points.length]; let center = position; drawTriangle(gfx, [center, center.addNew(current), center.addNew(next)]); } } function drawLine(gfx: Graphics, A: Vec2, B: Vec2) { const a_position = gfx.getAttribute("a_position"); const a_color = gfx.getAttribute("a_color"); let points: Array = [ A.x, A.y, B.x, B.y, ]; const color: Array = [ 1, 0, 0, 1, 0, 0, 1, 1, ]; a_position.data(gfx.ctx, points, gfx.ctx.STATIC_DRAW); a_color.data(gfx.ctx, color, gfx.ctx.STATIC_DRAW); gfx.ctx.drawArrays(gfx.ctx.LINES, 0, 2); } function fullscreenCanvas(id: string) { const canvas = document.getElementById(id) as HTMLCanvasElement; canvas.width = window.innerWidth; canvas.height = window.innerHeight; } function draw(gfx: Graphics) { const position: Vec2 = new Vec2(gfx.ctx.canvas.width / 2 - 100, gfx.ctx.canvas.height / 2 - 100); gfx.clear(0, 0, 0, 0); gfx.ctx.uniform2f(gfx.getUniform("u_resolution"), gfx.ctx.canvas.width, gfx.ctx.canvas.height); drawRectangle(gfx, position, new Vec2(200, 200)) drawTriangle(gfx, [new Vec2(100, 100), new Vec2(200, 100), new Vec2(100, 200)]); drawTriangleExts(gfx, new Vec2(200, 200), new Vec2(-100, -100)); drawCircle(gfx, new Vec2(400, 200), 100); drawLine(gfx, new Vec2(100, 600), new Vec2(600, 600)); } (() => { const canvasId = "game"; fullscreenCanvas(canvasId); const ctx = initializeContext(canvasId); if (ctx === null) return; const gfx = new Graphics(ctx, vertexShader, fragmentShader); const a_position = gfx.createAttribute("a_position"); a_position.format(2, gfx.ctx.FLOAT, false, 0, 0); const a_color = gfx.createAttribute("a_color"); a_color.format(4, gfx.ctx.FLOAT, false, 0, 0); gfx.createUniform("u_resolution"); draw(gfx); window.onresize = () => { fullscreenCanvas(canvasId); draw(gfx); } })();