colourful planets

This commit is contained in:
ajuvercr 2019-09-18 12:29:56 +02:00
parent aa97ec8837
commit 366f3361d9
9 changed files with 113 additions and 87 deletions

View file

@ -23,11 +23,11 @@ pub struct Game {
turn: usize, turn: usize,
/* put extra shit here */ /* put extra shit here */
planets: Vec<Vec3<f64>>, planets: Vec<Vec3<f32>>,
view_box: Vec<f64>, view_box: Vec<f32>,
ship_locations: Vec<Mat3<f64>>, ship_locations: Vec<Mat3<f32>>,
current_planet_colours: Vec<Vec3<f64>>, current_planet_colours: Vec<Vec3<f32>>,
} }
#[wasm_bindgen] #[wasm_bindgen]
@ -41,7 +41,7 @@ impl Game {
).collect(); ).collect();
Self { 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), view_box: utils::caclulate_viewbox(&states[0].planets),
turn: 0, turn: 0,
states, 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() self.view_box.as_ptr()
} }
pub fn get_planets(&self) -> *const Vec3<f64> { pub fn get_planets(&self) -> *const Vec3<f32> {
self.planets.as_ptr() self.planets.as_ptr()
} }
pub fn get_planet_colors(&self) -> *const Vec3<f64> { pub fn get_planet_colors(&self) -> *const Vec3<f32> {
self.current_planet_colours.as_ptr() self.current_planet_colours.as_ptr()
} }
@ -71,7 +71,7 @@ impl Game {
} }
pub fn update_turn(&mut self, turn: usize) { 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_planet_colours();
self.update_ship_locations() 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( // self.current_turn.push(
// Location { x, y, angle} // Location { x, y, angle}
// ); // );
@ -98,7 +98,7 @@ impl Game {
self.ship_locations.len() self.ship_locations.len()
} }
pub fn get_ship_locations(&self) -> *const Mat3<f64> { pub fn get_ship_locations(&self) -> *const Mat3<f32> {
self.ship_locations.as_ptr() self.ship_locations.as_ptr()
} }
} }

View file

@ -11,8 +11,8 @@ pub struct Expedition {
#[derive(Debug, Clone, Serialize, Deserialize)] #[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Planet { pub struct Planet {
pub ship_count: u64, pub ship_count: u64,
pub x: f64, pub x: f32,
pub y: f64, pub y: f32,
pub owner: Option<u32>, pub owner: Option<u32>,
pub name: String, pub name: String,
} }

View file

