imgui piped sort of how I want it. but not really

master
mitchellhansen 4 years ago
parent d12083506b
commit fa059fd177

@ -8,6 +8,11 @@ use cgmath::Deg;
// a component is any type that is 'static, sized, send and sync
pub struct ImguiWindow<'a> {
pub window: imgui::Window<'a>,
}
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct LoopState {
pub delta_time: Duration,

@ -1,4 +1,4 @@
//! This crate provides a winit-based backend platform for imgui-rs.
//! This crate provides a winit-based backend platform for imgui_supp-rs.
//!
//! A backend platform handles window/input device events and manages their
//! state.
@ -17,7 +17,7 @@
//!
//! ```rust,no_run,ignore
//! # // TODO: Remove ignore when only one winit version is used
//! use imgui::Context;
//! use imgui_supp::Context;
//! use imgui_winit_support::{HiDpiMode, WinitPlatform};
//! use std::time::Instant;
//! use winit::event::{Event, WindowEvent};
@ -27,11 +27,11 @@
//! let mut event_loop = EventLoop::new();
//! let mut window = Window::new(&event_loop).unwrap();
//!
//! let mut imgui = Context::create();
//! // configure imgui-rs Context if necessary
//! let mut imgui_supp = Context::create();
//! // configure imgui_supp-rs Context if necessary
//!
//! let mut platform = WinitPlatform::init(&mut imgui); // step 1
//! platform.attach_window(imgui.io_mut(), &window, HiDpiMode::Default); // step 2
//! let mut platform = WinitPlatform::init(&mut imgui_supp); // step 1
//! platform.attach_window(imgui_supp.io_mut(), &window, HiDpiMode::Default); // step 2
//!
//! let mut last_frame = Instant::now();
//! let mut run = true;
@ -39,16 +39,16 @@
//! match event {
//! Event::NewEvents(_) => {
//! // other application-specific logic
//! last_frame = imgui.io_mut().update_delta_time(last_frame);
//! last_frame = imgui_supp.io_mut().update_delta_time(last_frame);
//! },
//! Event::MainEventsCleared => {
//! // other application-specific logic
//! platform.prepare_frame(imgui.io_mut(), &window) // step 4
//! platform.prepare_frame(imgui_supp.io_mut(), &window) // step 4
//! .expect("Failed to prepare frame");
//! window.request_redraw();
//! }
//! Event::RedrawRequested(_) => {
//! let ui = imgui.frame();
//! let ui = imgui_supp.frame();
//! // application-specific rendering *under the UI*
//!
//! // construct the UI
@ -65,7 +65,7 @@
//! }
//! // other application-specific event handling
//! event => {
//! platform.handle_event(imgui.io_mut(), &window, &event); // step 3
//! platform.handle_event(imgui_supp.io_mut(), &window, &event); // step 3
//! // other application-specific event handling
//! }
//! }
@ -107,7 +107,7 @@
//! your `Cargo.toml`:
//!
//! ```toml
//! [dependencies.imgui-winit-support]
//! [dependencies.imgui_supp-winit-support]
//! version = "0.6"
//! features = ["winit-$YOUR_VERSION_HERE"]
//! default-features = false
@ -238,7 +238,7 @@ fn check_multiple_winits() {
// ensure atomicity.
let _ = writeln!(
err,
"Warning (imgui-winit-support): More than one `winit-*` version feature is enabled \
"Warning (imgui_supp-winit-support): More than one `winit-*` version feature is enabled \
(this likely indicates misconfiguration, see documentation for details)."
);
let feats = [
@ -373,10 +373,10 @@ enum ActiveHiDpiMode {
/// DPI factor handling mode.
///
/// Applications that use imgui-rs might want to customize the used DPI factor and not use
/// Applications that use imgui_supp-rs might want to customize the used DPI factor and not use
/// directly the value coming from winit.
///
/// **Note: if you use a mode other than default and the DPI factor is adjusted, winit and imgui-rs
/// **Note: if you use a mode other than default and the DPI factor is adjusted, winit and imgui_supp-rs
/// will use different logical coordinates, so be careful if you pass around logical size or
/// position values.**
#[derive(Copy, Clone, Debug, PartialEq)]
@ -405,9 +405,9 @@ impl HiDpiMode {
}
impl WinitPlatform {
/// Initializes a winit platform instance and configures imgui.
/// Initializes a winit platform instance and configures imgui_supp.
///
/// This function configures imgui-rs in the following ways:
/// This function configures imgui_supp-rs in the following ways:
///
/// * backend flags are updated
/// * keys are configured
@ -441,7 +441,7 @@ impl WinitPlatform {
io[Key::Y] = VirtualKeyCode::Y as _;
io[Key::Z] = VirtualKeyCode::Z as _;
imgui.set_platform_name(Some(ImString::from(format!(
"imgui-winit-support {}",
"imgui_supp-winit-support {}",
env!("CARGO_PKG_VERSION")
))));
WinitPlatform {
@ -453,7 +453,7 @@ impl WinitPlatform {
}
/// Attaches the platform instance to a winit window.
///
/// This function configures imgui-rs in the following ways:
/// This function configures imgui_supp-rs in the following ways:
///
/// * framebuffer scale (= DPI factor) is set
/// * display size is set
@ -478,7 +478,7 @@ impl WinitPlatform {
}
/// Attaches the platform instance to a winit window.
///
/// This function configures imgui-rs in the following ways:
/// This function configures imgui_supp-rs in the following ways:
///
/// * framebuffer scale (= DPI factor) is set
/// * display size is set
@ -506,7 +506,7 @@ impl WinitPlatform {
/// Scales a logical size coming from winit using the current DPI mode.
///
/// This utility function is useful if you are using a DPI mode other than default, and want
/// your application to use the same logical coordinates as imgui-rs.
/// your application to use the same logical coordinates as imgui_supp-rs.
#[cfg(all(
not(any(
feature = "winit-24",
@ -527,7 +527,7 @@ impl WinitPlatform {
/// Scales a logical size coming from winit using the current DPI mode.
///
/// This utility function is useful if you are using a DPI mode other than default, and want
/// your application to use the same logical coordinates as imgui-rs.
/// your application to use the same logical coordinates as imgui_supp-rs.
#[cfg(any(
feature = "winit-20",
feature = "winit-22",
@ -549,7 +549,7 @@ impl WinitPlatform {
/// Scales a logical position coming from winit using the current DPI mode.
///
/// This utility function is useful if you are using a DPI mode other than default, and want
/// your application to use the same logical coordinates as imgui-rs.
/// your application to use the same logical coordinates as imgui_supp-rs.
#[cfg(all(
not(any(
feature = "winit-24",
@ -574,7 +574,7 @@ impl WinitPlatform {
/// Scales a logical position coming from winit using the current DPI mode.
///
/// This utility function is useful if you are using a DPI mode other than default, and want
/// your application to use the same logical coordinates as imgui-rs.
/// your application to use the same logical coordinates as imgui_supp-rs.
#[cfg(any(
feature = "winit-20",
feature = "winit-22",
@ -596,7 +596,7 @@ impl WinitPlatform {
/// Scales a logical position for winit using the current DPI mode.
///
/// This utility function is useful if you are using a DPI mode other than default, and want
/// your application to use the same logical coordinates as imgui-rs.
/// your application to use the same logical coordinates as imgui_supp-rs.
#[cfg(all(
not(any(
feature = "winit-24",
@ -621,7 +621,7 @@ impl WinitPlatform {
/// Scales a logical position for winit using the current DPI mode.
///
/// This utility function is useful if you are using a DPI mode other than default, and want
/// your application to use the same logical coordinates as imgui-rs.
/// your application to use the same logical coordinates as imgui_supp-rs.
#[cfg(any(
feature = "winit-20",
feature = "winit-22",
@ -722,7 +722,7 @@ impl WinitPlatform {
// We need to track modifiers separately because some system like macOS, will
// not reliably send modifier states during certain events like ScreenCapture.
// Gotta let the people show off their pretty imgui widgets!
// Gotta let the people show off their pretty imgui_supp widgets!
Event::DeviceEvent {
event: DeviceEvent::ModifiersChanged(modifiers),
..
@ -751,7 +751,7 @@ impl WinitPlatform {
} if window_id == window.id() => {
// We need to track modifiers separately because some system like macOS, will
// not reliably send modifier states during certain events like ScreenCapture.
// Gotta let the people show off their pretty imgui widgets!
// Gotta let the people show off their pretty imgui_supp widgets!
if let OwnedWindowEvent::ModifiersChanged(modifiers) = event {
io.key_shift = modifiers.shift();
io.key_ctrl = modifiers.ctrl();
@ -1084,10 +1084,10 @@ impl WinitPlatform {
}
/// Frame preparation callback.
///
/// Call this before calling the imgui-rs context `frame` function.
/// Call this before calling the imgui_supp-rs context `frame` function.
/// This function performs the following actions:
///
/// * mouse cursor is repositioned (if requested by imgui-rs)
/// * mouse cursor is repositioned (if requested by imgui_supp-rs)
#[cfg(all(
not(any(
feature = "winit-24",
@ -1111,10 +1111,10 @@ impl WinitPlatform {
}
/// Frame preparation callback.
///
/// Call this before calling the imgui-rs context `frame` function.
/// Call this before calling the imgui_supp-rs context `frame` function.
/// This function performs the following actions:
///
/// * mouse cursor is repositioned (if requested by imgui-rs)
/// * mouse cursor is repositioned (if requested by imgui_supp-rs)
#[cfg(any(
feature = "winit-20",
feature = "winit-22",
@ -1142,10 +1142,10 @@ impl WinitPlatform {
/// Render preparation callback.
///
/// Call this before calling the imgui-rs UI `render_with`/`render` function.
/// Call this before calling the imgui_supp-rs UI `render_with`/`render` function.
/// This function performs the following actions:
///
/// * mouse cursor is changed and/or hidden (if requested by imgui-rs)
/// * mouse cursor is changed and/or hidden (if requested by imgui_supp-rs)
pub fn prepare_render(&mut self, ui: &Ui, window: &Window) {
let io = ui.io();
if !io

@ -0,0 +1,12 @@
use crate::imgui_supp::extended_winit_imgui_support::WinitPlatform;
pub struct ImguiContext {
pub context: imgui::Context,
}
unsafe impl Send for ImguiContext {}
pub struct ImguiPlatform {
pub platform: WinitPlatform,
}
unsafe impl Send for ImguiPlatform {}

@ -0,0 +1,2 @@
pub mod extended_winit_imgui_support;
pub mod imgui_support;

@ -3,6 +3,7 @@ extern crate imgui_wgpu;
extern crate tobj;
extern crate winit_24;
use std::borrow::Borrow;
use std::f32::consts::PI;
use std::rc::Rc;
use std::sync::{Arc, Mutex};
@ -15,10 +16,13 @@ use cgmath::{
};
use futures::executor::block_on;
use futures::task::LocalSpawn;
use gilrs::{Gamepad, Gilrs};
use gilrs::Event as GilEvent;
use gilrs::{Gamepad, Gilrs};
use imgui::FontSource;
use imgui::__core::convert::TryInto;
use imgui::*;
use imgui_wgpu::{Renderer as ImguiRenderer, RendererConfig as ImguiRendererConfig};
use legion::systems::{SyncResources, UnsafeResources};
use legion::*;
use rapier3d::counters::Timer;
use rapier3d::dynamics::{
@ -30,32 +34,30 @@ use rapier3d::na::{Isometry, Isometry3, Vector, Vector3};
use rapier3d::pipeline::PhysicsPipeline;
use wgpu::{BindGroup, Buffer, TextureView};
use wgpu_subscriber;
use winit_24::event::DeviceEvent::MouseMotion;
use winit_24::platform::unix::x11::ffi::Time;
use winit_24::window::Window;
use winit_24::{
event::{self, WindowEvent},
event_loop::{ControlFlow, EventLoop},
};
use winit_24::event::DeviceEvent::MouseMotion;
use winit_24::platform::unix::x11::ffi::Time;
use winit_24::window::Window;
use crate::camera::{Camera, CameraController};
use crate::components::{Collider, Color, LoopState, Physics, Position};
use crate::components::{Collider, Color, ImguiWindow, LoopState, Physics, Position};
use crate::imgui_supp::extended_winit_imgui_support;
use crate::imgui_supp::imgui_support::{ImguiContext, ImguiPlatform};
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 crate::extended_winit_imgui_support::WinitPlatform;
mod camera;
mod components;
mod geometry;
mod imgui_supp;
mod light;
mod owned_event;
mod physics;
mod render;
mod extended_winit_imgui_support;
/*
@ -75,12 +77,10 @@ legion ECS
https://github.com/amethyst/legion
mvp:
ECS
animation
render 3d (good!)
input/io
input/io (yep!)
collision / physics (yep!)
entities & behaviours (got the entities!)
@ -88,20 +88,18 @@ ECS
//log::info!("");
// ImGUI works on more or less a global state. which is MegaLame
static mut CURRENT_UI: Option<imgui::Ui<'static>> = None;
pub unsafe fn current_ui<'a>() -> Option<&'a imgui::Ui<'a>> { CURRENT_UI.as_ref() }
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 imgui_prepare_schedule = Schedule::builder()
.add_system(render::imgui_prepare_system())
.build();
let mut render_schedule = Schedule::builder()
.add_system(render::render_test_system())
.build();
@ -135,23 +133,24 @@ fn main() {
extended_winit_imgui_support::HiDpiMode::Default,
);
// imgui rendering context
// imgui_supp rendering context
let mut imgui_context = ImguiContext {
context: imgui_context,
};
let mut imgui_platform = ImguiPlatform {
platform: platform,
};
let mut imgui_platform = ImguiPlatform { platform: platform };
let font_size = 20.0 as f32;
imgui_context.context.io_mut().font_global_scale = 1.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
.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
@ -236,13 +235,21 @@ fn main() {
*control_flow = ControlFlow::Poll;
match event {
event::Event::NewEvents(cause) => {
}
// This is the big boy section of the event loop
// We : dispatch events and clear the queue, query the loops
// time data and prep the dt data. Loop the dt locked
// conditionally, and run the fps locked renderer
event::Event::MainEventsCleared => {
event_schedule.execute(&mut world, &mut resources);
imgui_prepare_schedule.execute(&mut world, &mut resources);
resources
.get_mut::<Vec<OwnedEvent<OwnedEventExtension>>>()
.unwrap()
.clear();
}
event::Event::MainEventsCleared => {
let (step_size, elapsed_time) = {
// deltatime since last frame
let loop_state = resources.get::<LoopState>().unwrap();
@ -287,7 +294,8 @@ fn main() {
} => *control_flow = ControlFlow::Exit,
event::Event::RedrawRequested(_) => {
// Call the render system
render_schedule.execute(&mut world, &mut resources);
// imgui_prepare_schedule.execute(&mut world, &mut resources);
// render_schedule.execute(&mut world, &mut resources);
}
_ => {}
}
@ -299,8 +307,9 @@ fn main() {
});
}
pub fn entity_loading(world: &mut World, renderer: &mut Renderer) {
let monkey_mesh = renderer.load_mesh_to_buffer("./resources/monkey.obj");
let camera_ent: Entity = world.push((

@ -10,10 +10,10 @@ use winit_24::window::{Theme, WindowId, Window};
use crate::camera::{Camera, CameraController};
use crate::owned_event::OwnedWindowEvent::MouseWheel;
use crate::{ImguiPlatform, ImguiContext};
use std::sync::{Mutex, Arc};
use std::cmp::Ordering;
use imgui::Io;
use crate::imgui_supp::imgui_support::{ImguiContext, ImguiPlatform};
#[derive(Clone)]
pub enum OwnedUIEvent<T> {
@ -297,6 +297,7 @@ pub fn event_dispatch(
}
_ => {}
}
let mut imgui_context = &mut imgui_context.lock().unwrap().context;
let mut imgui_platform = &mut imgui_platform.lock().unwrap().platform;

@ -1,4 +1,7 @@
use std::cell::RefCell;
use std::sync::{Arc, Mutex};
use std::thread::current;
use std::time::Duration;
use std::{iter, num::NonZeroU32, ops::Range, rc::Rc};
use bytemuck::__core::mem;
@ -8,6 +11,9 @@ use cgmath::{
Transform, Vector3,
};
use futures::executor::LocalPool;
use imgui::sys::ImGuiContext;
use imgui::*;
use imgui_wgpu::{Renderer as ImguiRenderer, RendererConfig as ImguiRendererConfig};
use legion::world::SubWorld;
use legion::*;
use rapier3d::parry::motion::RigidMotionComposition;
@ -23,14 +29,10 @@ use winit_24::window::Window;
use crate::camera::{Camera, CameraController};
use crate::components::{Color, Mesh, Position, RangeCopy};
use crate::current_ui;
use crate::geometry::{import_mesh, vertex, Vertex};
use crate::imgui_supp::imgui_support::{ImguiContext, ImguiPlatform};
use crate::light::{DirectionalLight, LightRaw};
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)]
@ -79,6 +81,27 @@ pub struct Pass {
uniform_buf: wgpu::Buffer,
}
#[system]
#[write_component(Camera)]
pub fn imgui_prepare(
world: &mut SubWorld,
#[resource] winit_window: &mut Window,
#[resource] imgui_context: &mut Arc<Mutex<ImguiContext>>,
#[resource] imgui_platform: &mut Arc<Mutex<ImguiPlatform>>,
) {
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
unsafe { crate::CURRENT_UI = Some(std::mem::transmute(imgui_context.frame())) }
}
#[system]
#[write_component(Camera)]
#[write_component(Position)]
@ -93,7 +116,6 @@ pub fn render_test(
#[resource] imgui_context: &mut Arc<Mutex<ImguiContext>>,
#[resource] imgui_platform: &mut Arc<Mutex<ImguiPlatform>>,
) {
let mut encoder = renderer
.device
.create_command_encoder(&wgpu::CommandEncoderDescriptor { label: None });
@ -101,9 +123,6 @@ pub fn render_test(
let frame = renderer.get_current_frame();
// Update the camera uniform buffers, need to make it support selection of
// cameras
let mut query = <(&mut Camera)>::query();
@ -118,7 +137,6 @@ pub fn render_test(
}
let mut query = <(&mut Position, &mut Mesh, &mut Color)>::query();
let mut mesh_stack = Vec::new();
// Update the entity uniforms
@ -244,17 +262,12 @@ pub fn render_test(
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");
let ui = unsafe { crate::current_ui().unwrap() };
// 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, 100.0], Condition::FirstUseEver)
@ -263,8 +276,7 @@ pub fn render_test(
ui.text(im_str!("Frametime: {:?}", 10.0));
});
//ui.show_demo_window(&mut demo_open);
// ui.show_demo_window(&mut true);
imgui_platform.prepare_render(&ui, &winit_window);
let mut rpass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
@ -279,16 +291,23 @@ pub fn render_test(
}],
depth_stencil_attachment: None,
});
renderer.imgui_renderer
.render(ui.render(), &renderer.queue, &renderer.device, &mut rpass)
// We gotta do some jank shit here and manually pull the draw data from the UI
let draw_data = unsafe {
crate::CURRENT_UI = None; // This is where the drop() occurs
imgui::sys::igRender();
&*(imgui::sys::igGetDrawData() as *mut imgui::DrawData)
};
renderer
.imgui_renderer
.render(draw_data, &renderer.queue, &renderer.device, &mut rpass)
.expect("Rendering failed");
}
renderer.queue.submit(iter::once(encoder.finish()));
}
pub struct Renderer {
swapchain: SwapChain,
swapchain_description: SwapChainDescriptor,
@ -314,7 +333,6 @@ pub struct Renderer {
camera_projection: Matrix4<f32>,
imgui_renderer: ImguiRenderer,
}
impl Renderer {
@ -456,7 +474,6 @@ impl 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);
let (size, surface) = unsafe {
@ -631,9 +648,7 @@ impl Renderer {
slope_scale: 2.0,
clamp: 0.0,
},
clamp_depth: device.features().contains(
wgpu::Features::DEPTH_CLAMPING
),
clamp_depth: device.features().contains(wgpu::Features::DEPTH_CLAMPING),
}),
multisample: wgpu::MultisampleState::default(),
});
@ -867,14 +882,13 @@ impl Renderer {
label: Some("Depth Texture"),
});
// 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);
let mut imgui_renderer =
ImguiRenderer::new(&mut imgui_context.context, &device, &queue, renderer_config);
Renderer {
swapchain: swap_chain,
@ -893,7 +907,7 @@ impl Renderer {
instance: Arc::new(instance),
views_given: 0,
camera_projection: mx_projection,
imgui_renderer
imgui_renderer,
}
}

Loading…
Cancel
Save