colourful planets
This commit is contained in:
parent
aa97ec8837
commit
366f3361d9
9 changed files with 113 additions and 87 deletions
|
@ -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()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
}
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
body {
|
||||
background-color: #333;
|
||||
}
|
||||
|
||||
.loading {
|
||||
position: relative;
|
||||
|
@ -21,6 +24,7 @@
|
|||
|
||||
#c {
|
||||
position: relative;
|
||||
background-color: black;
|
||||
}
|
||||
|
||||
/* ----------------------------------------------
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue