From 152f426a2fc027d1860752c8e5bb31dc41726153 Mon Sep 17 00:00:00 2001 From: Bergmann89 Date: Sun, 29 Nov 2020 18:18:03 +0100 Subject: [PATCH] Refactored project (use specs and rayon instead own implementation) --- .gitmodules | 9 - Cargo.lock | 246 +++++++++---------- Cargo.toml | 6 - asparit | 1 - async-ecs | 1 - async-ecs-derive | 1 - gl/build.rs | 2 +- glc/src/shader.rs | 3 +- space-crush/Cargo.toml | 7 +- space-crush/src/app.rs | 26 -- space-crush/src/app/misc/events.rs | 56 +++++ space-crush/src/app/misc/geometry.rs | 58 +++++ space-crush/src/app/misc/mod.rs | 3 + space-crush/src/app/misc/window.rs | 52 ++++ space-crush/src/app/mod.rs | 55 +++++ space-crush/src/app/render/background.rs | 57 +++++ space-crush/src/{ => app}/render/mod.rs | 0 space-crush/src/app/render/shader/noise.frag | 21 ++ space-crush/src/app/render/shader/noise.vert | 8 + space-crush/src/app/systems/mod.rs | 3 + space-crush/src/app/systems/state.rs | 49 ++++ space-crush/src/error.rs | 13 +- space-crush/src/lib.rs | 3 +- space-crush/src/main.rs | 93 ++----- space-crush/src/render/background.rs | 95 ------- space-crush/src/render/shader/noise.frag | 17 -- space-crush/src/server/mod.rs | 15 ++ 27 files changed, 522 insertions(+), 378 deletions(-) delete mode 100644 .gitmodules delete mode 160000 asparit delete mode 160000 async-ecs delete mode 160000 async-ecs-derive delete mode 100644 space-crush/src/app.rs create mode 100644 space-crush/src/app/misc/events.rs create mode 100644 space-crush/src/app/misc/geometry.rs create mode 100644 space-crush/src/app/misc/mod.rs create mode 100644 space-crush/src/app/misc/window.rs create mode 100644 space-crush/src/app/mod.rs create mode 100644 space-crush/src/app/render/background.rs rename space-crush/src/{ => app}/render/mod.rs (100%) create mode 100644 space-crush/src/app/render/shader/noise.frag create mode 100644 space-crush/src/app/render/shader/noise.vert create mode 100644 space-crush/src/app/systems/mod.rs create mode 100644 space-crush/src/app/systems/state.rs delete mode 100644 space-crush/src/render/background.rs delete mode 100644 space-crush/src/render/shader/noise.frag create mode 100644 space-crush/src/server/mod.rs diff --git a/.gitmodules b/.gitmodules deleted file mode 100644 index 2af0b38..0000000 --- a/.gitmodules +++ /dev/null @@ -1,9 +0,0 @@ -[submodule "asparit"] - path = asparit - url = git@github.com:Bergmann89/asparit.git -[submodule "async-ecs"] - path = async-ecs - url = git@github.com:Bergmann89/async-ecs.git -[submodule "async-ecs-derive"] - path = async-ecs-derive - url = git@github.com:Bergmann89/async-ecs-derive.git diff --git a/Cargo.lock b/Cargo.lock index 1b7986e..13d7f77 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8,9 +8,9 @@ checksum = "d9fe5e32de01730eb1f6b7f5b51c17e03e2325bf40a74f754f04f130043affff" [[package]] name = "ahash" -version = "0.4.6" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6789e291be47ace86a60303502173d84af8327e3627ecf334356ee0f87a164c" +checksum = "e8fd72866655d1904d6b0997d0b07ba561047d070fbe29de039031c641b61217" [[package]] name = "aho-corasick" @@ -41,39 +41,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "000444226fcff248f2bc4c7625be32c63caccfecc2723a2b9f78a7487a49c407" [[package]] -name = "asparit" -version = "0.1.0" -dependencies = [ - "futures", - "num_cpus", - "rayon-core", - "tokio", -] - -[[package]] -name = "async-ecs" -version = "0.1.0" -dependencies = [ - "asparit", - "async-ecs-derive", - "crossbeam-queue", - "futures", - "hashbrown", - "hibitset", - "log", - "mopa", - "thiserror", - "tokio", -] - -[[package]] -name = "async-ecs-derive" -version = "0.1.0" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] +name = "arrayvec" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b" [[package]] name = "atom" @@ -116,12 +87,6 @@ version = "1.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de" -[[package]] -name = "bytes" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0dcbc35f504eb6fc275a6d20e4ebcda18cf50d40ba6fabff8c711fa16cb3b16" - [[package]] name = "calloop" version = "0.6.5" @@ -294,7 +259,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dca26ee1f8d361640700bde38b2c37d8c22b3ce2d360e1fc1c74ea4b0aa7d775" dependencies = [ "cfg-if 1.0.0", - "crossbeam-utils", + "crossbeam-utils 0.8.1", ] [[package]] @@ -305,18 +270,18 @@ checksum = "94af6efb46fef72616855b036a624cf27ba656ffc9be1b9a3c931cfc7749a9a9" dependencies = [ "cfg-if 1.0.0", "crossbeam-epoch", - "crossbeam-utils", + "crossbeam-utils 0.8.1", ] [[package]] name = "crossbeam-epoch" -version = "0.9.0" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec0f606a85340376eef0d6d8fec399e6d4a544d648386c6645eb6d0653b27d9f" +checksum = "a1aaa739f95311c2c7887a76863f500026092fb1dce0161dab577e559ef3569d" dependencies = [ "cfg-if 1.0.0", "const_fn", - "crossbeam-utils", + "crossbeam-utils 0.8.1", "lazy_static", "memoffset", "scopeguard", @@ -324,23 +289,34 @@ dependencies = [ [[package]] name = "crossbeam-queue" -version = "0.3.0" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b2a58563f049aa3bae172bc4120f093b5901161c629f280a1f40ba55317d774" +checksum = "774ba60a54c213d409d5353bda12d49cd68d14e45036a285234c8d6f91f92570" dependencies = [ - "cfg-if 1.0.0", - "crossbeam-utils", + "cfg-if 0.1.10", + "crossbeam-utils 0.7.2", + "maybe-uninit", ] [[package]] name = "crossbeam-utils" -version = "0.8.0" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3c7c73a2d1e9fc0886a08b93e98eb643461230d5f1925e4036204d5f2e261a8" +dependencies = [ + "autocfg", + "cfg-if 0.1.10", + "lazy_static", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec91540d98355f690a86367e566ecad2e9e579f230230eb7c21398372be73ea5" +checksum = "02d96d1e189ef58269ebe5b97953da3274d83a93af647c2ddd6f9dab28cedb8d" dependencies = [ "autocfg", "cfg-if 1.0.0", - "const_fn", "lazy_static", ] @@ -411,6 +387,12 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ea835d29036a4087793836fa931b08837ad5e957da9e23886b29586fb9b6650" +[[package]] +name = "either" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" + [[package]] name = "env_logger" version = "0.8.2" @@ -670,11 +652,12 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.9.1" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7afe4a420e3fe79967a00898cc1f4db7c8a49a9333a29f8a4bd76a253d5cd04" +checksum = "96282e96bfcd3da0d3aa9938bedf1e50df3269b6db08b4876d2da0bb1a0841cf" dependencies = [ "ahash", + "autocfg", ] [[package]] @@ -693,6 +676,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "93a1bb8316a44459a7d14253c4d28dd7395cbd23cc04a68c46e851b8e46d64b1" dependencies = [ "atom", + "rayon", ] [[package]] @@ -826,9 +810,9 @@ dependencies = [ [[package]] name = "memoffset" -version = "0.5.6" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "043175f069eda7b85febe4a74abbaeff828d9f8b448515d3151a14a3542811aa" +checksum = "157b4208e3059a8f9e78d559edc658e13df41410cb3ae03979c83130067fdd87" dependencies = [ "autocfg", ] @@ -846,25 +830,12 @@ dependencies = [ "kernel32-sys", "libc", "log", - "miow 0.2.1", + "miow", "net2", "slab", "winapi 0.2.8", ] -[[package]] -name = "mio" -version = "0.7.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f33bc887064ef1fd66020c9adfc45bb9f33d75a42096c81e7c56c65b75dd1a8b" -dependencies = [ - "libc", - "log", - "miow 0.3.6", - "ntapi", - "winapi 0.3.9", -] - [[package]] name = "mio-extras" version = "2.0.6" @@ -873,7 +844,7 @@ checksum = "52403fe290012ce777c4626790c8951324a2b9e3316b3143779c72b029742f19" dependencies = [ "lazycell", "log", - "mio 0.6.22", + "mio", "slab", ] @@ -889,16 +860,6 @@ dependencies = [ "ws2_32-sys", ] -[[package]] -name = "miow" -version = "0.3.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a33c1b55807fbed163481b5ba66db4b2fa6cde694a5027be10fb724206c5897" -dependencies = [ - "socket2", - "winapi 0.3.9", -] - [[package]] name = "mopa" version = "0.2.2" @@ -975,21 +936,22 @@ dependencies = [ [[package]] name = "nom" -version = "6.0.1" +version = "5.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88034cfd6b4a0d54dd14f4a507eceee36c0b70e5a02236c4e4df571102be17f0" +checksum = "ffb4262d26ed83a1c0a33a38fe2bb15797329c85770da05e6b828ddb782627af" dependencies = [ "memchr", "version_check", ] [[package]] -name = "ntapi" -version = "0.3.6" +name = "nom" +version = "6.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f6bb902e437b6d86e03cce10a7e2af662292c5dfef23b65899ea3ac9354ad44" +checksum = "88034cfd6b4a0d54dd14f4a507eceee36c0b70e5a02236c4e4df571102be17f0" dependencies = [ - "winapi 0.3.9", + "memchr", + "version_check", ] [[package]] @@ -1222,6 +1184,18 @@ dependencies = [ "libc", ] +[[package]] +name = "rayon" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b0d8e0819fadc20c74ea8373106ead0600e3a67ef1fe8da56e39b9ae7275674" +dependencies = [ + "autocfg", + "crossbeam-deque", + "either", + "rayon-core", +] + [[package]] name = "rayon-core" version = "1.9.0" @@ -1230,7 +1204,7 @@ checksum = "9ab346ac5921dc62ffa9f89b7a773907511cdfa5490c572ae9be1be33e8afa4a" dependencies = [ "crossbeam-channel", "crossbeam-deque", - "crossbeam-utils", + "crossbeam-utils 0.8.1", "lazy_static", "num_cpus", ] @@ -1307,14 +1281,25 @@ dependencies = [ ] [[package]] -name = "signal-hook-registry" -version = "1.2.2" +name = "shred" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce32ea0c6c56d5eacaeb814fbed9960547021d3edd010ded1425f180536b20ab" +checksum = "c5f08237e667ac94ad20f8878b5943d91a93ccb231428446c57c21c57779016d" dependencies = [ - "libc", + "arrayvec", + "hashbrown", + "mopa", + "rayon", + "smallvec", + "tynm", ] +[[package]] +name = "shrev" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5752e017e03af9d735b4b069f53b7a7fd90fefafa04d8bd0c25581b0bff437f" + [[package]] name = "slab" version = "0.4.2" @@ -1347,25 +1332,10 @@ dependencies = [ "wayland-protocols", ] -[[package]] -name = "socket2" -version = "0.3.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c29947abdee2a218277abeca306f25789c938e500ea5a9d4b12a5a504466902" -dependencies = [ - "cfg-if 1.0.0", - "libc", - "redox_syscall", - "winapi 0.3.9", -] - [[package]] name = "space-crush" version = "0.1.0" dependencies = [ - "asparit", - "async-ecs", - "async-ecs-derive", "env_logger", "futures", "gl", @@ -1374,10 +1344,28 @@ dependencies = [ "log", "num_cpus", "rand", + "shrev", + "specs", "thiserror", "tokio", ] +[[package]] +name = "specs" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fff28a29366aff703d5da8a7e2c8875dc8453ac1118f842cbc0fa70c7db51240" +dependencies = [ + "crossbeam-queue", + "hashbrown", + "hibitset", + "log", + "rayon", + "shred", + "shrev", + "tuple_utils", +] + [[package]] name = "strsim" version = "0.9.3" @@ -1440,30 +1428,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9dfe2523e6fa84ddf5e688151d4e5fddc51678de9752c6512a24714c23818d61" dependencies = [ "autocfg", - "bytes", - "futures-core", - "lazy_static", - "libc", - "memchr", - "mio 0.7.6", - "num_cpus", - "parking_lot", "pin-project-lite", - "signal-hook-registry", - "slab", - "tokio-macros", - "winapi 0.3.9", -] - -[[package]] -name = "tokio-macros" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21d30fdbb5dc2d8f91049691aa1a9d4d4ae422a21c334ce8936e5886d30c5c45" -dependencies = [ - "proc-macro2", - "quote", - "syn", ] [[package]] @@ -1481,6 +1446,21 @@ version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3e5d7cd7ab3e47dda6e56542f4bbf3824c15234958c6e1bd6aaa347e93499fdc" +[[package]] +name = "tuple_utils" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44834418e2c5b16f47bedf35c28e148db099187dd5feee6367fb2525863af4f1" + +[[package]] +name = "tynm" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4df2caa2dc9c3d1f7641ba981f4cd40ab229775aa7aeb834c9ab2850d50623d" +dependencies = [ + "nom 5.1.2", +] + [[package]] name = "unicode-xid" version = "0.2.1" @@ -1652,7 +1632,7 @@ dependencies = [ "lazy_static", "libc", "log", - "mio 0.6.22", + "mio", "mio-extras", "ndk", "ndk-glue", @@ -1695,7 +1675,7 @@ version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3a9a231574ae78801646617cefd13bfe94be907c0e4fa979cfd8b770aa3c5d08" dependencies = [ - "nom", + "nom 6.0.1", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index d3a4621..80b97b2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,8 +1,5 @@ [workspace] members = [ - "asparit", - "async-ecs", - "async-ecs-derive", "gl", "glc", "space-crush", @@ -12,9 +9,6 @@ default-members = [ ] [patch.crates-io] -asparit = { path = "./asparit" } -async-ecs = { path = "./async-ecs" } -async-ecs-derive = { path = "./async-ecs-derive" } gl = { path = "./gl" } glc = { path = "./glc" } space-crush = { path = "./space-crush" } diff --git a/asparit b/asparit deleted file mode 160000 index e3d7c56..0000000 --- a/asparit +++ /dev/null @@ -1 +0,0 @@ -Subproject commit e3d7c56297232aa66e720cc0766b1c25bc11420d diff --git a/async-ecs b/async-ecs deleted file mode 160000 index b2e2596..0000000 --- a/async-ecs +++ /dev/null @@ -1 +0,0 @@ -Subproject commit b2e25967b55b968d8955d285a67fceaa6a257271 diff --git a/async-ecs-derive b/async-ecs-derive deleted file mode 160000 index 7a33669..0000000 --- a/async-ecs-derive +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 7a33669aa8f000d15e56209dcf93f81112f08a24 diff --git a/gl/build.rs b/gl/build.rs index 30c795d..c6ebbdd 100644 --- a/gl/build.rs +++ b/gl/build.rs @@ -30,7 +30,7 @@ fn main() { }, }; - Registry::new(Api::Gl, (4, 5), Profile::Core, Fallbacks::All, []) + Registry::new(Api::Gl, (4, 5), Profile::Compatibility, Fallbacks::All, []) .write_bindings(generator, &mut file) .unwrap(); } diff --git a/glc/src/shader.rs b/glc/src/shader.rs index a6182cd..96247e4 100644 --- a/glc/src/shader.rs +++ b/glc/src/shader.rs @@ -94,10 +94,11 @@ pub struct Shader { } impl Shader { - pub fn from_string(type_: Type, source: String) -> Result { + pub fn from_string(type_: Type, mut source: String) -> Result { let id = gl::create_shader(type_.as_enum()); let id = Error::err_if(&0, id)?; + source.push('\0'); let source = source.as_ptr() as *const i8; let source: *const *const i8 = &source; diff --git a/space-crush/Cargo.toml b/space-crush/Cargo.toml index 3fc561f..c2e48e8 100644 --- a/space-crush/Cargo.toml +++ b/space-crush/Cargo.toml @@ -5,16 +5,15 @@ authors = ["Bergmann89 "] edition = "2018" [dependencies] -asparit = { version = "0.1", default-features = false, features = [ "tokio-executor" ] } -async-ecs = "0.1" -async-ecs-derive = "0.1" env_logger = "0.8" futures = "0.3" -gl = { version = "0.1", features = [ "use_log_crate", "generate_debug" ] } +gl = { version = "0.1", features = [ "use_log_crate" ] } glc = "0.1" glutin = "0.25" log = { version = "0.4", features = [ "max_level_trace", "release_max_level_warn" ] } num_cpus = "1.13" rand = "0.7" +shrev = "1.1" +specs = "0.16" thiserror = "1.0" tokio = "0.3" diff --git a/space-crush/src/app.rs b/space-crush/src/app.rs deleted file mode 100644 index b16ce1f..0000000 --- a/space-crush/src/app.rs +++ /dev/null @@ -1,26 +0,0 @@ -use async_ecs::{Dispatcher, World}; - -use crate::{render::Background, Error}; - -pub struct App { - world: World, - dispatcher: Dispatcher, -} - -impl App { - pub fn new() -> Result { - let mut world = World::default(); - let dispatcher = Dispatcher::setup_builder(&mut world) - .with_local(Background::new()?, "render_background", &[])? - .build(); - - Ok(Self { world, dispatcher }) - } - - pub async fn progress(&mut self) -> Result<(), Error> { - self.dispatcher.dispatch(&self.world).await?; - self.world.maintain().await; - - Ok(()) - } -} diff --git a/space-crush/src/app/misc/events.rs b/space-crush/src/app/misc/events.rs new file mode 100644 index 0000000..ce23f8a --- /dev/null +++ b/space-crush/src/app/misc/events.rs @@ -0,0 +1,56 @@ +use glutin::{ + event::{Event, WindowEvent as GlutinWindowEvent}, + event_loop::{ControlFlow, EventLoop}, + platform::desktop::EventLoopExtDesktop, +}; +use shrev::EventChannel; +use specs::World; + +pub struct Events { + event_loop: EventLoop<()>, +} + +impl Events { + pub fn new(world: &mut World) -> Self { + world.insert(EventChannel::::default()); + + Self { + event_loop: EventLoop::new(), + } + } +} + +impl Events { + pub fn handle(&self) -> &EventLoop<()> { + &self.event_loop + } + + pub fn process(&mut self, world: &World) { + let mut channel = world.fetch_mut::>(); + + self.event_loop.run_return(|event, _target, flow_control| { + *flow_control = ControlFlow::Poll; + + match event { + Event::MainEventsCleared | Event::RedrawRequested(_) => { + *flow_control = ControlFlow::Exit; + } + Event::WindowEvent { event, .. } => match event { + GlutinWindowEvent::Resized(pos) => { + channel.single_write(WindowEvent::Resize(pos.width, pos.height)); + } + GlutinWindowEvent::CloseRequested => { + channel.single_write(WindowEvent::Close); + } + _ => (), + }, + _ => (), + } + }); + } +} + +pub enum WindowEvent { + Resize(u32, u32), + Close, +} diff --git a/space-crush/src/app/misc/geometry.rs b/space-crush/src/app/misc/geometry.rs new file mode 100644 index 0000000..6a4540c --- /dev/null +++ b/space-crush/src/app/misc/geometry.rs @@ -0,0 +1,58 @@ +use std::mem::size_of; + +use glc::{ + array_buffer::{ArrayBuffer, Target, Usage}, + misc::Bindable, + vertex_array::{DataType, VertexArray}, +}; + +use crate::Error; + +pub struct Geometry { + quad: VertexArray, +} + +impl Geometry { + pub fn new() -> Result { + Ok(Self { + quad: create_quad_array()?, + }) + } + + pub fn render_quad(&self) { + self.quad.bind(); + + gl::draw_arrays(gl::TRIANGLE_FAN, 0, 4); + + self.quad.unbind(); + } +} + +#[repr(C, packed)] +#[derive(Debug, Copy, Clone, PartialEq)] +struct Vertex { + pub x: f32, + pub y: f32, +} + +fn create_quad_array() -> Result { + let vertices = &[ + Vertex { x: -1.0, y: -1.0 }, + Vertex { x: 1.0, y: -1.0 }, + Vertex { x: 1.0, y: 1.0 }, + Vertex { x: -1.0, y: 1.0 }, + ]; + + const STRIDE_POS: gl::GLsizei = size_of::() as gl::GLsizei; + const OFFSET_POS: gl::GLsizei = 0; + + let mut array_buffer = ArrayBuffer::new(Target::ArrayBuffer)?; + array_buffer.buffer_data(Usage::StaticDraw, vertices)?; + + let vertex_array = VertexArray::builder() + .bind_buffer(array_buffer) + .vertex_attrib_pointer(0, 2, DataType::Float, false, STRIDE_POS, OFFSET_POS)? + .build()?; + + Ok(vertex_array) +} diff --git a/space-crush/src/app/misc/mod.rs b/space-crush/src/app/misc/mod.rs new file mode 100644 index 0000000..f4aeec5 --- /dev/null +++ b/space-crush/src/app/misc/mod.rs @@ -0,0 +1,3 @@ +pub mod events; +pub mod geometry; +pub mod window; diff --git a/space-crush/src/app/misc/window.rs b/space-crush/src/app/misc/window.rs new file mode 100644 index 0000000..19bc9c0 --- /dev/null +++ b/space-crush/src/app/misc/window.rs @@ -0,0 +1,52 @@ +use glutin::{ + dpi::{PhysicalPosition, PhysicalSize}, + event_loop::EventLoop, + window::Window as GlutinWindow, + window::WindowBuilder, + Api, ContextBuilder, ContextWrapper, GlProfile, GlRequest, PossiblyCurrent, +}; + +use crate::Error; + +pub struct Window { + context: ContextWrapper, +} + +impl Window { + pub fn new(event_loop: &EventLoop) -> Result { + let window_builder = WindowBuilder::new() + .with_title("space-crush") + .with_visible(true) + .with_inner_size(PhysicalSize::new(WINDOW_WIDTH, WINDOW_HEIGHT)); + let context = ContextBuilder::new() + .with_double_buffer(Some(true)) + .with_hardware_acceleration(Some(true)) + .with_pixel_format(24, 8) + .with_vsync(true) + .with_gl(GlRequest::Specific(Api::OpenGl, (4, 5))) + .with_gl_profile(GlProfile::Core) + .build_windowed(window_builder, event_loop)?; + + let window = context.window(); + let window_size = window.outer_size(); + let monitor_size = window.current_monitor().unwrap().size(); + window.set_outer_position(PhysicalPosition::new( + (monitor_size.width - window_size.width) / 2, + (monitor_size.height - window_size.height) / 2, + )); + + let context = unsafe { context.make_current().unwrap() }; + gl::load_with(|s| context.get_proc_address(s)); + + Ok(Self { context }) + } + + pub fn swap_buffers(&self) -> Result<(), Error> { + self.context.swap_buffers()?; + + Ok(()) + } +} + +const WINDOW_WIDTH: u32 = 1280; +const WINDOW_HEIGHT: u32 = 720; diff --git a/space-crush/src/app/mod.rs b/space-crush/src/app/mod.rs new file mode 100644 index 0000000..da6ad0d --- /dev/null +++ b/space-crush/src/app/mod.rs @@ -0,0 +1,55 @@ +mod misc; +mod render; +mod systems; + +use specs::{Dispatcher, DispatcherBuilder, World}; + +use crate::Error; + +use misc::{events::Events, geometry::Geometry, window::Window}; +use render::Background; +use systems::{State, StateUpdate}; + +pub struct App<'a, 'b> { + is_running: bool, + events: Events, + window: Window, + dispatcher: Dispatcher<'a, 'b>, +} + +impl<'a, 'b> App<'a, 'b> { + pub fn new(world: &mut World) -> Result { + let events = Events::new(world); + let window = Window::new(events.handle())?; + + let mut dispatcher = DispatcherBuilder::new() + .with(StateUpdate::new(world), "state_update", &[]) + .with_thread_local(Background::new(world)?) + .build(); + dispatcher.setup(world); + + world.insert(Geometry::new()?); + + Ok(Self { + is_running: true, + events, + window, + dispatcher, + }) + } + + pub fn is_running(&self) -> bool { + self.is_running + } + + pub fn process(&mut self, world: &World) -> Result<(), Error> { + self.events.process(world); + self.dispatcher.dispatch(world); + + self.window.swap_buffers()?; + + self.is_running = !world.fetch::().close_requested; + + Ok(()) + } +} diff --git a/space-crush/src/app/render/background.rs b/space-crush/src/app/render/background.rs new file mode 100644 index 0000000..e715ae6 --- /dev/null +++ b/space-crush/src/app/render/background.rs @@ -0,0 +1,57 @@ +use glc::{ + misc::Bindable, + shader::{Program, Shader, Type}, +}; +use shrev::{EventChannel, ReaderId}; +use specs::{ReadExpect, System, World}; + +use crate::Error; + +use super::super::misc::{events::WindowEvent, geometry::Geometry}; + +pub struct Background { + program: Program, + window_events_id: ReaderId, +} + +impl Background { + pub fn new(world: &mut World) -> Result { + let shaders = vec![ + (Type::Vertex, include_str!("shader/noise.vert")), + (Type::Fragment, include_str!("shader/noise.frag")), + ]; + let program = Program::from_shaders_result( + shaders + .into_iter() + .map(|(t, s)| Shader::from_string(t, s.into())), + )?; + let window_events_id = world + .fetch_mut::>() + .register_reader(); + + Ok(Self { + program, + window_events_id, + }) + } +} + +impl<'a> System<'a> for Background { + type SystemData = ( + ReadExpect<'a, Geometry>, + ReadExpect<'a, EventChannel>, + ); + + fn run(&mut self, (geometry, window_events): Self::SystemData) { + let events = window_events.read(&mut self.window_events_id); + for event in events { + if let WindowEvent::Resize(w, h) = event { + gl::viewport(0, 0, *w as gl::GLsizei, *h as gl::GLsizei); + } + } + + self.program.bind(); + geometry.render_quad(); + self.program.unbind(); + } +} diff --git a/space-crush/src/render/mod.rs b/space-crush/src/app/render/mod.rs similarity index 100% rename from space-crush/src/render/mod.rs rename to space-crush/src/app/render/mod.rs diff --git a/space-crush/src/app/render/shader/noise.frag b/space-crush/src/app/render/shader/noise.frag new file mode 100644 index 0000000..01043a4 --- /dev/null +++ b/space-crush/src/app/render/shader/noise.frag @@ -0,0 +1,21 @@ +#version 450 core + +layout(pixel_center_integer) in vec4 gl_FragCoord; + +out vec4 Color; + +const float NOISE_RANGE = 0.02; +const float NOISE_BASE = 0.05; + +float random(vec4 seed) +{ + return fract(sin(dot(seed, vec4(12.9898, 78.233, 45.164, 53.1324))) * 43758.5453); +} + +void main() +{ + float rnd = random(gl_FragCoord); + vec3 rbg = vec3(NOISE_BASE + NOISE_RANGE * rnd); + + Color = vec4(rbg, 1.0); +} diff --git a/space-crush/src/app/render/shader/noise.vert b/space-crush/src/app/render/shader/noise.vert new file mode 100644 index 0000000..81f59ca --- /dev/null +++ b/space-crush/src/app/render/shader/noise.vert @@ -0,0 +1,8 @@ +#version 450 core + +layout (location = 0) in vec3 Position; + +void main() +{ + gl_Position = vec4(Position, 1.0); +} diff --git a/space-crush/src/app/systems/mod.rs b/space-crush/src/app/systems/mod.rs new file mode 100644 index 0000000..c20a632 --- /dev/null +++ b/space-crush/src/app/systems/mod.rs @@ -0,0 +1,3 @@ +mod state; + +pub use state::{State, StateUpdate}; diff --git a/space-crush/src/app/systems/state.rs b/space-crush/src/app/systems/state.rs new file mode 100644 index 0000000..bd1645f --- /dev/null +++ b/space-crush/src/app/systems/state.rs @@ -0,0 +1,49 @@ +use shrev::{EventChannel, ReaderId}; +use specs::{ReadExpect, System, World, Write}; + +use super::super::misc::events::WindowEvent; + +/* State */ + +#[derive(Default)] +pub struct State { + pub close_requested: bool, + + pub window_width: u32, + pub window_height: u32, +} + +/* StateUpdate*/ + +pub struct StateUpdate { + window_events_id: ReaderId, +} + +impl StateUpdate { + pub fn new(world: &mut World) -> Self { + let window_events_id = world + .fetch_mut::>() + .register_reader(); + + Self { window_events_id } + } +} + +impl<'a> System<'a> for StateUpdate { + type SystemData = (Write<'a, State>, ReadExpect<'a, EventChannel>); + + fn run(&mut self, (mut state, window_events): Self::SystemData) { + let events = window_events.read(&mut self.window_events_id); + for event in events { + match event { + WindowEvent::Resize(w, h) => { + state.window_width = *w; + state.window_height = *h; + } + WindowEvent::Close => { + state.close_requested = true; + } + } + } + } +} diff --git a/space-crush/src/error.rs b/space-crush/src/error.rs index 8b4469c..830df9c 100644 --- a/space-crush/src/error.rs +++ b/space-crush/src/error.rs @@ -1,6 +1,5 @@ -use async_ecs::dispatcher::Error as DispatcherError; use glc::error::Error as GlcError; -use glutin::CreationError as GlutinCreationError; +use glutin::{ContextError as GlutinContextError, CreationError as GlutinCreationError}; use thiserror::Error; #[derive(Debug, Error)] @@ -8,8 +7,8 @@ pub enum Error { #[error("GLC Error: {0}")] GlcError(GlcError), - #[error("ECS Dispatcher Error: {0}")] - DispatcherError(DispatcherError), + #[error("glutin Context Error: {0}")] + GlutinContextError(GlutinContextError), #[error("glutin Creation Error: {0}")] GlutinCreationError(GlutinCreationError), @@ -21,9 +20,9 @@ impl From for Error { } } -impl From for Error { - fn from(err: DispatcherError) -> Self { - Self::DispatcherError(err) +impl From for Error { + fn from(err: GlutinContextError) -> Self { + Self::GlutinContextError(err) } } diff --git a/space-crush/src/lib.rs b/space-crush/src/lib.rs index 040d0af..b468dc5 100644 --- a/space-crush/src/lib.rs +++ b/space-crush/src/lib.rs @@ -1,6 +1,7 @@ mod app; mod error; -mod render; +mod server; pub use app::App; pub use error::Error; +pub use server::Server; diff --git a/space-crush/src/main.rs b/space-crush/src/main.rs index 25d4a26..28f3d72 100644 --- a/space-crush/src/main.rs +++ b/space-crush/src/main.rs @@ -1,93 +1,36 @@ -use glutin::{ - dpi::{PhysicalPosition, PhysicalSize}, - event::{Event, WindowEvent}, - event_loop::{ControlFlow, EventLoop}, - platform::desktop::EventLoopExtDesktop, - window::WindowBuilder, - ContextBuilder, GlProfile, -}; use log::{error, info}; -use tokio::{runtime::Builder, task::LocalSet}; +use specs::{World, WorldExt}; -use space_crush::{App, Error}; +use space_crush::{App, Error, Server}; -fn main() { +fn main() -> Result<(), Error> { env_logger::builder() .filter_level(log::LevelFilter::Trace) .format_timestamp_nanos() .init(); - let rt = Builder::new_multi_thread() - .worker_threads(num_cpus::get() + 4) - .enable_all() - .build() - .unwrap(); + info!("Application started"); - if let Err(err) = rt.block_on(async move { LocalSet::new().run_until(run()).await }) { - error!("Error while executinr application: {}", err); - } -} - -async fn run() -> Result<(), Error> { - let mut event_loop = EventLoop::new(); - let window_builder = WindowBuilder::new() - .with_title("space-crush") - .with_visible(true) - .with_inner_size(PhysicalSize::new(WINDOW_WIDTH, WINDOW_HEIGHT)); - let context = ContextBuilder::new() - .with_double_buffer(Some(true)) - .with_hardware_acceleration(Some(true)) - .with_pixel_format(24, 8) - .with_vsync(true) - .with_gl_profile(GlProfile::Core) - .build_windowed(window_builder, &event_loop)?; - - let window = context.window(); - let window_size = window.outer_size(); - let monitor_size = window.current_monitor().unwrap().size(); - window.set_outer_position(PhysicalPosition::new( - (monitor_size.width - window_size.width) / 2, - (monitor_size.height - window_size.height) / 2, - )); - - let context = unsafe { context.make_current().unwrap() }; - gl::load_with(|s| context.get_proc_address(s)); - - let mut run = true; - let mut app = App::new()?; + if let Err(err) = run() { + error!("Error while executing application: {}", err); - loop { - event_loop.run_return(|event, _target, flow_control| { - *flow_control = ControlFlow::Poll; + return Err(err); + } - match event { - Event::WindowEvent { - event: WindowEvent::CloseRequested, - .. - } => { - run = false; - *flow_control = ControlFlow::Exit; - } - Event::MainEventsCleared | Event::RedrawRequested(_) => { - *flow_control = ControlFlow::Exit; - } - _ => (), - } - }); + info!("Application exited"); - if !run { - break; - } + Ok(()) +} - app.progress().await?; +fn run() -> Result<(), Error> { + let mut world = World::new(); + let mut server = Server::new(&mut world); + let mut app = App::new(&mut world)?; - context.swap_buffers().unwrap(); + while app.is_running() { + server.process(&world); + app.process(&world)?; } - info!("finished"); - Ok(()) } - -const WINDOW_WIDTH: u32 = 1280; -const WINDOW_HEIGHT: u32 = 720; diff --git a/space-crush/src/render/background.rs b/space-crush/src/render/background.rs deleted file mode 100644 index 79e7ce5..0000000 --- a/space-crush/src/render/background.rs +++ /dev/null @@ -1,95 +0,0 @@ -use std::mem::size_of; - -use async_ecs::System; -use glc::{ - array_buffer::{ArrayBuffer, Target, Usage}, - shader::{Program, Shader, Type}, - vertex_array::{DataType, VertexArray}, -}; - -use crate::Error; - -pub struct Background { - program: Program, - vertex_array: VertexArray, -} - -impl Background { - pub fn new() -> Result { - let shaders = vec![(Type::Fragment, include_str!("shader/noise.frag"))]; - let program = Program::from_shaders_result( - shaders - .into_iter() - .map(|(t, s)| Shader::from_string(t, s.into())), - )?; - - let mut array_buffer = ArrayBuffer::new(Target::ArrayBuffer)?; - array_buffer.buffer_size(Usage::StaticDraw, 4 * size_of::())?; - - { - let mut buf = array_buffer.map_mut(false)?; - buf[0] = Vertex { - x: -1.0, - y: -1.0, - s: -1.0, - t: -1.0, - }; - buf[1] = Vertex { - x: 1.0, - y: -1.0, - s: 1.0, - t: -1.0, - }; - buf[2] = Vertex { - x: 1.0, - y: 1.0, - s: 1.0, - t: 1.0, - }; - buf[3] = Vertex { - x: -1.0, - y: 1.0, - s: -1.0, - t: 1.0, - }; - } - - const STRIDE_POS: gl::GLsizei = size_of::() as gl::GLsizei; - const STRIDE_TEX: gl::GLsizei = size_of::() as gl::GLsizei; - - const OFFSET_POS: gl::GLsizei = 0; - const OFFSET_TEX: gl::GLsizei = 2 * size_of::() as gl::GLsizei; - - let vertex_array = VertexArray::builder() - .bind_buffer(array_buffer) - .vertex_attrib_pointer(0, 2, DataType::Float, false, STRIDE_POS, OFFSET_POS)? - .vertex_attrib_pointer(1, 2, DataType::Float, false, STRIDE_TEX, OFFSET_TEX)? - .build()?; - - Ok(Self { - program, - vertex_array, - }) - } -} - -impl<'a> System<'a> for Background { - type SystemData = (); - - fn run(&mut self, (): Self::SystemData) { - let _program = &self.program; - let _vertex_array = &self.vertex_array; - - gl::clear_color(0.1, 0.1, 0.1, 1.0); - gl::clear(gl::COLOR_BUFFER_BIT); - } -} - -#[repr(C, packed)] -#[derive(Debug, Copy, Clone, PartialEq)] -struct Vertex { - pub x: f32, - pub y: f32, - pub s: f32, - pub t: f32, -} diff --git a/space-crush/src/render/shader/noise.frag b/space-crush/src/render/shader/noise.frag deleted file mode 100644 index f21e009..0000000 --- a/space-crush/src/render/shader/noise.frag +++ /dev/null @@ -1,17 +0,0 @@ -const float NOISE_RANGE = 0.05; -const float NOISE_BASE = 0.05; - -float random(vec4 seed) -{ - return fract(sin(dot(seed, vec4(12.9898, 78.233, 45.164, 53.1324))) * 43758.5453); -} - -void main(void) -{ - float rnd = random(gl_ModelViewProjectionMatrix * gl_FragCoord); - vec4 color = vec4(NOISE_BASE + NOISE_RANGE * rnd); - - color.a = 1.0; - - gl_FragColor = color; -} diff --git a/space-crush/src/server/mod.rs b/space-crush/src/server/mod.rs new file mode 100644 index 0000000..ca238e3 --- /dev/null +++ b/space-crush/src/server/mod.rs @@ -0,0 +1,15 @@ +use specs::World; + +pub struct Server {} + +impl Server { + pub fn new(world: &mut World) -> Self { + let _world = world; + + Self {} + } + + pub fn process(&mut self, world: &World) { + let _world = world; + } +}