diff options
-rw-r--r-- | web/pw-visualizer/assets/res/ship.png | bin | 0 -> 4963 bytes | |||
-rw-r--r-- | web/pw-visualizer/assets/res/ship.svg | 51 | ||||
-rw-r--r-- | web/pw-visualizer/src/assets.ts | 1 | ||||
-rw-r--r-- | web/pw-visualizer/src/index.ts | 102 | ||||
-rw-r--r-- | web/pw-visualizer/src/webgl/text.ts | 8 | ||||
-rw-r--r-- | web/pw-visualizer/src/webgl/texture.ts | 26 |
6 files changed, 98 insertions, 90 deletions
diff --git a/web/pw-visualizer/assets/res/ship.png b/web/pw-visualizer/assets/res/ship.png Binary files differnew file mode 100644 index 0000000..fe289aa --- /dev/null +++ b/web/pw-visualizer/assets/res/ship.png diff --git a/web/pw-visualizer/assets/res/ship.svg b/web/pw-visualizer/assets/res/ship.svg index ee202ff..41af3ea 100644 --- a/web/pw-visualizer/assets/res/ship.svg +++ b/web/pw-visualizer/assets/res/ship.svg @@ -2,20 +2,20 @@ <!-- Created with Inkscape (http://www.inkscape.org/) --> <svg - xmlns:dc="http://purl.org/dc/elements/1.1/" - xmlns:cc="http://creativecommons.org/ns#" - xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" - xmlns:svg="http://www.w3.org/2000/svg" - xmlns="http://www.w3.org/2000/svg" - xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" - xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" - width="100mm" - height="100mm" - viewBox="0 0 100 99.999999" + width="10.231839cm" + height="19.597593cm" + viewBox="0 0 102.31839 195.97593" version="1.1" id="svg8" sodipodi:docname="ship.svg" - inkscape:version="0.92.4 (f8dce91, 2019-08-02)"> + inkscape:version="1.1.2 (0a00cf5339, 2022-02-04)" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> <defs id="defs2" /> <sodipodi:namedview @@ -26,8 +26,8 @@ inkscape:pageopacity="0.0" inkscape:pageshadow="2" inkscape:zoom="1.0993438" - inkscape:cx="676.08563" - inkscape:cy="474.10966" + inkscape:cx="424.34405" + inkscape:cy="384.32017" inkscape:document-units="mm" inkscape:current-layer="layer1" showgrid="true" @@ -35,15 +35,19 @@ fit-margin-left="0" fit-margin-right="0" fit-margin-bottom="0" - inkscape:window-width="2560" - inkscape:window-height="1417" + inkscape:window-width="1920" + inkscape:window-height="1048" inkscape:window-x="0" - inkscape:window-y="0" - inkscape:window-maximized="0" - gridtolerance="10"> + inkscape:window-y="32" + inkscape:window-maximized="1" + gridtolerance="10" + inkscape:pagecheckerboard="0" + units="cm"> <inkscape:grid type="xygrid" - id="grid894" /> + id="grid894" + originx="-160.50747" + originy="118.75037" /> </sodipodi:namedview> <metadata id="metadata5"> @@ -53,7 +57,6 @@ <dc:format>image/svg+xml</dc:format> <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> - <dc:title></dc:title> </cc:Work> </rdf:RDF> </metadata> @@ -61,17 +64,17 @@ inkscape:label="Layer 1" inkscape:groupmode="layer" id="layer1" - transform="translate(229.05372,-117.27915)"> + transform="translate(68.546255,1.4712222)"> <ellipse ry="79.47506" rx="48.672089" cy="39.779182" cx="439.0813" id="ellipse888" - style="opacity:1;fill:#00ffff;fill-opacity:1;stroke:none;stroke-width:6.61458302;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> + style="opacity:1;fill:#00ffff;fill-opacity:1;stroke:none;stroke-width:6.61458;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> <path - style="opacity:1;fill:#000000;fill-opacity:1;stroke:none;stroke-width:24.99999809;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" - d="M 800 -448.82031 C 800 -448.82031 640 -342.04689 640 -92.046875 C 640 -16.101728 661.67774 51.924976 695.88672 97.775391 C 640.96482 152.90966 593.39426 234.74166 610 267.95312 C 620.00003 287.95314 720.00001 297.95311 730 287.95312 C 751.8315 266.12161 757.39662 198.03742 758.92773 149.62305 C 772.03579 155.04778 785.80002 157.95312 800 157.95312 C 814.19998 157.95312 827.96422 155.04778 841.07227 149.62305 C 842.60338 198.03742 848.1685 266.12161 870 287.95312 C 879.99999 297.95311 979.99997 287.95314 990 267.95312 C 1006.6057 234.74166 959.03518 152.90966 904.11328 97.775391 C 938.32226 51.924976 959.99999 -16.101728 960 -92.046875 C 960.00002 -342.04689 800 -448.82031 800 -448.82031 z M 800 -352.04688 C 800 -352.04688 908.96486 -279.33252 908.96484 -109.07617 C 908.96484 -15.046189 860.17918 61.179688 800 61.179688 C 739.82082 61.179688 691.03515 -15.046189 691.03516 -109.07617 C 691.03516 -279.33252 800 -352.04687 800 -352.04688 z " + style="opacity:1;fill:#000000;fill-opacity:1;stroke:none;stroke-width:25;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="m 800,-448.82031 c 0,0 -160,106.77342 -160,356.773435 0,75.945147 21.67774,143.971851 55.88672,189.822266 C 640.96482,152.90966 593.39426,234.74166 610,267.95312 c 10.00003,20.00002 110.00001,29.99999 120,20 21.8315,-21.83151 27.39662,-89.9157 28.92773,-138.33007 13.10806,5.42473 26.87229,8.33007 41.07227,8.33007 14.19998,0 27.96422,-2.90534 41.07227,-8.33007 1.53111,48.41437 7.09623,116.49856 28.92773,138.33007 9.99999,9.99999 109.99997,2e-5 120,-20 C 1006.6057,234.74166 959.03518,152.90966 904.11328,97.775391 938.32226,51.924976 959.99999,-16.101728 960,-92.046875 960.00002,-342.04689 800,-448.82031 800,-448.82031 Z m 0,96.77343 c 0,0 108.96486,72.71436 108.96484,242.97071 0,94.029981 -48.78566,170.255858 -108.96484,170.255858 -60.17918,0 -108.96485,-76.225877 -108.96484,-170.255858 C 691.03516,-279.33252 800,-352.04687 800,-352.04688 Z" transform="matrix(0.26458333,0,0,0.26458333,-229.05372,117.27915)" id="path4600" /> </g> diff --git a/web/pw-visualizer/src/assets.ts b/web/pw-visualizer/src/assets.ts index be155c5..5fa5215 100644 --- a/web/pw-visualizer/src/assets.ts +++ b/web/pw-visualizer/src/assets.ts @@ -5,6 +5,7 @@ export {default as marsSvg} from "../assets/res/mars.svg"; export {default as venusSvg} from "../assets/res/venus.svg"; export {default as earthPng} from "../assets/res/earth.png"; +export {default as shipPng} from "../assets/res/ship.png"; export {default as fontPng} from "../assets/res/font.png"; diff --git a/web/pw-visualizer/src/index.ts b/web/pw-visualizer/src/index.ts index 6f2c1b4..bee1bab 100644 --- a/web/pw-visualizer/src/index.ts +++ b/web/pw-visualizer/src/index.ts @@ -1,6 +1,4 @@ import { Game } from "planetwars-rs"; -// import { memory } from "planetwars-rs/planetwars_rs_bg"; -// const memory = planetwars_bg.memory; import type { Dictionary } from './webgl/util'; import type { BBox } from "./voronoi/voronoi-core"; @@ -8,8 +6,6 @@ import { Resizer, resizeCanvasToDisplaySize, FPSCounter, - url_to_mesh, - Mesh, } from "./webgl/util"; import { Shader, @@ -40,14 +36,6 @@ function to_bbox(box: number[]): BBox { }; } -// function f32v(ptr: number, size: number): Float32Array { -// return new Float32Array(memory.buffer, ptr, size); -// } - -// function i32v(ptr: number, size: number): Int32Array { -// return new Int32Array(memory.buffer, ptr, size); -// } - export function set_game_name(name: string) { ELEMENTS["name"].innerHTML = name; } @@ -142,6 +130,7 @@ export class GameInstance { ship_ibo: IndexBuffer; ship_vao: VertexArray; + ship_texture: Texture; // TODO: find a better way max_num_ships: number; @@ -161,8 +150,9 @@ export class GameInstance { constructor( game: Game, - meshes: Mesh[], - ship_mesh: Mesh, + planets_textures: Texture[], + ship_texture: Texture, + font_texture: Texture, shaders: Dictionary<ShaderFactory> ) { this.game = game; @@ -178,10 +168,12 @@ export class GameInstance { }); this.masked_image_shader = shaders["masked_image"].create_shader(GL); - this.text_factory = defaultLabelFactory(GL, this.image_shader); + this.text_factory = defaultLabelFactory(GL, font_texture, this.image_shader); this.planet_labels = []; this.ship_labels = []; + this.ship_texture = ship_texture + this.resizer = new Resizer(CANVAS, [...game.get_viewbox()], true); this.renderer = new Renderer(); this.game.update_turn(0); @@ -191,15 +183,8 @@ export class GameInstance { // List of [(x, y, r)] for all planets this._create_voronoi(planets); - this._create_planets(planets, meshes); - - // create_shipes - this.ship_ibo = new IndexBuffer(GL, ship_mesh.cells); - const ship_positions = new VertexBuffer(GL, ship_mesh.positions); - const ship_layout = new VertexBufferLayout(); - ship_layout.push(GL.FLOAT, 3, 4, "a_position"); - this.ship_vao = new VertexArray(); - this.ship_vao.addBuffer(ship_positions, ship_layout); + this._create_planets(planets, planets_textures); + this.max_num_ships = 0; // Set slider correctly @@ -236,9 +221,7 @@ export class GameInstance { this.renderer.addRenderable(this.vor_builder.getRenderable(), LAYERS.vor); } - _create_planets(planets: Float32Array, meshes: Mesh[]) { - const earth = Texture.fromImage(GL, assets.earthPng, 'earth'); - + _create_planets(planets: Float32Array, planets_textures: Texture[]) { for (let i = 0; i < this.planet_count; i++) { { const transform = new UniformMatrix3fv([ @@ -280,7 +263,7 @@ export class GameInstance { u_trans_next: transform, }; - const renderable = new DefaultRenderable(ib, vao, this.masked_image_shader, [earth], uniforms); + const renderable = new DefaultRenderable(ib, vao, this.masked_image_shader, [planets_textures[0]], uniforms); this.renderer.addRenderable(renderable, LAYERS.planet); @@ -361,16 +344,39 @@ export class GameInstance { const ship_colours = this.game.get_ship_colours(); for (let i = this.max_num_ships; i < ship_counts.length; i++) { - this.renderer.addToDraw( - this.ship_ibo, - this.ship_vao, - this.shader, - {}, - [], - LAYERS.ship - ); + const gl = GL; + const ib = new IndexBuffer(gl, [ + 0, 1, 2, + 1, 2, 3 + ]); + const ratio = this.ship_texture.getWidth() / this.ship_texture.getHeight(); + const vb_pos = new VertexBuffer(gl, [ + -ratio, 1, + ratio, 1, + -ratio, -1, + ratio, -1 + ]); + const vb_tex = new VertexBuffer(gl, [ + 0, 0, + 1, 0, + 0, 1, + 1, 1, + ]); + + 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_pos, layout_pos); + vao.addBuffer(vb_tex, layout_tex); + const renderable = new DefaultRenderable(ib, vao, this.masked_image_shader, [this.ship_texture], {}); + this.renderer.addRenderable(renderable, LAYERS.ship); const label = this.text_factory.build(GL); + this.ship_labels.push(label); this.renderer.addRenderable(label.getRenderable(), LAYERS.ship_label); } @@ -579,18 +585,17 @@ export class GameInstance { } var game_instance: GameInstance; -var meshes: Mesh[]; +var textures: Texture[]; var shaders: Dictionary<ShaderFactory>; export async function set_instance(source: string): Promise<GameInstance> { // TODO: embed shader programs - if (!meshes || !shaders) { - const mesh_promises = [ - assets.shipSvg, - assets.earthSvg, - assets.marsSvg, - assets.venusSvg, - ].map(url_to_mesh); + if (!textures || !shaders) { + const texture_promises = [ + Texture.fromImage(GL, assets.fontPng, "font"), + Texture.fromImage(GL, assets.shipPng, "ship"), + Texture.fromImage(GL, assets.earthPng, "earth") + ]; const shader_promies = [ (async () => @@ -628,8 +633,8 @@ export async function set_instance(source: string): Promise<GameInstance> { ]; let shaders_array: [string, ShaderFactory][]; - [meshes, shaders_array] = await Promise.all([ - Promise.all(mesh_promises), + [textures, shaders_array] = await Promise.all([ + Promise.all(texture_promises), Promise.all(shader_promies), ]); @@ -641,8 +646,9 @@ export async function set_instance(source: string): Promise<GameInstance> { game_instance = new GameInstance( Game.new(source), - meshes.slice(1), - meshes[0], + textures.slice(2), + textures[1], + textures[0], shaders ); diff --git a/web/pw-visualizer/src/webgl/text.ts b/web/pw-visualizer/src/webgl/text.ts index cb72a42..1ae6f37 100644 --- a/web/pw-visualizer/src/webgl/text.ts +++ b/web/pw-visualizer/src/webgl/text.ts @@ -33,8 +33,8 @@ export class LabelFactory { font: FontInfo; shader: Shader; - constructor(gl: WebGLRenderingContext, loc: string, font: FontInfo, shader: Shader) { - this.texture = Texture.fromImage(gl, loc, 'font'); + constructor(gl: WebGLRenderingContext, fontTexture: Texture, font: FontInfo, shader: Shader) { + this.texture = fontTexture; this.font = font; this.shader = shader; } @@ -144,7 +144,7 @@ export class Label { } } -export function defaultLabelFactory(gl: WebGLRenderingContext, shader: Shader): LabelFactory { +export function defaultLabelFactory(gl: WebGLRenderingContext, fontTexture: Texture, shader: Shader): LabelFactory { const fontInfo = { letterHeight: 8, spaceWidth: 8, @@ -195,5 +195,5 @@ export function defaultLabelFactory(gl: WebGLRenderingContext, shader: Shader): }, }; - return new LabelFactory(gl, fontPng, fontInfo, shader); + return new LabelFactory(gl, fontTexture, fontInfo, shader); } diff --git a/web/pw-visualizer/src/webgl/texture.ts b/web/pw-visualizer/src/webgl/texture.ts index 9d6adcf..faafe76 100644 --- a/web/pw-visualizer/src/webgl/texture.ts +++ b/web/pw-visualizer/src/webgl/texture.ts @@ -11,15 +11,18 @@ export class Texture { gl: WebGLRenderingContext, path: string, name: string, - ): Texture { - const out = new Texture(gl, name); - - const image = new Image(); - image.onload = out.setImage.bind(out, gl, image); - image.onerror = error; - image.src = path; - - return out; + ): Promise<Texture> { + return new Promise((resolve, reject) => { + const out = new Texture(gl, name); + + const image = new Image(); + image.onload = () => { + out.setImage(gl, image); + resolve(out); + } + image.onerror = reject; + image.src = path; + }) } static fromRenderer( @@ -99,8 +102,3 @@ export class Texture { return this.height; } } - -function error(e: any) { - console.error("IMAGE LOAD ERROR"); - console.error(e); -} |