resize voronoi with resize + squash all in one buffer

This commit is contained in:
ajuvercr 2020-04-20 11:15:18 +02:00
parent 55dbd5ff2e
commit f8c86487d5
3 changed files with 60 additions and 57 deletions

View file

@ -1,14 +1,11 @@
import { Game } from "planetwars"; import { Game } from "planetwars";
import { memory } from "planetwars/planetwars_bg"; import { memory } from "planetwars/planetwars_bg";
import { Resizer, resizeCanvasToDisplaySize, FPSCounter, url_to_mesh, Mesh } from "./webgl/util"; import { Resizer, resizeCanvasToDisplaySize, FPSCounter, url_to_mesh, Mesh } from "./webgl/util";
import { Shader, Uniform4f, Uniform2fv, Uniform3fv, Uniform1i, Uniform1f, Uniform2f, ShaderFactory, Uniform3f, UniformMatrix3fv, UniformBool } from './webgl/shader'; import { Shader, Uniform4f, Uniform3fv, Uniform1f, Uniform2f, ShaderFactory, Uniform3f, UniformMatrix3fv, UniformBool } from './webgl/shader';
import { Renderer } from "./webgl/renderer"; import { Renderer } from "./webgl/renderer";
import { VertexBuffer, IndexBuffer } from "./webgl/buffer"; import { VertexBuffer, IndexBuffer } from "./webgl/buffer";
import { VertexBufferLayout, VertexArray } from "./webgl/vertexBufferLayout"; import { VertexBufferLayout, VertexArray } from "./webgl/vertexBufferLayout";
import { Texture } from "./webgl/texture";
import { callbackify } from "util";
import { defaultLabelFactory, LabelFactory, Align, Label } from "./webgl/text"; import { defaultLabelFactory, LabelFactory, Align, Label } from "./webgl/text";
import Voronoi = require("./voronoi/voronoi-core");
import { VoronoiBuilder } from "./voronoi/voronoi"; import { VoronoiBuilder } from "./voronoi/voronoi";
const LAYERS = { const LAYERS = {
@ -63,7 +60,7 @@ var ms_per_frame = parseInt(SPEED.value);
resizeCanvasToDisplaySize(CANVAS); resizeCanvasToDisplaySize(CANVAS);
GL.clearColor(0, 0, 0, 0); GL.clearColor(0, 0, 0, 1);
GL.clear(GL.COLOR_BUFFER_BIT); GL.clear(GL.COLOR_BUFFER_BIT);
GL.enable(GL.BLEND); GL.enable(GL.BLEND);
@ -212,14 +209,20 @@ class GameInstance {
this.renderer.addRenderable(label.getRenderable(), LAYERS.ship_label) this.renderer.addRenderable(label.getRenderable(), LAYERS.ship_label)
} }
// this.vor_shader.uniform(GL, "u_planets", new Uniform3fv(planets));
// Set slider correctly // Set slider correctly
SLIDER.max = this.turn_count - 1 + ''; SLIDER.max = this.turn_count - 1 + '';
} }
on_resize() { on_resize() {
this.resizer = new Resizer(CANVAS, [...f32v(this.game.get_viewbox(), 4)], true); this.resizer = new Resizer(CANVAS, [...f32v(this.game.get_viewbox(), 4)], true);
const _bbox = this.resizer.get_viewbox();
const bbox = {
'xl': _bbox[0], 'xr': _bbox[0] + _bbox[2],
'yt': _bbox[1], 'yb': _bbox[1] + _bbox[3]
};
this.vor_builder.resize(GL, bbox);
} }
_update_state() { _update_state() {

View file

@ -58,39 +58,63 @@ function dist(a: Point, b: Point, norm = false): number {
export class VoronoiBuilder { export class VoronoiBuilder {
inner: DefaultRenderable; inner: DefaultRenderable;
vor: VoronoiDiagram; vor: Voronoi;
a_own: number[]; planets: Point[];
constructor(gl: WebGLRenderingContext, shader: Shader, planets: Point[], bbox: BBox) { constructor(gl: WebGLRenderingContext, shader: Shader, planets: Point[], bbox: BBox) {
const voronoi = new Voronoi(); this.vor = new Voronoi();
this.planets = planets;
const ib = new IndexBuffer(gl, []);
const vb = new VertexBuffer(gl, []);
const layout = new VertexBufferLayout();
layout.push(gl.FLOAT, 2, 4, "a_pos");
layout.push(gl.FLOAT, 1, 4, "a_own");
layout.push(gl.FLOAT, 1, 4, "a_intensity");
const vao = new VertexArray();
vao.addBuffer(vb, layout);
this.inner = new DefaultRenderable(ib, vao, shader, [], {});
this.resize(gl, bbox);
}
getRenderable(): DefaultRenderable {
return this.inner;
}
resize(gl: WebGLRenderingContext, bbox: BBox) {
const start = new Date().getTime();
// This voronoi sorts the planets, then owners don't align anymore // This voronoi sorts the planets, then owners don't align anymore
const own_map = {}; const own_map = {};
planets.forEach((p, i) => own_map[to_key(p)] = i); this.planets.forEach((p, i) => own_map[to_key(p)] = i);
this.vor = voronoi.compute(planets, bbox); const vor = this.vor.compute(this.planets, bbox);
const a_pos = []; const attrs = [];
const a_own = [];
const ids = []; const ids = [];
let vertCount = 0; let vertCount = 0;
for (let i = 0; i < this.vor.cells.length; i++) { for (let i = 0; i < vor.cells.length; i++) {
const cell = this.vor.cells[i]; const cell = vor.cells[i];
const planetId = own_map[to_key(cell.site)]; const planetId = own_map[to_key(cell.site)];
const point_map = build_point_map(cell.halfedges); const point_map = build_point_map(cell.halfedges);
const centerId = vertCount++; const centerId = vertCount++;
a_pos.push(cell.site.x, cell.site.y); attrs.push(cell.site.x, cell.site.y);
a_own.push(planetId); attrs.push(planetId);
a_own.push(1); attrs.push(1);
const dist_mean = cell.halfedges.map(e => { const dist_mean = cell.halfedges.map(e => {
const start = e.getStartpoint(); const start = e.getStartpoint();
const end = e.getEndpoint(); const end = e.getEndpoint();
return dist(cell.site, start, true) + dist(cell.site, {'x': (start.x + end.x) / 2, 'y': (start.y + end.y) / 2}, true) return dist(cell.site, start, true) + dist(cell.site, { 'x': (start.x + end.x) / 2, 'y': (start.y + end.y) / 2 }, true)
}).reduce((a, b) => a + b, 0) / cell.halfedges.length / 2; }).reduce((a, b) => a + b, 0) / cell.halfedges.length / 2;
const round_fn = get_round_fn(dist_mean); const round_fn = get_round_fn(dist_mean);
@ -107,51 +131,29 @@ export class VoronoiBuilder {
ids.push(centerId); ids.push(centerId);
ids.push(vertCount++); ids.push(vertCount++);
a_pos.push(start.x, start.y); attrs.push(start.x, start.y);
a_own.push(planetId); attrs.push(planetId);
a_own.push(0); attrs.push(0);
ids.push(vertCount++); ids.push(vertCount++);
a_pos.push(center.x, center.y); attrs.push(center.x, center.y);
a_own.push(planetId); attrs.push(planetId);
a_own.push(0); attrs.push(0);
ids.push(centerId); ids.push(centerId);
ids.push(vertCount - 1); ids.push(vertCount - 1);
ids.push(vertCount++); ids.push(vertCount++);
a_pos.push(end.x, end.y); attrs.push(end.x, end.y);
a_own.push(planetId); attrs.push(planetId);
a_own.push(0); attrs.push(0);
} }
} }
const ib = new IndexBuffer(gl, ids); this.inner.updateIndexBuffer(gl, ids);
const vb_pos = new VertexBuffer(gl, a_pos); this.inner.updateVAOBuffer(gl, 0, attrs);
const vb_own = new VertexBuffer(gl, a_own); // this.inner.updateVAOBuffer(gl, 1, attrs);
const layout_pos = new VertexBufferLayout(); console.log(`Vor things took ${new Date().getTime() - start} ms!`)
layout_pos.push(gl.FLOAT, 2, 4, "a_pos");
const layout_own = new VertexBufferLayout();
layout_own.push(gl.FLOAT, 1, 4, "a_own");
layout_own.push(gl.FLOAT, 1, 4, "a_intensity");
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);
} }
} }

View file

@ -141,8 +141,6 @@ export class Renderer {
} }
render(gl: WebGLRenderingContext, frameBuffer?: WebGLFramebuffer, width?: number, height?: number) { render(gl: WebGLRenderingContext, frameBuffer?: WebGLFramebuffer, width?: number, height?: number) {
gl.clearColor(0,0,0,1);
gl.bindFramebuffer(gl.FRAMEBUFFER, frameBuffer); gl.bindFramebuffer(gl.FRAMEBUFFER, frameBuffer);
gl.viewport(0, 0, width || gl.canvas.width, height || gl.canvas.height); gl.viewport(0, 0, width || gl.canvas.width, height || gl.canvas.height);
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);