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,
/* put extra shit here */
planets: Vec<Vec3<f64>>,
view_box: Vec<f64>,
planets: Vec<Vec3<f32>>,
view_box: Vec<f32>,
ship_locations: Vec<Mat3<f64>>,
current_planet_colours: Vec<Vec3<f64>>,
ship_locations: Vec<Mat3<f32>>,
current_planet_colours: Vec<Vec3<f32>>,
}
#[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<f64> {
pub fn get_planets(&self) -> *const Vec3<f32> {
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()
}
@ -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<f64> {
pub fn get_ship_locations(&self) -> *const Mat3<f32> {
self.ship_locations.as_ptr()
}
}

View file

@ -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<u32>,
pub name: String,
}

View file

@ -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<types::Planet>) -> Vec<f64> {
pub fn caclulate_viewbox(planets: &Vec<types::Planet>) -> Vec<f32> {
let mut iter = planets.iter();
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)));
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<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()
}

View file

@ -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));
}

View file

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

View file

@ -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;
}

View file

@ -17,7 +17,7 @@ async function main() {
var canvas = <HTMLCanvasElement>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);

View file

@ -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;
}

View file

@ -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();
}
}