| @@ -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 | |||
| @@ -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]] | |||
| @@ -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" } | |||
| @@ -1 +0,0 @@ | |||
| Subproject commit e3d7c56297232aa66e720cc0766b1c25bc11420d | |||
| @@ -1 +0,0 @@ | |||
| Subproject commit b2e25967b55b968d8955d285a67fceaa6a257271 | |||
| @@ -1 +0,0 @@ | |||
| Subproject commit 7a33669aa8f000d15e56209dcf93f81112f08a24 | |||
| @@ -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(); | |||
| } | |||
| @@ -94,10 +94,11 @@ pub struct Shader { | |||
| } | |||
| impl Shader { | |||
| pub fn from_string(type_: Type, source: String) -> Result<Self, Error> { | |||
| pub fn from_string(type_: Type, mut source: String) -> Result<Self, Error> { | |||
| 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; | |||
| @@ -5,16 +5,15 @@ authors = ["Bergmann89 <info@bergmann89.de>"] | |||
| 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" | |||
| @@ -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<Self, Error> { | |||
| 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(()) | |||
| } | |||
| } | |||
| @@ -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::<WindowEvent>::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::<EventChannel<WindowEvent>>(); | |||
| 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, | |||
| } | |||
| @@ -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<Self, Error> { | |||
| 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<VertexArray, Error> { | |||
| 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::<Vertex>() 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) | |||
| } | |||
| @@ -0,0 +1,3 @@ | |||
| pub mod events; | |||
| pub mod geometry; | |||
| pub mod window; | |||
| @@ -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<PossiblyCurrent, GlutinWindow>, | |||
| } | |||
| impl Window { | |||
| pub fn new<T>(event_loop: &EventLoop<T>) -> Result<Self, Error> { | |||
| 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; | |||
| @@ -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<Self, Error> { | |||
| 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::<State>().close_requested; | |||
| Ok(()) | |||
| } | |||
| } | |||
| @@ -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<WindowEvent>, | |||
| } | |||
| impl Background { | |||
| pub fn new(world: &mut World) -> Result<Self, Error> { | |||
| 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::<EventChannel<WindowEvent>>() | |||
| .register_reader(); | |||
| Ok(Self { | |||
| program, | |||
| window_events_id, | |||
| }) | |||
| } | |||
| } | |||
| impl<'a> System<'a> for Background { | |||
| type SystemData = ( | |||
| ReadExpect<'a, Geometry>, | |||
| ReadExpect<'a, EventChannel<WindowEvent>>, | |||
| ); | |||
| 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(); | |||
| } | |||
| } | |||
| @@ -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); | |||
| } | |||
| @@ -0,0 +1,8 @@ | |||
| #version 450 core | |||
| layout (location = 0) in vec3 Position; | |||
| void main() | |||
| { | |||
| gl_Position = vec4(Position, 1.0); | |||
| } | |||
| @@ -0,0 +1,3 @@ | |||
| mod state; | |||
| pub use state::{State, StateUpdate}; | |||
| @@ -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<WindowEvent>, | |||
| } | |||
| impl StateUpdate { | |||
| pub fn new(world: &mut World) -> Self { | |||
| let window_events_id = world | |||
| .fetch_mut::<EventChannel<WindowEvent>>() | |||
| .register_reader(); | |||
| Self { window_events_id } | |||
| } | |||
| } | |||
| impl<'a> System<'a> for StateUpdate { | |||
| type SystemData = (Write<'a, State>, ReadExpect<'a, EventChannel<WindowEvent>>); | |||
| 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; | |||
| } | |||
| } | |||
| } | |||
| } | |||
| } | |||
| @@ -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<GlcError> for Error { | |||
| } | |||
| } | |||
| impl From<DispatcherError> for Error { | |||
| fn from(err: DispatcherError) -> Self { | |||
| Self::DispatcherError(err) | |||
| impl From<GlutinContextError> for Error { | |||
| fn from(err: GlutinContextError) -> Self { | |||
| Self::GlutinContextError(err) | |||
| } | |||
| } | |||
| @@ -1,6 +1,7 @@ | |||
| mod app; | |||
| mod error; | |||
| mod render; | |||
| mod server; | |||
| pub use app::App; | |||
| pub use error::Error; | |||
| pub use server::Server; | |||
| @@ -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; | |||
| @@ -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<Self, Error> { | |||
| 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::<Vertex>())?; | |||
| { | |||
| 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::<Vertex>() as gl::GLsizei; | |||
| const STRIDE_TEX: gl::GLsizei = size_of::<Vertex>() as gl::GLsizei; | |||
| const OFFSET_POS: gl::GLsizei = 0; | |||
| const OFFSET_TEX: gl::GLsizei = 2 * size_of::<f32>() 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, | |||
| } | |||
| @@ -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; | |||
| } | |||
| @@ -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; | |||
| } | |||
| } | |||