From 5dfca809efa41ea0fc7cd2cd702b350338e893af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Tue, 2 Jul 2019 04:32:18 +0200 Subject: [PATCH 1/8] Add `web` feature --- .travis.yml | 3 ++- Cargo.toml | 3 ++- build.rs | 1 + src/graphics.rs | 2 ++ src/graphics/backend_wgpu/mod.rs | 4 ++++ src/graphics/backend_wgpu/surface.rs | 4 ++++ 6 files changed, 15 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 9700e52..55e50e8 100644 --- a/.travis.yml +++ b/.travis.yml @@ -30,5 +30,6 @@ matrix: script: - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then chmod +x spirvtest && ./spirvtest; fi #- cargo test --verbose --features opengl - #- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then cargo test --verbose --features vulkan --release; fi - cargo test --verbose + #- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then cargo test --verbose --features vulkan --release; fi + - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then cargo test --verbose --features web --target wasm32-unknown-unknown --no-run; fi diff --git a/Cargo.toml b/Cargo.toml index 4c5fcde..5996e56 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -25,6 +25,7 @@ vulkan = ["wgpu", "wgpu/vulkan", "wgpu_glyph"] metal = ["wgpu", "wgpu/metal", "wgpu_glyph"] dx11 = ["wgpu", "wgpu/dx11", "wgpu_glyph"] dx12 = ["wgpu", "wgpu/dx12", "wgpu_glyph"] +web = ["wgpu", "wgpu/web", "wgpu_glyph"] empty = ["wgpu", "wgpu_glyph"] debug = [] @@ -52,7 +53,7 @@ wgpu_glyph = { version = "0.3", optional = true } [dev-dependencies] # Example dependencies -rand = "0.6" +rand = { version = "0.6", features = ["wasm-bindgen"] } [patch.crates-io] wgpu = { git = "https://github.com/hecrj/wgpu-rs", branch = "web" } diff --git a/build.rs b/build.rs index 34b4461..24c309a 100644 --- a/build.rs +++ b/build.rs @@ -4,6 +4,7 @@ feature = "metal", feature = "dx11", feature = "dx12", + feature = "web", all(debug_assertions, feature = "empty") )))] compile_error!( diff --git a/src/graphics.rs b/src/graphics.rs index 30445e9..d222058 100644 --- a/src/graphics.rs +++ b/src/graphics.rs @@ -95,6 +95,7 @@ use backend_gfx as gpu; feature = "metal", feature = "dx11", feature = "dx12", + feature = "web", all(debug_assertions, feature = "empty") ))] mod backend_wgpu; @@ -103,6 +104,7 @@ mod backend_wgpu; feature = "metal", feature = "dx11", feature = "dx12", + feature = "web", all(debug_assertions, feature = "empty") ))] use backend_wgpu as gpu; diff --git a/src/graphics/backend_wgpu/mod.rs b/src/graphics/backend_wgpu/mod.rs index f8138ad..12fb37f 100644 --- a/src/graphics/backend_wgpu/mod.rs +++ b/src/graphics/backend_wgpu/mod.rs @@ -33,8 +33,12 @@ impl Gpu { .build(event_loop) .map_err(|error| Error::WindowCreation(error.to_string()))?; + #[cfg(not(feature = "web"))] let instance = wgpu::Instance::new(); + #[cfg(feature = "web")] + let instance = wgpu::Instance::new(&window); + let adapter = instance.get_adapter(&wgpu::AdapterDescriptor { power_preference: wgpu::PowerPreference::HighPerformance, }); diff --git a/src/graphics/backend_wgpu/surface.rs b/src/graphics/backend_wgpu/surface.rs index 79b877c..1d9f4bc 100644 --- a/src/graphics/backend_wgpu/surface.rs +++ b/src/graphics/backend_wgpu/surface.rs @@ -18,8 +18,12 @@ impl Surface { instance: &wgpu::Instance, device: &wgpu::Device, ) -> Surface { + #[cfg(not(feature = "web"))] let surface = instance.create_surface(&window); + #[cfg(feature = "web")] + let surface = instance.get_surface(); + let size = window.inner_size().to_physical(window.hidpi_factor()); let (swap_chain, extent, buffer, target) = From 58e01644620989b986b5fbe7a77cea1682cdc9c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Tue, 2 Jul 2019 04:40:07 +0200 Subject: [PATCH 2/8] Use `instant` crate instead of `time::Instant` --- .gitignore | 3 ++- Cargo.toml | 4 +++- src/debug/basic.rs | 47 +++++++++++++++++++++++----------------------- src/timer.rs | 7 ++++--- 4 files changed, 32 insertions(+), 29 deletions(-) diff --git a/.gitignore b/.gitignore index 2f88dba..8399fbd 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ /target **/*.rs.bk -Cargo.lock \ No newline at end of file +Cargo.lock +.cargo diff --git a/Cargo.toml b/Cargo.toml index 5996e56..b21fcfa 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -25,7 +25,7 @@ vulkan = ["wgpu", "wgpu/vulkan", "wgpu_glyph"] metal = ["wgpu", "wgpu/metal", "wgpu_glyph"] dx11 = ["wgpu", "wgpu/dx11", "wgpu_glyph"] dx12 = ["wgpu", "wgpu/dx12", "wgpu_glyph"] -web = ["wgpu", "wgpu/web", "wgpu_glyph"] +web = ["wgpu", "wgpu/web", "wgpu_glyph", "instant/wasm-bindgen", "instant/now"] empty = ["wgpu", "wgpu_glyph"] debug = [] @@ -37,6 +37,7 @@ stretch = "0.2" twox-hash = "1.3" lyon_tessellation = "0.13" gilrs = "0.7" +instant = "0.1" # gfx (OpenGL) gfx = { version = "0.18", optional = true } @@ -63,3 +64,4 @@ gfx-hal = { git = "https://github.com/hecrj/gfx", branch = "web" } gfx-backend-empty = { git = "https://github.com/hecrj/gfx", branch = "web" } gfx-backend-gl = { git = "https://github.com/hecrj/gfx", branch = "web" } winit = { git = "https://github.com/hecrj/winit", branch = "web" } +instant = { git = "https://github.com/hecrj/instant", branch = "fix/illegal-invocation" } diff --git a/src/debug/basic.rs b/src/debug/basic.rs index 25aefd5..3cbc404 100644 --- a/src/debug/basic.rs +++ b/src/debug/basic.rs @@ -1,3 +1,4 @@ +use instant::Instant; use std::time; use crate::graphics; @@ -19,19 +20,19 @@ use crate::graphics; pub struct Debug { font: graphics::Font, enabled: bool, - load_start: time::Instant, + load_start: Instant, load_duration: time::Duration, - frame_start: time::Instant, + frame_start: Instant, frame_durations: TimeBuffer, - interact_start: time::Instant, + interact_start: Instant, interact_duration: time::Duration, - update_start: time::Instant, + update_start: Instant, update_durations: TimeBuffer, - draw_start: time::Instant, + draw_start: Instant, draw_durations: TimeBuffer, - ui_start: time::Instant, + ui_start: Instant, ui_durations: TimeBuffer, - debug_start: time::Instant, + debug_start: Instant, debug_durations: TimeBuffer, text: Vec<(String, String)>, draw_rate: u16, @@ -40,7 +41,7 @@ pub struct Debug { impl Debug { pub(crate) fn new(gpu: &mut graphics::Gpu) -> Self { - let now = time::Instant::now(); + let now = Instant::now(); Self { font: graphics::Font::from_bytes(gpu, graphics::Font::DEFAULT) @@ -67,11 +68,11 @@ impl Debug { } pub(crate) fn loading_started(&mut self) { - self.load_start = time::Instant::now(); + self.load_start = Instant::now(); } pub(crate) fn loading_finished(&mut self) { - self.load_duration = time::Instant::now() - self.load_start; + self.load_duration = Instant::now() - self.load_start; } /// Returns the time spent loading your [`Game`]. @@ -82,11 +83,10 @@ impl Debug { } pub(crate) fn frame_started(&mut self) { - self.frame_start = time::Instant::now(); + self.frame_start = Instant::now(); } pub(crate) fn frame_finished(&mut self) { - self.frame_durations - .push(time::Instant::now() - self.frame_start); + self.frame_durations.push(Instant::now() - self.frame_start); } /// Returns the average time spent per frame. @@ -97,11 +97,11 @@ impl Debug { } pub(crate) fn interact_started(&mut self) { - self.interact_start = time::Instant::now(); + self.interact_start = Instant::now(); } pub(crate) fn interact_finished(&mut self) { - self.interact_duration = time::Instant::now() - self.interact_start; + self.interact_duration = Instant::now() - self.interact_start; } /// Returns the average time spent processing events and running @@ -113,12 +113,12 @@ impl Debug { } pub(crate) fn update_started(&mut self) { - self.update_start = time::Instant::now(); + self.update_start = Instant::now(); } pub(crate) fn update_finished(&mut self) { self.update_durations - .push(time::Instant::now() - self.update_start); + .push(Instant::now() - self.update_start); } /// Returns the average time spent running [`Game::update`]. @@ -129,11 +129,11 @@ impl Debug { } pub(crate) fn draw_started(&mut self) { - self.draw_start = time::Instant::now(); + self.draw_start = Instant::now(); } pub(crate) fn draw_finished(&mut self) { - let duration = time::Instant::now() - self.draw_start; + let duration = Instant::now() - self.draw_start; if duration.subsec_micros() > 0 { self.draw_durations.push(duration); @@ -148,11 +148,11 @@ impl Debug { } pub(crate) fn ui_started(&mut self) { - self.ui_start = time::Instant::now(); + self.ui_start = Instant::now(); } pub(crate) fn ui_finished(&mut self) { - self.ui_durations.push(time::Instant::now() - self.ui_start); + self.ui_durations.push(Instant::now() - self.ui_start); } /// Returns the average time spent rendering the [`UserInterface`]. @@ -168,12 +168,11 @@ impl Debug { } pub(crate) fn debug_started(&mut self) { - self.debug_start = time::Instant::now(); + self.debug_start = Instant::now(); } pub(crate) fn debug_finished(&mut self) { - self.debug_durations - .push(time::Instant::now() - self.debug_start); + self.debug_durations.push(Instant::now() - self.debug_start); } /// Returns the average time spent running [`Game::debug`]. diff --git a/src/timer.rs b/src/timer.rs index 9f69f9e..70c38e3 100644 --- a/src/timer.rs +++ b/src/timer.rs @@ -1,3 +1,4 @@ +use instant::Instant; use std::time; /// The timer of your game state. @@ -11,7 +12,7 @@ use std::time; pub struct Timer { target_ticks: u16, target_delta: time::Duration, - last_tick: time::Instant, + last_tick: Instant, accumulated_delta: time::Duration, has_ticked: bool, } @@ -28,14 +29,14 @@ impl Timer { target_seconds as u64, target_nanos as u32, ), - last_tick: time::Instant::now(), + last_tick: Instant::now(), accumulated_delta: time::Duration::from_secs(0), has_ticked: false, } } pub(crate) fn update(&mut self) { - let now = time::Instant::now(); + let now = Instant::now(); let diff = now - self.last_tick; self.last_tick = now; From 0b9c10ce1b530c521b39fcca65434538b57bd5f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Tue, 2 Jul 2019 04:45:42 +0200 Subject: [PATCH 3/8] Use `seahash` instead of `twox-hash --- Cargo.toml | 1 + src/graphics/backend_wgpu/font.rs | 3 ++- src/ui/core/hasher.rs | 2 +- src/ui/core/interface.rs | 6 +++--- 4 files changed, 7 insertions(+), 5 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index b21fcfa..45e2c88 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -35,6 +35,7 @@ nalgebra = "0.18" rayon = "1.0" stretch = "0.2" twox-hash = "1.3" +seahash = "3.0" lyon_tessellation = "0.13" gilrs = "0.7" instant = "0.1" diff --git a/src/graphics/backend_wgpu/font.rs b/src/graphics/backend_wgpu/font.rs index 8402938..33adfcb 100644 --- a/src/graphics/backend_wgpu/font.rs +++ b/src/graphics/backend_wgpu/font.rs @@ -6,7 +6,7 @@ use crate::graphics::{ use wgpu_glyph::GlyphCruncher; pub struct Font { - glyphs: wgpu_glyph::GlyphBrush<'static>, + glyphs: wgpu_glyph::GlyphBrush<'static, std::hash::BuildHasherDefault>, } impl Font { @@ -14,6 +14,7 @@ impl Font { Font { glyphs: wgpu_glyph::GlyphBrushBuilder::using_font_bytes(bytes) .texture_filter_method(wgpu::FilterMode::Nearest) + .section_hasher(std::hash::BuildHasherDefault::::default()) .build(device, wgpu::TextureFormat::Bgra8UnormSrgb), } } diff --git a/src/ui/core/hasher.rs b/src/ui/core/hasher.rs index a930fa1..3a8712f 100644 --- a/src/ui/core/hasher.rs +++ b/src/ui/core/hasher.rs @@ -1,2 +1,2 @@ /// The hasher used to compare layouts. -pub type Hasher = twox_hash::XxHash; +pub type Hasher = seahash::SeaHasher; diff --git a/src/ui/core/interface.rs b/src/ui/core/interface.rs index 6c66b8f..21ca638 100644 --- a/src/ui/core/interface.rs +++ b/src/ui/core/interface.rs @@ -2,7 +2,7 @@ use std::hash::Hasher; use stretch::result; use crate::graphics::{Frame, Point}; -use crate::ui::core::{self, Element, Event, Layout, MouseCursor}; +use crate::ui::core::{self, Element, Event, Layout, MouseCursor, hasher}; pub struct Interface<'a, Message, Renderer> { hash: u64, @@ -23,7 +23,7 @@ where root: Element<'a, Message, Renderer>, renderer: &Renderer, ) -> Interface<'a, Message, Renderer> { - let hasher = &mut twox_hash::XxHash::default(); + let hasher = &mut hasher::Hasher::default(); root.hash(hasher); let hash = hasher.finish(); @@ -37,7 +37,7 @@ where renderer: &Renderer, cache: Cache, ) -> Interface<'a, Message, Renderer> { - let hasher = &mut twox_hash::XxHash::default(); + let hasher = &mut hasher::Hasher::default(); root.hash(hasher); let hash = hasher.finish(); From ef99958898f72e083ce612d98f85504dba288306 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Tue, 2 Jul 2019 04:46:22 +0200 Subject: [PATCH 4/8] Fix `triangle` pipeline shader --- .../backend_wgpu/shader/triangle.vert | 2 +- .../backend_wgpu/shader/triangle.vert.spv | Bin 1264 -> 1252 bytes src/graphics/backend_wgpu/triangle.rs | 2 +- 3 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/graphics/backend_wgpu/shader/triangle.vert b/src/graphics/backend_wgpu/shader/triangle.vert index 888d5d7..9f55d17 100644 --- a/src/graphics/backend_wgpu/shader/triangle.vert +++ b/src/graphics/backend_wgpu/shader/triangle.vert @@ -7,7 +7,7 @@ layout (set = 0, binding = 0) uniform Globals { mat4 u_Transform; }; -layout(location = 0) flat out vec4 v_Color; +layout(location = 0) out vec4 v_Color; void main() { v_Color = a_Color; diff --git a/src/graphics/backend_wgpu/shader/triangle.vert.spv b/src/graphics/backend_wgpu/shader/triangle.vert.spv index 932730b5c79cfb5666362f3d3ec5cf7f25df6b44..95fb765bcee489be08da013d288f0138d230cbc3 100644 GIT binary patch delta 12 Tcmeys`Gj*r8RO Date: Tue, 2 Jul 2019 04:49:09 +0200 Subject: [PATCH 5/8] Dirtyfix `gfx-backend-gl` 1-layer texture arrays. Apparently, `gfx-backend-gl` cannot easily distinguish between single-layered texture arrays and normal textures. --- src/graphics/backend_wgpu/texture.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/graphics/backend_wgpu/texture.rs b/src/graphics/backend_wgpu/texture.rs index 863687d..0f75c54 100644 --- a/src/graphics/backend_wgpu/texture.rs +++ b/src/graphics/backend_wgpu/texture.rs @@ -169,7 +169,7 @@ fn create_texture_array( let texture = device.create_texture(&wgpu::TextureDescriptor { size: extent, - array_layer_count: layer_count, + array_layer_count: layer_count.max(2), mip_level_count: 1, sample_count: 1, dimension: wgpu::TextureDimension::D2, From e8a5d5e08f666ccda50a5076bbcc3f9321aa63ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Tue, 2 Jul 2019 04:52:08 +0200 Subject: [PATCH 6/8] Use `RGBA` instead of `BGRA` as texture format. Apparently, `BGRA` does not work properly. We should investigate why. --- src/graphics/backend_wgpu/font.rs | 2 +- src/graphics/backend_wgpu/quad.rs | 2 +- src/graphics/backend_wgpu/surface.rs | 4 ++-- src/graphics/backend_wgpu/texture.rs | 20 ++++++++++---------- src/graphics/backend_wgpu/triangle.rs | 2 +- 5 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/graphics/backend_wgpu/font.rs b/src/graphics/backend_wgpu/font.rs index 33adfcb..bdfd1fb 100644 --- a/src/graphics/backend_wgpu/font.rs +++ b/src/graphics/backend_wgpu/font.rs @@ -15,7 +15,7 @@ impl Font { glyphs: wgpu_glyph::GlyphBrushBuilder::using_font_bytes(bytes) .texture_filter_method(wgpu::FilterMode::Nearest) .section_hasher(std::hash::BuildHasherDefault::::default()) - .build(device, wgpu::TextureFormat::Bgra8UnormSrgb), + .build(device, wgpu::TextureFormat::Rgba8UnormSrgb), } } diff --git a/src/graphics/backend_wgpu/quad.rs b/src/graphics/backend_wgpu/quad.rs index e1ad2d4..bddee9d 100644 --- a/src/graphics/backend_wgpu/quad.rs +++ b/src/graphics/backend_wgpu/quad.rs @@ -108,7 +108,7 @@ impl Pipeline { }, primitive_topology: wgpu::PrimitiveTopology::TriangleList, color_states: &[wgpu::ColorStateDescriptor { - format: wgpu::TextureFormat::Bgra8UnormSrgb, + format: wgpu::TextureFormat::Rgba8UnormSrgb, color_blend: wgpu::BlendDescriptor { src_factor: wgpu::BlendFactor::SrcAlpha, dst_factor: wgpu::BlendFactor::OneMinusSrcAlpha, diff --git a/src/graphics/backend_wgpu/surface.rs b/src/graphics/backend_wgpu/surface.rs index 1d9f4bc..c8cc406 100644 --- a/src/graphics/backend_wgpu/surface.rs +++ b/src/graphics/backend_wgpu/surface.rs @@ -110,7 +110,7 @@ fn new_swap_chain( &wgpu::SwapChainDescriptor { usage: wgpu::TextureUsage::OUTPUT_ATTACHMENT | wgpu::TextureUsage::TRANSFER_DST, - format: wgpu::TextureFormat::Bgra8Unorm, + format: wgpu::TextureFormat::Rgba8Unorm, width: size.width.round() as u32, height: size.height.round() as u32, }, @@ -128,7 +128,7 @@ fn new_swap_chain( array_layer_count: 1, mip_level_count: 1, sample_count: 1, - format: wgpu::TextureFormat::Bgra8UnormSrgb, + format: wgpu::TextureFormat::Rgba8UnormSrgb, usage: wgpu::TextureUsage::OUTPUT_ATTACHMENT | wgpu::TextureUsage::TRANSFER_SRC, }); diff --git a/src/graphics/backend_wgpu/texture.rs b/src/graphics/backend_wgpu/texture.rs index 0f75c54..f41d47b 100644 --- a/src/graphics/backend_wgpu/texture.rs +++ b/src/graphics/backend_wgpu/texture.rs @@ -31,16 +31,16 @@ impl Texture { pipeline: &Pipeline, image: &image::DynamicImage, ) -> Texture { - let bgra = image.to_bgra(); - let width = bgra.width() as u16; - let height = bgra.height() as u16; + let rgba = image.to_rgba(); + let width = rgba.width() as u16; + let height = rgba.height() as u16; let (texture, view, binding) = create_texture_array( device, pipeline, width, height, - Some(&[&bgra.into_raw()[..]]), + Some(&[&rgba.into_raw()[..]]), wgpu::TextureUsage::TRANSFER_DST | wgpu::TextureUsage::SAMPLED, ); @@ -59,14 +59,14 @@ impl Texture { pipeline: &Pipeline, layers: &[image::DynamicImage], ) -> Texture { - let first_layer = &layers[0].to_bgra(); + let first_layer = &layers[0].to_rgba(); let width = first_layer.width() as u16; let height = first_layer.height() as u16; - let bgra: Vec> = - layers.iter().map(|i| i.to_bgra().into_raw()).collect(); + let rgba: Vec> = + layers.iter().map(|i| i.to_rgba().into_raw()).collect(); - let raw_layers: Vec<&[u8]> = bgra.iter().map(|i| &i[..]).collect(); + let raw_layers: Vec<&[u8]> = rgba.iter().map(|i| &i[..]).collect(); let (texture, view, binding) = create_texture_array( device, @@ -173,7 +173,7 @@ fn create_texture_array( mip_level_count: 1, sample_count: 1, dimension: wgpu::TextureDimension::D2, - format: wgpu::TextureFormat::Bgra8UnormSrgb, + format: wgpu::TextureFormat::Rgba8UnormSrgb, usage, }); @@ -216,7 +216,7 @@ fn create_texture_array( } let view = texture.create_view(&wgpu::TextureViewDescriptor { - format: wgpu::TextureFormat::Bgra8UnormSrgb, + format: wgpu::TextureFormat::Rgba8UnormSrgb, dimension: wgpu::TextureViewDimension::D2Array, aspect: wgpu::TextureAspectFlags::COLOR, base_mip_level: 0, diff --git a/src/graphics/backend_wgpu/triangle.rs b/src/graphics/backend_wgpu/triangle.rs index f0547ba..3f482f2 100644 --- a/src/graphics/backend_wgpu/triangle.rs +++ b/src/graphics/backend_wgpu/triangle.rs @@ -75,7 +75,7 @@ impl Pipeline { }, primitive_topology: wgpu::PrimitiveTopology::TriangleList, color_states: &[wgpu::ColorStateDescriptor { - format: wgpu::TextureFormat::Bgra8UnormSrgb, + format: wgpu::TextureFormat::Rgba8UnormSrgb, color_blend: wgpu::BlendDescriptor { src_factor: wgpu::BlendFactor::SrcAlpha, dst_factor: wgpu::BlendFactor::OneMinusSrcAlpha, From b9a52854eb8776a282b8b3c2991b30bbbf3d985d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Tue, 2 Jul 2019 04:54:45 +0200 Subject: [PATCH 7/8] Add WASM support to examples :tada: --- Cargo.toml | 6 ++++++ examples/mesh.rs | 20 ++++++++++++++++++-- examples/particles.rs | 34 ++++++++++++++++++++++------------ examples/ui.rs | 20 ++++++++++++++++++-- 4 files changed, 64 insertions(+), 16 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 45e2c88..e1d13eb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -57,6 +57,12 @@ wgpu_glyph = { version = "0.3", optional = true } # Example dependencies rand = { version = "0.6", features = ["wasm-bindgen"] } +[target.'cfg(target_arch = "wasm32")'.dev-dependencies] +log = "0.4" +wasm-bindgen = "0.2" +console_error_panic_hook = "0.1.6" +console_log = "0.1.2" + [patch.crates-io] wgpu = { git = "https://github.com/hecrj/wgpu-rs", branch = "web" } wgpu_glyph = { git = "https://github.com/hecrj/wgpu_glyph", branch = "web" } diff --git a/examples/mesh.rs b/examples/mesh.rs index 68f9da2..f08e6fd 100644 --- a/examples/mesh.rs +++ b/examples/mesh.rs @@ -3,7 +3,7 @@ use coffee::graphics::{ WindowSettings, }; use coffee::input::KeyboardAndMouse; -use coffee::load::Task; +use coffee::load::{loading_screen::ProgressBar, Task}; use coffee::ui::{ slider, Align, Column, Element, Justify, Radio, Renderer, Row, Slider, Text, UserInterface, @@ -12,6 +12,22 @@ use coffee::{Game, Result, Timer}; use std::ops::RangeInclusive; +#[cfg(target_arch = "wasm32")] +use wasm_bindgen::prelude::*; + +#[cfg(target_arch = "wasm32")] +#[wasm_bindgen(start)] +pub fn wasm_main() { + #[cfg(debug_assertions)] + { + use log::Level; + console_log::init_with_level(Level::Trace).expect("error initializing log"); + } + + std::panic::set_hook(Box::new(console_error_panic_hook::hook)); + main().expect("Run main"); +} + fn main() -> Result<()> { ::run(WindowSettings { title: String::from("Mesh - Coffee"), @@ -52,7 +68,7 @@ enum ModeOption { impl Game for Example { type Input = KeyboardAndMouse; - type LoadingScreen = (); + type LoadingScreen = ProgressBar; fn load(_window: &Window) -> Task { Task::new(move || Example { diff --git a/examples/particles.rs b/examples/particles.rs index 3f77267..2b6850d 100644 --- a/examples/particles.rs +++ b/examples/particles.rs @@ -1,10 +1,6 @@ //! A particle gravity simulator that showcases a loading screen, input //! handling, and graphics interpolation with batched drawing and font //! rendering. Move the mouse around to attract the particles. -use rand::Rng; -use rayon::prelude::*; -use std::{thread, time}; - use coffee::graphics::{ Batch, Color, Frame, Image, Point, Rectangle, Sprite, Vector, Window, WindowSettings, @@ -14,6 +10,24 @@ use coffee::load::{loading_screen::ProgressBar, Join, Task}; use coffee::ui::{Checkbox, Column, Element, Justify, Renderer, UserInterface}; use coffee::{Game, Result, Timer}; +use rand::Rng; + +#[cfg(target_arch = "wasm32")] +use wasm_bindgen::prelude::*; + +#[cfg(target_arch = "wasm32")] +#[wasm_bindgen(start)] +pub fn wasm_main() { + #[cfg(debug_assertions)] + { + use log::Level; + console_log::init_with_level(Level::Trace).expect("error initializing log"); + } + + std::panic::set_hook(Box::new(console_error_panic_hook::hook)); + main().expect("Run main"); +} + fn main() -> Result<()> { ::run(WindowSettings { title: String::from("Particles - Coffee"), @@ -74,13 +88,9 @@ impl Game for Particles { Self::generate(window.width(), window.height()), ), Task::stage("Loading assets...", Self::load_palette()), - Task::stage( - "Showing off the loading screen for a bit...", - Task::new(|| thread::sleep(time::Duration::from_secs(2))), - ), ) .join() - .map(|(particles, palette, _)| Particles { + .map(|(particles, palette)| Particles { particles, gravity_centers: vec![Point::new(0.0, 0.0)], batch: Batch::new(palette), @@ -106,7 +116,7 @@ impl Game for Particles { let gravity_centers = self.gravity_centers.clone(); // Update particles in parallel! <3 rayon - self.particles.par_iter_mut().for_each(move |particle| { + self.particles.iter_mut().for_each(move |particle| { particle.acceleration = gravity_centers .iter() .map(|gravity_center| { @@ -133,7 +143,7 @@ impl Game for Particles { }; // Generate sprites in parallel! <3 rayon - let sprites = self.particles.par_iter().map(|particle| { + let sprites = self.particles.iter().map(|particle| { let velocity = particle.velocity + particle.acceleration * delta_factor; @@ -153,7 +163,7 @@ impl Game for Particles { self.batch.clear(); // Use the parallel iterator to populate the batch efficiently - self.batch.par_extend(sprites); + self.batch.extend(sprites); // Draw particles all at once! self.batch.draw(&mut frame.as_target()); diff --git a/examples/ui.rs b/examples/ui.rs index d2d0bce..967741e 100644 --- a/examples/ui.rs +++ b/examples/ui.rs @@ -1,13 +1,29 @@ use coffee::graphics::{ Color, Frame, HorizontalAlignment, Window, WindowSettings, }; -use coffee::load::Task; +use coffee::load::{loading_screen::ProgressBar, Task}; use coffee::ui::{ button, slider, Align, Button, Checkbox, Column, Element, Justify, Radio, Renderer, Row, Slider, Text, UserInterface, }; use coffee::{Game, Result, Timer}; +#[cfg(target_arch = "wasm32")] +use wasm_bindgen::prelude::*; + +#[cfg(target_arch = "wasm32")] +#[wasm_bindgen(start)] +pub fn wasm_main() { + #[cfg(debug_assertions)] + { + use log::Level; + console_log::init_with_level(Level::Trace).expect("error initializing log"); + } + + std::panic::set_hook(Box::new(console_error_panic_hook::hook)); + main().expect("Run main"); +} + fn main() -> Result<()> { ::run(WindowSettings { title: String::from("User Interface - Coffee"), @@ -25,7 +41,7 @@ struct Tour { impl Game for Tour { type Input = (); - type LoadingScreen = (); + type LoadingScreen = ProgressBar; fn load(_window: &Window) -> Task { Task::new(|| Tour { From e30cc96ce109488d0135b58947b03d20e6a08c86 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Tue, 2 Jul 2019 05:36:25 +0200 Subject: [PATCH 8/8] Install WASM target on CI --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index 55e50e8..540a3c9 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,6 +12,7 @@ before_install: if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then sudo apt-get -qq update sudo apt-get install -y libudev-dev + rustup target add wasm32-unknown-unknown fi - | if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then