From 366f3361d92f19a570d0aca54264463e6ab82520 Mon Sep 17 00:00:00 2001 From: ajuvercr Date: Wed, 18 Sep 2019 12:29:56 +0200 Subject: [PATCH] colourful planets --- frontend/src/lib.rs | 22 ++++---- frontend/src/types.rs | 4 +- frontend/src/utils.rs | 16 +++--- frontend/www/index.ts | 45 ++++++++++----- frontend/www/static/res/style.css | 4 ++ frontend/www/static/shaders/frag/simple.glsl | 13 +++-- frontend/www/webgl/index.ts | 26 +++++---- frontend/www/webgl/shader.ts | 12 ++-- frontend/www/webgl/util.ts | 58 ++++++++++---------- 9 files changed, 113 insertions(+), 87 deletions(-) diff --git a/frontend/src/lib.rs b/frontend/src/lib.rs index 2ee5504..740b7bf 100644 --- a/frontend/src/lib.rs +++ b/frontend/src/lib.rs @@ -23,11 +23,11 @@ pub struct Game { turn: usize, /* put extra shit here */ - planets: Vec>, - view_box: Vec, + planets: Vec>, + view_box: Vec, - ship_locations: Vec>, - current_planet_colours: Vec>, + ship_locations: Vec>, + current_planet_colours: Vec>, } #[wasm_bindgen] @@ -41,7 +41,7 @@ impl Game { ).collect(); Self { - planets: utils::get_planets(&states[0].planets, 10.0), + planets: utils::get_planets(&states[0].planets, 2.0), view_box: utils::caclulate_viewbox(&states[0].planets), turn: 0, states, @@ -50,15 +50,15 @@ impl Game { } } - pub fn get_viewbox(&self) -> *const f64 { + pub fn get_viewbox(&self) -> *const f32 { self.view_box.as_ptr() } - pub fn get_planets(&self) -> *const Vec3 { + pub fn get_planets(&self) -> *const Vec3 { self.planets.as_ptr() } - pub fn get_planet_colors(&self) -> *const Vec3 { + pub fn get_planet_colors(&self) -> *const Vec3 { self.current_planet_colours.as_ptr() } @@ -71,7 +71,7 @@ impl Game { } pub fn update_turn(&mut self, turn: usize) { - self.turn = turn.min(self.states.len()); + self.turn = turn.min(self.states.len() -1); self.update_planet_colours(); self.update_ship_locations() @@ -88,7 +88,7 @@ impl Game { } - // pub fn add_location(&mut self, x: f64, y: f64, angle: f64) { + // pub fn add_location(&mut self, x: f32, y: f32, angle: f32) { // self.current_turn.push( // Location { x, y, angle} // ); @@ -98,7 +98,7 @@ impl Game { self.ship_locations.len() } - pub fn get_ship_locations(&self) -> *const Mat3 { + pub fn get_ship_locations(&self) -> *const Mat3 { self.ship_locations.as_ptr() } } diff --git a/frontend/src/types.rs b/frontend/src/types.rs index 260030b..e1a4594 100644 --- a/frontend/src/types.rs +++ b/frontend/src/types.rs @@ -11,8 +11,8 @@ pub struct Expedition { #[derive(Debug, Clone, Serialize, Deserialize)] pub struct Planet { pub ship_count: u64, - pub x: f64, - pub y: f64, + pub x: f32, + pub y: f32, pub owner: Option, pub name: String, } diff --git a/frontend/src/utils.rs b/frontend/src/utils.rs index c76463a..b0c9115 100644 --- a/frontend/src/utils.rs +++ b/frontend/src/utils.rs @@ -12,12 +12,12 @@ pub fn set_panic_hook() { use octoon_math::{Vec3}; /// this is total extra, so it the planet viewbox is like 100px wide, it will now be in total 110 pixels wide -static VIEWBOX_SCALE: f64 = 0.1; +static VIEWBOX_SCALE: f32 = 0.1; -pub static COLORS: [[f64; 3]; 10] = [ - [1.0, 0.0, 0.0], - [1.0, 0.0, 0.0], - [1.0, 0.0, 0.0], +pub static COLORS: [[f32; 3]; 10] = [ + [0.5, 0.5, 0.5], + [0.0, 1.0, 0.0], + [0.0, 0.0, 1.0], [1.0, 0.0, 0.0], [1.0, 0.0, 0.0], [1.0, 0.0, 0.0], @@ -29,7 +29,7 @@ pub static COLORS: [[f64; 3]; 10] = [ use super::types; -pub fn caclulate_viewbox(planets: &Vec) -> Vec { +pub fn caclulate_viewbox(planets: &Vec) -> Vec { let mut iter = planets.iter(); let init = match iter.next() { @@ -41,11 +41,11 @@ pub fn caclulate_viewbox(planets: &Vec) -> Vec { .fold(init, |(min_x, min_y, max_x, max_y), p| (min_x.min(p.x), min_y.min(p.y), max_x.max(p.x), max_y.max(p.y))); let (width, height) = (max_x - min_x, max_y - min_y); - let (dx, dy) = (VIEWBOX_SCALE * width, VIEWBOX_SCALE * height); + let (dx, dy) = ((VIEWBOX_SCALE * width).max(6.0), (VIEWBOX_SCALE * height).max(6.0)); vec![min_x - dx/2.0, min_y - dy/2.0, width + dx, height + dy] } -pub fn get_planets(planets: &Vec, r: f64) -> Vec> { +pub fn get_planets(planets: &Vec, r: f32) -> Vec> { planets.iter().map(|p| Vec3::new(p.x, p.y, r)).collect() } diff --git a/frontend/www/index.ts b/frontend/www/index.ts index 57562af..e70ad6c 100644 --- a/frontend/www/index.ts +++ b/frontend/www/index.ts @@ -7,6 +7,14 @@ import { VertexBuffer, IndexBuffer } from "./webgl/buffer"; import { VertexBufferLayout, VertexArray } from "./webgl/vertexBufferLayout"; import { callbackify } from "util"; +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); +} + const COUNTER = new FPSCounter(); const LOADER = document.getElementById("loader"); @@ -57,39 +65,46 @@ ShaderFactory.create_factory( LOCATION + "static/shaders/frag/simple.glsl", LOCATION + "static/shaders/vert/simple.glsl" ).then((e) => SHADERFACOTRY = e); - -function create_array(ptr: number, size: number): Float64Array { - return new Float64Array(memory.buffer, ptr, size); -} - class GameInstance { resizer: Resizer; game: Game; shader: Shader; renderer: Renderer; + planet_count: number; + + last_time = 0; + frame = -1; constructor(game: Game) { this.game = game; - this.shader = SHADERFACOTRY.create_shader(GL, {"MAX_CIRCLES": "50"}); - this.resizer = new Resizer(CANVAS, [...create_array(game.get_viewbox(), 4)], true); + this.planet_count = this.game.get_planet_count(); + this.shader = SHADERFACOTRY.create_shader(GL, {"MAX_CIRCLES": ''+this.planet_count}); + this.resizer = new Resizer(CANVAS, [...f32v(game.get_viewbox(), 4)], true); this.renderer = new Renderer(); this.renderer.addToDraw(indexBuffer, vao, this.shader); + + // this.game.update_turn(this.frame); + + console.log(f32v(this.game.get_planet_colors(), 3 * this.game.get_planet_count())); + // console.log(this.resizer.get_viewbox()); } render(time: number) { - this.shader.uniform(GL, "u_circle_count", new Uniform1i(3)); + if (time > this.last_time + 100) { + this.last_time = time; + this.frame ++; + this.game.update_turn(this.frame); + } + + this.shader.uniform(GL, "u_circle_count", new Uniform1i(this.planet_count)); this.shader.uniform(GL, "u_time", new Uniform1f(time * 0.001)); this.shader.uniform(GL, "u_mouse", new Uniform2f(this.resizer.get_mouse_pos())); this.shader.uniform(GL, "u_viewbox", new Uniform4f(this.resizer.get_viewbox())); this.shader.uniform(GL, "u_resolution", new Uniform2f(RESOLUTION)); - this.shader.uniform(GL, "u_circles", new Uniform3fv([ - 0, 0, 3.5, - -2, -2, 2, - 5, 2, 4, - ])); - this.shader.uniform(GL, "u_color", new Uniform4f([1, 1, 0, 1])); + this.shader.uniform(GL, "u_circles", new Uniform3fv(f32v(this.game.get_planets(), 3 * this.planet_count))); + this.shader.uniform(GL, "u_colors", new Uniform3fv(f32v(this.game.get_planet_colors(), 3 * this.planet_count))); this.renderer.render(GL); COUNTER.frame(time); @@ -103,7 +118,7 @@ export function set_instance(game: Game) { console.log(game.turn_count()); - console.log(create_array(game.get_viewbox(), 4)); + console.log(f32v(game.get_viewbox(), 4)); } diff --git a/frontend/www/static/res/style.css b/frontend/www/static/res/style.css index f5bc236..5fb138b 100644 --- a/frontend/www/static/res/style.css +++ b/frontend/www/static/res/style.css @@ -1,3 +1,6 @@ +body { + background-color: #333; +} .loading { position: relative; @@ -21,6 +24,7 @@ #c { position: relative; + background-color: black; } /* ---------------------------------------------- diff --git a/frontend/www/static/shaders/frag/simple.glsl b/frontend/www/static/shaders/frag/simple.glsl index 9f6fb42..6b78958 100644 --- a/frontend/www/static/shaders/frag/simple.glsl +++ b/frontend/www/static/shaders/frag/simple.glsl @@ -8,7 +8,7 @@ uniform vec2 u_mouse; uniform vec4 u_viewbox; // [x, y, width, height] uniform vec2 u_resolution; uniform vec3 u_circles[$MAX_CIRCLES]; -uniform vec4 u_color; +uniform vec3 u_colors[$MAX_CIRCLES]; varying vec2 v_pos; @@ -16,12 +16,17 @@ void main() { vec2 uv = v_pos; float alpha = 0.0; + vec3 color; for (int i = 0; i < $MAX_CIRCLES; i++ ){ if (i >= u_circle_count) { break; } float d = distance(uv.xy, u_circles[i].xy); - alpha = max(1.0 - d/u_circles[i].z, alpha); + float a = 1.0 - d/u_circles[i].z; + if (a > alpha) { + alpha = a; + color = u_colors[i]; + } } - gl_FragColor = u_color; - gl_FragColor.w *= alpha; + gl_FragColor = vec4(color, alpha); + // gl_FragColor.w *= alpha; } diff --git a/frontend/www/webgl/index.ts b/frontend/www/webgl/index.ts index f3e8616..8a7c39f 100644 --- a/frontend/www/webgl/index.ts +++ b/frontend/www/webgl/index.ts @@ -17,7 +17,7 @@ async function main() { var canvas = document.getElementById("c"); const resolution = [canvas.width, canvas.height]; - const resizer = new Resizer(canvas, [0, 0, 900, 900], true); + const resizer = new Resizer(canvas, [-100, -10, 200, 20], true); var gl = canvas.getContext("webgl"); if (!gl) { @@ -88,9 +88,9 @@ async function main() { program.uniform(gl, "u_viewbox", new Uniform4f(resizer.get_viewbox())); program.uniform(gl, "u_resolution", new Uniform2f(resolution)); program.uniform(gl, "u_circles", new Uniform3fv([ - 450, 450, 100, - 200, 200, 200, - 900, 0, 300, + 0, 0, 3.5, + -2, -2, 2, + 5, 2, 4, ])); program.uniform(gl, "u_color", new Uniform4f([1, blue, 0, 1])); @@ -105,11 +105,13 @@ async function main() { main(); -const loader = document.getElementById("loader"); -setInterval(() => { - if (loader.classList.contains("loading")) { - loader.classList.remove("loading") - } else { - loader.classList.add("loading"); - } -}, 2000); +document.getElementById("loader").classList.remove("loading"); + +// const loader = document.getElementById("loader"); +// setInterval(() => { +// if (loader.classList.contains("loading")) { +// loader.classList.remove("loading") +// } else { +// loader.classList.add("loading"); +// } +// }, 2000); diff --git a/frontend/www/webgl/shader.ts b/frontend/www/webgl/shader.ts index aba96fd..6f99d3c 100644 --- a/frontend/www/webgl/shader.ts +++ b/frontend/www/webgl/shader.ts @@ -201,8 +201,8 @@ export interface Uniform { } export class Uniform2fv implements Uniform { - data: number[]; - constructor(data: number[]) { + data: number[] | Float32Array; + constructor(data: number[] | Float32Array) { this.data = data; } @@ -212,8 +212,8 @@ export class Uniform2fv implements Uniform { } export class Uniform3fv implements Uniform { - data: number[]; - constructor(data: number[]) { + data: number[] | Float32Array; + constructor(data: number[] | Float32Array) { this.data = data; } @@ -239,8 +239,8 @@ export class Uniform3f implements Uniform { } export class Uniform1iv implements Uniform { - data: number[]; - constructor(data: number[]) { + data: number[] | Int32List; + constructor(data: number[] | Int32List) { this.data = data; } diff --git a/frontend/www/webgl/util.ts b/frontend/www/webgl/util.ts index 007cb53..fc6fc07 100644 --- a/frontend/www/webgl/util.ts +++ b/frontend/www/webgl/util.ts @@ -48,51 +48,48 @@ export class FPSCounter { } export class Resizer { - hoovering: boolean; - dragging: boolean; + hoovering = false; + dragging = false; - mouse_pos: number[]; - last_drag: number[]; + mouse_pos = [0, 0]; + last_drag = [0, 0]; viewbox: number[]; orig_viewbox: number[]; - el_width: number; + el_box: number[]; scaleX = 1; scaleY = 1; constructor(el: HTMLCanvasElement, viewbox: number[], keep_aspect_ratio=false) { - console.log("viewbox:" + viewbox); - this.hoovering = false; - this.dragging = false; - - this.mouse_pos = [0, 0]; - this.last_drag = [0, 0]; this.viewbox = [...viewbox]; + this.el_box = [el.width, el.height]; if (keep_aspect_ratio) { const or_width = this.viewbox[2]; const or_height = this.viewbox[3]; - const scaleX = el.height / el.width; - if (scaleX < 1) { - this.scaleX= 1 / scaleX; - this.viewbox[2] *= this.scaleX; + const width_percentage = this.viewbox[2] / el.width; + const height_percentage = this.viewbox[3] / el.height; + + if (width_percentage < height_percentage) { + // width should be larger + this.viewbox[2] = height_percentage * el.width; } else { - this.scaleY = scaleX; - this.viewbox[3] *= scaleX; + this.viewbox[3] = width_percentage * el.height; + // height should be larger } this.viewbox[0] -= (this.viewbox[2] - or_width) / 2; this.viewbox[1] -= (this.viewbox[3] - or_height) / 2; + + this.scaleX = this.viewbox[2] / this.viewbox[3]; } this.orig_viewbox = [...this.viewbox]; - this.el_width = el.width; - el.addEventListener("mouseenter", this.mouseenter.bind(this), { capture: false, passive: true}); el.addEventListener("mouseleave", this.mouseleave.bind(this), { capture: false, passive: true}); el.addEventListener("mousemove", this.mousemove.bind(this), { capture: false, passive: true}); @@ -102,7 +99,7 @@ export class Resizer { window.addEventListener('wheel', this.wheel.bind(this), { capture: false, passive: true}); } - clip_viewbox() { + _clip_viewbox() { this.viewbox[0] = Math.max(this.viewbox[0], this.orig_viewbox[0]); this.viewbox[1] = Math.max(this.viewbox[1], this.orig_viewbox[1]); @@ -116,20 +113,21 @@ export class Resizer { mouseleave() { this.hoovering = false; - this.dragging = false; } mousemove(e: MouseEvent) { - this.mouse_pos = [e.offsetX, this.el_width - e.offsetY]; + this.mouse_pos = [e.offsetX, this.el_box[1] - e.offsetY]; if (this.dragging) { - const scale = this.viewbox[3] / this.orig_viewbox[3]; - this.viewbox[0] += (this.last_drag[0] - this.mouse_pos[0]) * scale; - this.viewbox[1] += (this.last_drag[1] - this.mouse_pos[1]) * scale; + const scaleX = this.viewbox[2] / this.el_box[0]; + const scaleY = this.viewbox[3] / this.el_box[1]; + + this.viewbox[0] += (this.last_drag[0] - this.mouse_pos[0]) * scaleX; + this.viewbox[1] += (this.last_drag[1] - this.mouse_pos[1]) * scaleY; this.last_drag = [...this.mouse_pos]; - this.clip_viewbox(); + this._clip_viewbox(); } } @@ -144,17 +142,19 @@ export class Resizer { wheel(e: WheelEvent) { if (this.hoovering) { - const dx = e.deltaY * this.scaleX; + const delta = e.deltaY > 0 ? 0.1 * this.viewbox[2] : -0.1 * this.viewbox[2]; + const dx = delta * this.scaleX; + this.viewbox[2] += dx; this.viewbox[0] -= dx / 2; this.viewbox[2] = Math.min(this.viewbox[2], this.orig_viewbox[2]); - const dy = e.deltaY * this.scaleY; + const dy = delta * this.scaleY; this.viewbox[3] += dy; this.viewbox[1] -= dy / 2; this.viewbox[3] = Math.min(this.viewbox[3], this.orig_viewbox[3]); - this.clip_viewbox(); + this._clip_viewbox(); } }