@ -12,12 +12,12 @@ pub fn set_panic_hook() {
use octoon_math::{Vec3}; 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 /// 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] = [ pub static COLORS: [[f32; 3]; 10] = [
[1.0, 0.0, 0.0], [0.5, 0.5, 0.5],
[1.0, 0.0, 0.0], [0.0, 1.0, 0.0],
[1.0, 0.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], [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; use super::types;
pub fn caclulate_viewbox(planets: &Vec<types::Planet>) -> Vec<f64> { pub fn caclulate_viewbox(planets: &Vec<types::Planet>) -> Vec<f32> {
let mut iter = planets.iter(); let mut iter = planets.iter();
let init = match iter.next() { let init = match iter.next() {
@ -41,11 +41,11 @@ pub fn caclulate_viewbox(planets: &Vec<types::Planet>) -> Vec<f64> {
.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))); .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 (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] vec![min_x - dx/2.0, min_y - dy/2.0, width + dx, height + dy]
} }
pub fn get_planets(planets: &Vec<types::Planet>, r: f64) -> Vec<Vec3<f64>> { pub fn get_planets(planets: &Vec<types::Planet>, r: f32) -> Vec<Vec3<f32>> {
planets.iter().map(|p| Vec3::new(p.x, p.y, r)).collect() planets.iter().map(|p| Vec3::new(p.x, p.y, r)).collect()
} }

View file

@ -7,6 +7,14 @@ import { VertexBuffer, IndexBuffer } from "./webgl/buffer";
import { VertexBufferLayout, VertexArray } from "./webgl/vertexBufferLayout"; import { VertexBufferLayout, VertexArray } from "./webgl/vertexBufferLayout";
import { callbackify } from "util"; 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 COUNTER = new FPSCounter();
const LOADER = document.getElementById("loader"); const LOADER = document.getElementById("loader");
@ -57,39 +65,46 @@ ShaderFactory.create_factory(
LOCATION + "static/shaders/frag/simple.glsl", LOCATION + "static/shaders/vert/simple.glsl" LOCATION + "static/shaders/frag/simple.glsl", LOCATION + "static/shaders/vert/simple.glsl"
).then((e) => SHADERFACOTRY = e); ).then((e) => SHADERFACOTRY = e);
function create_array(ptr: number, size: number): Float64Array {
return new Float64Array(memory.buffer, ptr, size);
}
class GameInstance { class GameInstance {
resizer: Resizer; resizer: Resizer;
game: Game; game: Game;
shader: Shader; shader: Shader;
renderer: Renderer; renderer: Renderer;
planet_count: number;
last_time = 0;
frame = -1;
constructor(game: Game) { constructor(game: Game) {
this.game = game; this.game = game;
this.shader = SHADERFACOTRY.create_shader(GL, {"MAX_CIRCLES": "50"}); this.planet_count = this.game.get_planet_count();
this.resizer = new Resizer(CANVAS, [...create_array(game.get_viewbox(), 4)], true); 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 = new Renderer();
this.renderer.addToDraw(indexBuffer, vao, this.shader); 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) { 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_time", new Uniform1f(time * 0.001));
this.shader.uniform(GL, "u_mouse", new Uniform2f(this.resizer.get_mouse_pos())); 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_viewbox", new Uniform4f(this.resizer.get_viewbox()));
this.shader.uniform(GL, "u_resolution", new Uniform2f(RESOLUTION)); this.shader.uniform(GL, "u_resolution", new Uniform2f(RESOLUTION));
this.shader.uniform(GL, "u_circles", new Uniform3fv([ this.shader.uniform(GL, "u_circles", new Uniform3fv(f32v(this.game.get_planets(), 3 * this.planet_count)));
0, 0, 3.5, this.shader.uniform(GL, "u_colors", new Uniform3fv(f32v(this.game.get_planet_colors(), 3 * this.planet_count)));
-2, -2, 2,
5, 2, 4,
]));
this.shader.uniform(GL, "u_color", new Uniform4f([1, 1, 0, 1]));
this.renderer.render(GL); this.renderer.render(GL);
COUNTER.frame(time); COUNTER.frame(time);
@ -103,7 +118,7 @@ export function set_instance(game: Game) {
console.log(game.turn_count()); console.log(game.turn_count());
console.log(create_array(game.get_viewbox(), 4)); console.log(f32v(game.get_viewbox(), 4));
} }

View file

@ -1,3 +1,6 @@
body {
background-color: #333;
}
.loading { .loading {
position: relative; position: relative;
@ -21,6 +24,7 @@
#c { #c {
position: relative; position: relative;
background-color: black;
} }
/* ---------------------------------------------- /* ----------------------------------------------

View file

@ -8,7 +8,7 @@ uniform vec2 u_mouse;
uniform vec4 u_viewbox; // [x, y, width, height] uniform vec4 u_viewbox; // [x, y, width, height]
uniform vec2 u_resolution; uniform vec2 u_resolution;
uniform vec3 u_circles[$MAX_CIRCLES]; uniform vec3 u_circles[$MAX_CIRCLES];
uniform vec4 u_color; uniform vec3 u_colors[$MAX_CIRCLES];
varying vec2 v_pos; varying vec2 v_pos;
@ -16,12 +16,17 @@ void main() {
vec2 uv = v_pos; vec2 uv = v_pos;
float alpha = 0.0; float alpha = 0.0;
vec3 color;
for (int i = 0; i < $MAX_CIRCLES; i++ ){ for (int i = 0; i < $MAX_CIRCLES; i++ ){
if (i >= u_circle_count) { break; } if (i >= u_circle_count) { break; }
float d = distance(uv.xy, u_circles[i].xy); 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 = vec4(color, alpha);
gl_FragColor.w *= alpha; // gl_FragColor.w *= alpha;
} }

View file

@ -17,7 +17,7 @@ async function main() {
var canvas = <HTMLCanvasElement>document.getElementById("c"); var canvas = <HTMLCanvasElement>document.getElementById("c");
const resolution = [canvas.width, canvas.height]; 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"); var gl = canvas.getContext("webgl");
if (!gl) { if (!gl) {
@ -88,9 +88,9 @@ async function main() {
program.uniform(gl, "u_viewbox", new Uniform4f(resizer.get_viewbox())); program.uniform(gl, "u_viewbox", new Uniform4f(resizer.get_viewbox()));
program.uniform(gl, "u_resolution", new Uniform2f(resolution)); program.uniform(gl, "u_resolution", new Uniform2f(resolution));
program.uniform(gl, "u_circles", new Uniform3fv([ program.uniform(gl, "u_circles", new Uniform3fv([
450, 450, 100, 0, 0, 3.5,
200, 200, 200, -2, -2, 2,
900, 0, 300, 5, 2, 4,
])); ]));
program.uniform(gl, "u_color", new Uniform4f([1, blue, 0, 1])); program.uniform(gl, "u_color", new Uniform4f([1, blue, 0, 1]));
@ -105,11 +105,13 @@ async function main() {
main(); main();
const loader = document.getElementById("loader"); document.getElementById("loader").classList.remove("loading");
setInterval(() => {
if (loader.classList.contains("loading")) { // const loader = document.getElementById("loader");
loader.classList.remove("loading") // setInterval(() => {
} else { // if (loader.classList.contains("loading")) {
loader.classList.add("loading"); // loader.classList.remove("loading")
} // } else {
}, 2000); // loader.classList.add("loading");
// }
// }, 2000);

View file

@ -201,8 +201,8 @@ export interface Uniform {
} }
export class Uniform2fv implements Uniform { export class Uniform2fv implements Uniform {
data: number[]; data: number[] | Float32Array;
constructor(data: number[]) { constructor(data: number[] | Float32Array) {
this.data = data; this.data = data;
} }
@ -212,8 +212,8 @@ export class Uniform2fv implements Uniform {
} }
export class Uniform3fv implements Uniform { export class Uniform3fv implements Uniform {
data: number[]; data: number[] | Float32Array;
constructor(data: number[]) { constructor(data: number[] | Float32Array) {
this.data = data; this.data = data;
} }
@ -239,8 +239,8 @@ export class Uniform3f implements Uniform {
} }
export class Uniform1iv implements Uniform { export class Uniform1iv implements Uniform {
data: number[]; data: number[] | Int32List;
constructor(data: number[]) { constructor(data: number[] | Int32List) {
this.data = data; this.data = data;
} }

View file

@ -48,51 +48,48 @@ export class FPSCounter {
} }
export class Resizer { export class Resizer {
hoovering: boolean; hoovering = false;
dragging: boolean; dragging = false;
mouse_pos: number[]; mouse_pos = [0, 0];
last_drag: number[]; last_drag = [0, 0];
viewbox: number[]; viewbox: number[];
orig_viewbox: number[]; orig_viewbox: number[];
el_width: number; el_box: number[];
scaleX = 1; scaleX = 1;
scaleY = 1; scaleY = 1;
constructor(el: HTMLCanvasElement, viewbox: number[], keep_aspect_ratio=false) { 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.viewbox = [...viewbox];
this.el_box = [el.width, el.height];
if (keep_aspect_ratio) { if (keep_aspect_ratio) {
const or_width = this.viewbox[2]; const or_width = this.viewbox[2];
const or_height = this.viewbox[3]; 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 { } else {
this.scaleY = scaleX; this.viewbox[3] = width_percentage * el.height;
this.viewbox[3] *= scaleX; // height should be larger
} }
this.viewbox[0] -= (this.viewbox[2] - or_width) / 2; this.viewbox[0] -= (this.viewbox[2] - or_width) / 2;
this.viewbox[1] -= (this.viewbox[3] - or_height) / 2; this.viewbox[1] -= (this.viewbox[3] - or_height) / 2;
this.scaleX = this.viewbox[2] / this.viewbox[3];
} }
this.orig_viewbox = [...this.viewbox]; this.orig_viewbox = [...this.viewbox];
this.el_width = el.width;
el.addEventListener("mouseenter", this.mouseenter.bind(this), { capture: false, passive: true}); el.addEventListener("mouseenter", this.mouseenter.bind(this), { capture: false, passive: true});
el.addEventListener("mouseleave", this.mouseleave.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}); 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}); 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[0] = Math.max(this.viewbox[0], this.orig_viewbox[0]);
this.viewbox[1] = Math.max(this.viewbox[1], this.orig_viewbox[1]); this.viewbox[1] = Math.max(this.viewbox[1], this.orig_viewbox[1]);
@ -116,20 +113,21 @@ export class Resizer {
mouseleave() { mouseleave() {
this.hoovering = false; this.hoovering = false;
this.dragging = false;
} }
mousemove(e: MouseEvent) { 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) { if (this.dragging) {
const scale = this.viewbox[3] / this.orig_viewbox[3]; const scaleX = this.viewbox[2] / this.el_box[0];
this.viewbox[0] += (this.last_drag[0] - this.mouse_pos[0]) * scale; const scaleY = this.viewbox[3] / this.el_box[1];
this.viewbox[1] += (this.last_drag[1] - this.mouse_pos[1]) * scale;
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.last_drag = [...this.mouse_pos];
this.clip_viewbox(); this._clip_viewbox();
} }
} }
@ -144,17 +142,19 @@ export class Resizer {
wheel(e: WheelEvent) { wheel(e: WheelEvent) {
if (this.hoovering) { 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[2] += dx;
this.viewbox[0] -= dx / 2; this.viewbox[0] -= dx / 2;
this.viewbox[2] = Math.min(this.viewbox[2], this.orig_viewbox[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[3] += dy;
this.viewbox[1] -= dy / 2; this.viewbox[1] -= dy / 2;
this.viewbox[3] = Math.min(this.viewbox[3], this.orig_viewbox[3]); this.viewbox[3] = Math.min(this.viewbox[3], this.orig_viewbox[3]);
this.clip_viewbox(); this._clip_viewbox();
} }
} }