diff --git a/frontend/www/src/index.ts b/frontend/www/src/index.ts index 3bb8993..f463d20 100644 --- a/frontend/www/src/index.ts +++ b/frontend/www/src/index.ts @@ -9,6 +9,7 @@ import { Texture } from "./webgl/texture"; import { callbackify } from "util"; import { defaultLabelFactory, LabelFactory, Align, Label } from "./webgl/text"; import Voronoi = require("./voronoi/voronoi-core"); +import { VoronoiBuilder } from "./voronoi/voronoi"; function f32v(ptr: number, size: number): Float32Array { return new Float32Array(memory.buffer, ptr, size); @@ -91,6 +92,8 @@ class GameInstance { renderer: Renderer; planet_count: number; + vor_builder: VoronoiBuilder; + vor_counter = 3; use_vor = true; playing = true; // 0 is paused, 1 is playing but not rerendered, 2 is playing and rerendered @@ -120,25 +123,25 @@ class GameInstance { - const indexBuffer = new IndexBuffer(GL, [ - 0, 1, 2, - 1, 2, 3, - ]); + // const indexBuffer = new IndexBuffer(GL, [ + // 0, 1, 2, + // 1, 2, 3, + // ]); - const positionBuffer = new VertexBuffer(GL, [ - -1, -1, - -1, 1, - 1, -1, - 1, 1, - ]); + // const positionBuffer = new VertexBuffer(GL, [ + // -1, -1, + // -1, 1, + // 1, -1, + // 1, 1, + // ]); - const layout = new VertexBufferLayout(); - layout.push(GL.FLOAT, 2, 4, "a_pos"); + // const layout = new VertexBufferLayout(); + // layout.push(GL.FLOAT, 2, 4, "a_pos"); - const vao = new VertexArray(); - vao.addBuffer(positionBuffer, layout); + // const vao = new VertexArray(); + // vao.addBuffer(positionBuffer, layout); - this.renderer.addToDraw(indexBuffer, vao, this.vor_shader); + // this.renderer.addToDraw(indexBuffer, vao, this.vor_shader); // Setup key handling document.addEventListener('keydown', this.handleKey.bind(this)); @@ -146,6 +149,22 @@ class GameInstance { // List of [(x, y, r)] for all planets const planets = f32v(game.get_planets(), this.planet_count * 3); + const planet_points = []; + for(let i = 0; i < planets.length; i += 3) { + planet_points.push({'x': planets[i], 'y': planets[i+1]}); + } + const _bbox = f32v(game.get_viewbox(), 4); + const bbox = { + 'xl': _bbox[0], 'xr': _bbox[0] + _bbox[2], + 'yt': _bbox[1], 'yb': _bbox[1] + _bbox[3] + }; + + this.vor_builder = new VoronoiBuilder(GL, this.vor_shader, planet_points, bbox); + this.renderer.addRenderable(this.vor_builder.getRenderable()); + const players= new Array(this.planet_count).fill(undefined).map((_, i) => i); + console.log(players); + this.vor_builder.updateOwners(GL, players); + for (let i = 0; i < this.planet_count; i++) { { const transform = new UniformMatrix3fv([ @@ -211,7 +230,7 @@ class GameInstance { this.renderer.addRenderable(label.getRenderable()) } - this.vor_shader.uniform(GL, "u_planets", new Uniform3fv(planets)); + // this.vor_shader.uniform(GL, "u_planets", new Uniform3fv(planets)); // Set slider correctly SLIDER.max = this.turn_count - 1 + ''; diff --git a/frontend/www/src/voronoi/voronoi.ts b/frontend/www/src/voronoi/voronoi.ts new file mode 100644 index 0000000..079a2e1 --- /dev/null +++ b/frontend/www/src/voronoi/voronoi.ts @@ -0,0 +1,68 @@ +import { Shader } from "../webgl/shader"; +import { BBox, Point, VoronoiDiagram } from "./voronoi-core"; +import Voronoi = require("./voronoi-core"); +import { DefaultRenderable } from "../webgl/renderer"; +import { IndexBuffer, VertexBuffer } from "../webgl/buffer"; +import { VertexBufferLayout, VertexArray } from "../webgl/vertexBufferLayout"; + +function to_key(p: Point): string { + return [p.x, p.y] + ""; +} + +export class VoronoiBuilder { + inner: DefaultRenderable; + + vor: VoronoiDiagram; + a_own: number[]; + + constructor(gl: WebGLRenderingContext, shader: Shader, planets: Point[], bbox: BBox) { + const voronoi = new Voronoi(); + this.vor = voronoi.compute(planets, bbox); + + const a_pos = planets.concat(this.vor.vertices).reduce((a, b) => a.concat([-b.x, -b.y]), []); + const a_own = new Array(planets.length + this.vor.vertices.length).fill(-1); + + const vert_indcs = {}; + planets.concat(this.vor.vertices).forEach((p, i) => vert_indcs[to_key(p)] = i); + + const ids = []; + + for (let cell of this.vor.cells) { + const baseIndx = vert_indcs[to_key(cell.site)]; + console.log(baseIndx); + for (let edge of cell.halfedges) { + ids.push(baseIndx); + + ids.push(vert_indcs[to_key(edge.getStartpoint())]); + ids.push(vert_indcs[to_key(edge.getEndpoint())]) + } + } + + const ib = new IndexBuffer(gl, ids); + const vb_pos = new VertexBuffer(gl, a_pos); + const vb_own = new VertexBuffer(gl, a_own); + + const layout_pos = new VertexBufferLayout(); + layout_pos.push(gl.FLOAT, 2, 4, "a_pos"); + + const layout_own = new VertexBufferLayout(); + layout_own.push(gl.FLOAT, 1, 4, "a_own"); + + const vao = new VertexArray(); + vao.addBuffer(vb_pos, layout_pos); + vao.addBuffer(vb_own, layout_own); + + this.inner = new DefaultRenderable(ib, vao, shader, [], {}); + + this.a_own = a_own; + } + + getRenderable(): DefaultRenderable { + return this.inner; + } + + updateOwners(gl: WebGLRenderingContext, planets_owners: number[]) { + planets_owners.forEach((own, i) => this.a_own[i] = own); + this.inner.updateVAOBuffer(gl, 1, this.a_own); + } +} diff --git a/frontend/www/src/webgl/text.ts b/frontend/www/src/webgl/text.ts index 2732f11..5b9d2ed 100644 --- a/frontend/www/src/webgl/text.ts +++ b/frontend/www/src/webgl/text.ts @@ -53,14 +53,18 @@ export class Label { const uniforms = transform ? { "u_trans": transform, "u_trans_next": transform, } : {}; const ib = new IndexBuffer(gl, []); - const vb = new VertexBuffer(gl, []); + const vb_pos = new VertexBuffer(gl, []); + const vb_tex = new VertexBuffer(gl, []); - const layout = new VertexBufferLayout(); - layout.push(gl.FLOAT, 2, 4, "a_position"); - layout.push(gl.FLOAT, 2, 4, "a_texCoord"); + const layout_pos = new VertexBufferLayout(); + layout_pos.push(gl.FLOAT, 2, 4, "a_position"); + + const layout_tex = new VertexBufferLayout(); + layout_tex.push(gl.FLOAT, 2, 4, "a_texCoord"); const vao = new VertexArray(); - vao.addBuffer(vb, layout); + vao.addBuffer(vb_pos, layout_pos); + vao.addBuffer(vb_tex, layout_tex); this.inner = new DefaultRenderable(ib, vao, shader, [tex], uniforms); } @@ -71,7 +75,8 @@ export class Label { setText(gl: WebGLRenderingContext, text: string, h_align = Align.Begin, v_align = Align.Begin) { const idxs = []; - const verts = []; + const verts_pos = []; + const verts_tex = []; const letterHeight = this.font.letterHeight / this.font.textureHeight; let xPos = 0; @@ -106,10 +111,16 @@ export class Label { const letterWidth = info.width / this.font.textureWidth; const x0 = info.x / this.font.textureWidth; const y0 = info.y / this.font.textureHeight; - verts.push(xPos, yStart, x0, y0); - verts.push(xPos + dx, yStart, x0 + letterWidth, y0); - verts.push(xPos, yStart-1, x0, y0 + letterHeight); - verts.push(xPos + dx, yStart-1, x0 + letterWidth, y0 + letterHeight); + verts_pos.push(xPos, yStart); + verts_pos.push(xPos + dx, yStart); + verts_pos.push(xPos, yStart-1); + verts_pos.push(xPos + dx, yStart-1); + + verts_tex.push(x0, y0); + verts_tex.push(x0 + letterWidth, y0); + verts_tex.push(x0, y0 + letterHeight); + verts_tex.push(x0 + letterWidth, y0 + letterHeight); + xPos += dx; idxs.push(j+0, j+1, j+2, j+1, j+2, j+3); @@ -121,7 +132,8 @@ export class Label { } this.inner.updateIndexBuffer(gl, idxs); - this.inner.updateVAOBuffer(gl, 0, verts); + this.inner.updateVAOBuffer(gl, 0, verts_pos); + this.inner.updateVAOBuffer(gl, 1, verts_tex); } } diff --git a/frontend/www/static/shaders/frag/vor.glsl b/frontend/www/static/shaders/frag/vor.glsl index 62e33f5..e459d6d 100644 --- a/frontend/www/static/shaders/frag/vor.glsl +++ b/frontend/www/static/shaders/frag/vor.glsl @@ -2,29 +2,15 @@ precision mediump float; #endif -uniform vec3 u_planets[$PLANETS]; uniform vec3 u_planet_colours[$PLANETS * 2]; uniform float u_step_interval; uniform float u_time; uniform bool u_vor; +varying vec3 v_color; varying vec2 v_pos; void main() { - vec3 color = vec3(0.2); - - if (u_vor) { - float dis = 1000000.0; - - for(int i = 0; i < $PLANETS; i++) { - float d = distance(v_pos, u_planets[i].xy); - if (d < dis) { - dis = d; - color = u_planet_colours[2 * i]; - } - } - } - - gl_FragColor = vec4(color, 0.2); + gl_FragColor = vec4(v_color, 0.8); } diff --git a/frontend/www/static/shaders/vert/vor.glsl b/frontend/www/static/shaders/vert/vor.glsl index a60110d..07f9ede 100644 --- a/frontend/www/static/shaders/vert/vor.glsl +++ b/frontend/www/static/shaders/vert/vor.glsl @@ -3,24 +3,33 @@ precision mediump float; #endif attribute vec2 a_pos; +attribute float a_own; +uniform vec3 u_planet_colours[$PLANETS * 2]; uniform vec4 u_viewbox; // [x, y, width, height] uniform vec2 u_resolution; varying vec2 v_pos; +varying vec3 v_color; void main() { + int own = int(a_own); - vec2 uv = (a_pos.xy + 1.0) * 0.5; - uv = 1.0 - uv; - // uv *= -1.0; + vec2 uv = a_pos; // Viewbox's center is top left, a_position's is in the center to the screen // So translate and scale the viewbox** - uv *= u_viewbox.zw; - uv -= u_viewbox.xy + u_viewbox.zw; + uv -= u_viewbox.xy + (u_viewbox.zw * 0.5); + uv /= u_viewbox.zw * 0.5; - v_pos = uv.xy; - gl_Position = vec4(a_pos, 0.0, 1.0); + v_pos = (uv.xy + 1.0) * 0.5; + + if (own < 0) { + v_color = vec3(0., 0., 0.); + } else { + v_color = u_planet_colours[own * 2]; + } + + gl_Position = vec4(uv.xy, 0.0, 1.0); }