diff --git a/src/main.rs b/src/main.rs index 8ac4c19..4e23352 100644 --- a/src/main.rs +++ b/src/main.rs @@ -6,7 +6,7 @@ extern crate winit; use std::f32::consts::PI; use std::rc::Rc; -use std::sync::Arc; +use std::sync::{Arc, Mutex}; #[cfg(not(target_arch = "wasm32"))] use std::time::{Duration, Instant}; @@ -44,6 +44,10 @@ use crate::components::{Collider, Color, LoopState, Physics, Position}; use crate::owned_event::{OwnedEvent, OwnedEventExtension}; use crate::physics::PhysicsState; use crate::render::Renderer; +use legion::systems::{UnsafeResources, SyncResources}; +use std::borrow::Borrow; +use imgui::__core::convert::TryInto; +use imgui_winit_support::WinitPlatform; mod camera; mod components; @@ -84,20 +88,26 @@ ECS //log::info!(""); + +pub struct ImguiContext { + pub context: imgui::Context, +} +unsafe impl Send for ImguiContext {} + +pub struct ImguiPlatform { + pub platform: WinitPlatform, +} +unsafe impl Send for ImguiPlatform {} + fn main() { let mut world = World::default(); - let (mut pool, spawner) = { - let local_pool = futures::executor::LocalPool::new(); - let spawner = local_pool.spawner(); - (local_pool, spawner) - }; - let mut render_schedule = Schedule::builder() .add_system(render::render_test_system()) .build(); let mut update_schedule = Schedule::builder() + .add_system(physics::test_unsafe_system()) .add_system(physics::update_camera_system()) .add_system(physics::run_physics_system()) .add_system(physics::update_models_system()) @@ -118,11 +128,41 @@ fn main() { // Load up all the resources { + let mut imgui_context = imgui::Context::create(); + let mut platform = imgui_winit_support::WinitPlatform::init(&mut imgui_context); + platform.attach_window( + imgui_context.io_mut(), + &window, + imgui_winit_support::HiDpiMode::Default, + ); + + // imgui rendering context + let mut imgui_context = ImguiContext { + context: imgui_context, + }; + let mut imgui_platform = ImguiPlatform { + platform: platform, + }; + let font_size = 10.0 as f32; + imgui_context.context.io_mut().font_global_scale = 10.0 as f32; + + imgui_context.context.fonts().add_font(&[FontSource::DefaultFontData { + config: Some(imgui::FontConfig { + oversample_h: 1, + pixel_snap_h: true, + size_pixels: font_size, + ..Default::default() + }), + }]); + imgui_context.context.set_ini_filename(None); // The renderer let mut renderer = render::Renderer::init(&window, &mut imgui_context); entity_loading(&mut world, &mut renderer); + resources.insert(renderer); + resources.insert(Arc::new(Mutex::new(imgui_context))); + resources.insert(Arc::new(Mutex::new(imgui_platform))); resources.insert(window); // Physics @@ -140,7 +180,6 @@ fn main() { // And our event stack resources.insert(Vec::>::new()); - }; let event_loop_proxy = event_loop.create_proxy(); diff --git a/src/physics.rs b/src/physics.rs index 62146fe..e6f04e8 100644 --- a/src/physics.rs +++ b/src/physics.rs @@ -12,6 +12,7 @@ use rapier3d::pipeline::PhysicsPipeline; use crate::camera::{Camera, CameraController}; use crate::components::{Collider, LoopState, Mesh, Physics, Position}; use crate::render::{EntityUniforms, Renderer}; +use imgui::FontSource; pub struct PhysicsState { gravity: rapier3d::math::Vector, @@ -88,22 +89,20 @@ pub fn run_physics( #[system] #[write_component(Camera)] -#[write_component(CameraController)] -pub fn update_camera(world: &mut SubWorld, #[resource] loop_state: &mut LoopState) { - let mut query = <(&mut Camera, &mut CameraController)>::query(); - for (mut camera, controller) in query.iter_mut(world) { - controller.update_camera(&mut camera, loop_state.step_size) - } +pub fn test_unsafe(world: &mut SubWorld, + #[resource] loop_state: &mut LoopState, + // #[resource] imgui_context: &mut imgui::Context, +) { + + + } + #[system] #[write_component(Camera)] -pub fn update_imgui( - world: &mut SubWorld, - #[resource] loop_state: &mut LoopState, - #[resource] renderer: &mut Renderer, -) { - +#[write_component(CameraController)] +pub fn update_camera(world: &mut SubWorld, #[resource] loop_state: &mut LoopState) { let mut query = <(&mut Camera, &mut CameraController)>::query(); for (mut camera, controller) in query.iter_mut(world) { controller.update_camera(&mut camera, loop_state.step_size) diff --git a/src/render.rs b/src/render.rs index 0c1c7db..ca0f6d4 100644 --- a/src/render.rs +++ b/src/render.rs @@ -1,4 +1,4 @@ -use std::sync::Arc; +use std::sync::{Arc, Mutex}; use std::{iter, num::NonZeroU32, ops::Range, rc::Rc}; use bytemuck::__core::mem; @@ -29,6 +29,9 @@ use imgui_winit_support::WinitPlatform; use imgui::*; use imgui_wgpu::{Renderer as ImguiRenderer, RendererConfig as ImguiRendererConfig}; use std::cell::RefCell; +use imgui::sys::ImGuiContext; +use crate::{ImguiContext, ImguiPlatform}; +use std::time::Duration; #[cfg_attr(rustfmt, rustfmt_skip)] #[allow(unused)] @@ -88,6 +91,8 @@ pub fn render_test( world: &mut SubWorld, #[resource] renderer: &mut Renderer, #[resource] winit_window: &mut Window, + #[resource] imgui_context: &mut Arc>, + #[resource] imgui_platform: &mut Arc>, ) { let mut encoder = renderer @@ -98,91 +103,8 @@ pub fn render_test( let frame = renderer.get_current_frame(); - // set up imgui for rendering - // update delta time and prepare the frame - //renderer.imgui_platform.io_mut().update_delta_time(now - last_frame); - { - - let mut imgui_context = imgui::Context::create(); - imgui_context.set_ini_filename(None); - - let font_size = 10.0 as f32; - //imgui_context.io_mut().font_global_scale = 10.0 as f32; - - imgui_context.fonts().add_font(&[FontSource::DefaultFontData { - config: Some(imgui::FontConfig { - oversample_h: 1, - pixel_snap_h: true, - size_pixels: font_size, - ..Default::default() - }), - }]); - - // The imgui context lives as a resource for the render system to use - let mut platform = imgui_winit_support::WinitPlatform::init(imgui_context); - platform.attach_window( - imgui_context.io_mut(), - window, - imgui_winit_support::HiDpiMode::Default, - ); - - let clear_color = wgpu::Color { - r: 0.1, - g: 0.2, - b: 0.3, - a: 1.0, - }; - - let renderer_config = ImguiRendererConfig { - texture_format: sc_desc.format, - ..Default::default() - }; - - let mut renderer = ImguiRenderer::new(imgui_context, &device, &queue, renderer_config); - - renderer.imgui_platform - .prepare_frame(imgui_context.io_mut(), &winit_window) - .expect("Failed to prepare frame"); - - // get the frame and build a ui window - let ui = imgui_context.frame(); - let window = imgui::Window::new(im_str!("Hello too")); - window - .size([400.0, 200.0], Condition::FirstUseEver) - .position([400.0, 200.0], Condition::FirstUseEver) - .build(&ui, || { - ui.text(im_str!("Frametime: {:?}", 10.0)); - }); - - - //ui.show_demo_window(&mut demo_open); - renderer.imgui_platform.prepare_render(&ui, &winit_window); - - let mut rpass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor { - label: None, - color_attachments: &[wgpu::RenderPassColorAttachmentDescriptor { - attachment: &frame.output.view, - resolve_target: None, - ops: wgpu::Operations { - load: wgpu::LoadOp::Clear(wgpu::Color { - r: 0.1, - g: 0.2, - b: 0.3, - a: 1.0, - }), - store: true, - }, - }], - depth_stencil_attachment: None, - }); - renderer.imgui_renderer - .render(ui.render(), &renderer.queue, &renderer.device, &mut rpass) - .expect("Rendering failed"); - - drop(rpass); - } // Update the camera uniform buffers, need to make it support selection of // cameras let mut query = <(&mut Camera)>::query(); @@ -322,9 +244,59 @@ pub fn render_test( encoder.pop_debug_group(); encoder.pop_debug_group(); + { + + // let mut imgui_context = &mut imgui_context.lock().unwrap().context; + // let mut imgui_platform = &mut imgui_platform.lock().unwrap().platform; + // + // //imgui_state.context.io_mut().update_delta_time(Duration::new(0,160)); + // imgui_platform + // .prepare_frame(imgui_context.io_mut(), &winit_window) + // .expect("Failed to prepare frame"); + // + // // get the frame and build a ui window + // let ui = imgui_context.frame(); + // let window = imgui::Window::new(im_str!("Hello too")); + // window + // .size([400.0, 200.0], Condition::FirstUseEver) + // .position([400.0, 200.0], Condition::FirstUseEver) + // .build(&ui, || { + // ui.text(im_str!("Frametime: {:?}", 10.0)); + // }); + // + // + // //ui.show_demo_window(&mut demo_open); + // imgui_platform.prepare_render(&ui, &winit_window); + // + // let mut rpass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor { + // label: None, + // color_attachments: &[wgpu::RenderPassColorAttachmentDescriptor { + // attachment: &frame.output.view, + // resolve_target: None, + // ops: wgpu::Operations { + // load: wgpu::LoadOp::Clear(wgpu::Color { + // r: 0.1, + // g: 0.2, + // b: 0.3, + // a: 1.0, + // }), + // store: true, + // }, + // }], + // depth_stencil_attachment: None, + // }); + // renderer.imgui_renderer + // .render(ui.render(), &renderer.queue, &renderer.device, &mut rpass) + // .expect("Rendering failed"); + // + + } + + renderer.queue.submit(iter::once(encoder.finish())); } + pub struct Renderer { swapchain: SwapChain, swapchain_description: SwapChainDescriptor, @@ -349,7 +321,6 @@ pub struct Renderer { camera_projection: Matrix4, - imgui_platform: WinitPlatform, imgui_renderer: ImguiRenderer, } @@ -492,7 +463,7 @@ impl Renderer { } } - pub fn init(window: &Window, imgui_context: &mut imgui::Context) -> Renderer { + pub fn init(window: &Window, imgui_context: &mut ImguiContext) -> Renderer { // Grab the GPU instance, and query its features let instance = wgpu::Instance::new(wgpu::BackendBit::PRIMARY); @@ -905,6 +876,14 @@ impl Renderer { }); + // Imgui renderer + let renderer_config = ImguiRendererConfig { + texture_format: sc_desc.format, + ..Default::default() + }; + let mut imgui_renderer = ImguiRenderer::new(&mut imgui_context.context, &device, &queue, renderer_config); + + Renderer { swapchain: swap_chain, queue: queue, @@ -922,8 +901,7 @@ impl Renderer { instance: Arc::new(instance), views_given: 0, camera_projection: mx_projection, - imgui_platform: platform, - imgui_renderer: renderer + imgui_renderer } }