Huge input update, FPS Camera controls system

Long day. I now store winit:🪟:Window in a mutex.
This commit is contained in:
reo 2025-09-28 01:31:14 +03:00
parent 1e9b997aeb
commit 46c8c32819
15 changed files with 307 additions and 39 deletions

View file

@ -1,5 +1,6 @@
use std::cell::RefCell;
use std::rc::Rc;
use std::sync::{Arc, Mutex};
use raidillon_platform::{Platform, PlatformContext, TimeContext};
use glium::backend::glutin::Display;
use glium::backend::glutin::SimpleWindowBuilder;
@ -8,7 +9,7 @@ use glium::winit::event_loop::EventLoop;
use glium::winit::window::Window;
use glium::Surface;
use crate::system::{RenderingContext, RenderingSystemManager};
use winit::event::{Event, WindowEvent};
use winit::event::{DeviceEvent, Event, WindowEvent};
use raidillon_assets::ModelManagerRef;
use raidillon_core::engine::EngineTrait;
use raidillon_core::time;
@ -17,10 +18,11 @@ use crate::render::debug_ui::ImguiBridge;
use crate::render::{BasicMeshRenderingSystem, SkyboxRenderingSystem};
use crate::GliumAssetManager;
use glam::Vec3;
use winit::event::DeviceEvent::MouseMotion;
pub struct GliumPlatform<E: EngineTrait<PlatformCtx = PlatformContext>> {
event_loop: EventLoop<()>,
window: Window,
window: Arc<Mutex<Window>>,
display: Display<WindowSurface>,
rendering_system_manager: RenderingSystemManager,
asset_manager: ModelManagerRef,
@ -45,10 +47,12 @@ impl<E: EngineTrait<PlatformCtx = PlatformContext>> Platform<E> for GliumPlatfor
let time_cfg = time::Config::default();
let time = time::Time::new(time_cfg);
let window = Arc::new(Mutex::new(window));
// Install rendering systems in order
rendering_system_manager.add::<SkyboxRenderingSystem>(&display, &window);
rendering_system_manager.add::<BasicMeshRenderingSystem>(&display, &window);
rendering_system_manager.add::<ImguiBridge>(&display, &window);
rendering_system_manager.add::<SkyboxRenderingSystem>(&display, window.clone());
rendering_system_manager.add::<BasicMeshRenderingSystem>(&display, window.clone());
rendering_system_manager.add::<ImguiBridge>(&display, window.clone());
Self {
event_loop,
@ -62,20 +66,24 @@ impl<E: EngineTrait<PlatformCtx = PlatformContext>> Platform<E> for GliumPlatfor
}
fn run(mut self) {
let (w, h): (u32, u32) = self.window.inner_size().into();
let (w, h): (u32, u32) = match self.window.lock() {
Ok(window) => window.inner_size().into(),
Err(_) => (0, 0), // fallback values
};
let ctx = PlatformContext {
current_event: Event::AboutToWait,
asset_manager: self.asset_manager.clone(),
frame_width: w as f32,
frame_height: h as f32,
time_ctx: self.construct_time_ctx(),
window: self.window.clone(),
};
self.engine.initialize(ctx.clone());
let _ = &self.event_loop.run(move |event, el| {
self.rendering_system_manager
.systems
.values_mut()
.for_each(|system| system.handle_event(&mut self.window, event.clone()));
.for_each(|system| system.handle_event(self.window.clone(), event.clone()));
let mut ctx2 = ctx.clone();
ctx2.current_event = event.clone();
@ -95,7 +103,7 @@ impl<E: EngineTrait<PlatformCtx = PlatformContext>> Platform<E> for GliumPlatfor
scene: scene_mut,
target: &mut target,
asset_manager: self.asset_manager.clone(),
window: &mut self.window,
window: self.window.clone(),
debug_ui_buffer,
env_light_dir: Vec3::new(0.0, -1.0, 0.0),
};
@ -129,8 +137,8 @@ impl<E: EngineTrait<PlatformCtx = PlatformContext>> Platform<E> for GliumPlatfor
self.rendering_system_manager
.systems
.values_mut()
.for_each(|system| system.prepare_frame(&mut self.window));
self.window.request_redraw();
.for_each(|system| system.prepare_frame(self.window.clone()));
self.window.lock().unwrap().request_redraw();
}
_ => {},
}

View file

@ -1,4 +1,5 @@
use std::any::Any;
use std::sync::{Arc, Mutex};
use glium::{uniform, Display, Program, Surface};
use glium::glutin::surface::WindowSurface;
use glium::texture::{RawImage2d, SrgbTexture2d};
@ -20,7 +21,7 @@ pub struct BasicMeshRenderingSystem {
}
impl RenderingSystem for BasicMeshRenderingSystem {
fn initialize(display: &Display<WindowSurface>, _window: &glium::winit::window::Window) -> Self {
fn initialize(display: &Display<WindowSurface>, _window: Arc<Mutex<glium::winit::window::Window>>) -> Self {
const VERT_SRC: &str = include_shader!("gl_textured.vert");
const FRAG_SRC: &str = include_shader!("gl_textured.frag");

View file

@ -1,3 +1,4 @@
use std::sync::{Arc, Mutex};
use std::time::Instant;
use glium::Display;
use glium::glutin::surface::WindowSurface;
@ -19,17 +20,19 @@ pub struct ImguiBridge {
}
impl RenderingSystem for ImguiBridge {
fn handle_event(&mut self, window: &mut Window, event: Event<()>) {
self.platform.handle_event(self.imgui.io_mut(), window, &event);
fn handle_event(&mut self, window: Arc<Mutex<Window>>, event: Event<()>) {
let window = window.lock().unwrap();
self.platform.handle_event(self.imgui.io_mut(), &*window, &event);
}
fn prepare_frame(&mut self, window: &mut Window) {
fn prepare_frame(&mut self, window: Arc<Mutex<Window>>) {
self.rendered_this_frame = false;
let now = Instant::now();
self.imgui.io_mut().update_delta_time(now - self.last_frame);
self.last_frame = now;
let window = window.lock().unwrap();
self.platform
.prepare_frame(self.imgui.io_mut(), window)
.prepare_frame(self.imgui.io_mut(), &*window)
.expect("Failed to prepare frame");
}
@ -40,7 +43,10 @@ impl RenderingSystem for ImguiBridge {
let ui = self.imgui.frame();
ctx.debug_ui_buffer.borrow().write_buffer(&ui);
self.platform.prepare_render(&ui, ctx.window);
{
let window = ctx.window.lock().unwrap();
self.platform.prepare_render(&ui, &*window);
}
let draw_data = self.imgui.render();
if draw_data.total_vtx_count == 0 && draw_data.total_idx_count == 0 {
return;
@ -49,11 +55,12 @@ impl RenderingSystem for ImguiBridge {
self.renderer.render(ctx.target, draw_data).expect("imgui rendering failed");
}
fn initialize(display: &Display<WindowSurface>, window: &Window) -> Self {
fn initialize(display: &Display<WindowSurface>, window: Arc<Mutex<Window>>) -> Self {
let mut imgui = ImguiContext::create();
imgui.set_ini_filename(None);
let mut platform = WinitPlatform::new(&mut imgui);
platform.attach_window(imgui.io_mut(), window, HiDpiMode::Default);
let window = window.lock().unwrap();
platform.attach_window(imgui.io_mut(), &*window, HiDpiMode::Default);
imgui.fonts().add_font(&[imgui::FontSource::DefaultFontData { config: None }]);
let renderer = ImguiGliumRenderer::new(&mut imgui, display).unwrap();

View file

@ -1,6 +1,7 @@
use std::path::PathBuf;
use std::rc::Rc;
use std::cell::RefCell;
use std::sync::{Arc, Mutex};
use glium::{Display, Program, Surface, VertexBuffer, IndexBuffer, implement_vertex};
use glium::glutin::surface::WindowSurface;
use glium::index::PrimitiveType;
@ -108,7 +109,7 @@ impl SkyboxRenderingSystem {
}
impl RenderingSystem for SkyboxRenderingSystem {
fn initialize(display: &Display<WindowSurface>, _window: &glium::winit::window::Window) -> Self {
fn initialize(display: &Display<WindowSurface>, _window: Arc<Mutex<glium::winit::window::Window>>) -> Self {
const VERT_SRC: &str = include_shader!("skybox.vert");
const FRAG_SRC: &str = include_shader!("skybox.frag");
let program = Program::from_source(display, VERT_SRC, FRAG_SRC, None).unwrap();

View file

@ -1,6 +1,7 @@
use std::any::TypeId;
use std::cell::RefCell;
use std::rc::Rc;
use std::sync::{Arc, Mutex};
use indexmap::IndexMap;
use glium::{Display, Frame};
use glium::glutin::surface::WindowSurface;
@ -12,7 +13,7 @@ use glam::Vec3;
pub struct RenderingContext<'a> {
pub scene: &'a Scene,
pub target: &'a mut Frame,
pub window: &'a mut glium::winit::window::Window,
pub window: Arc<Mutex<glium::winit::window::Window>>,
pub asset_manager: ModelManagerRef,
pub debug_ui_buffer: Rc<RefCell<DebugUIBuffer>>,
pub env_light_dir: Vec3,
@ -23,13 +24,13 @@ pub struct RenderingContext<'a> {
pub trait RenderingSystem {
fn handle_event(
&mut self,
_window: &mut glium::winit::window::Window,
_window: Arc<Mutex<glium::winit::window::Window>>,
_event: winit::event::Event<()>,
) {
}
fn prepare_frame(&mut self, _window: &mut glium::winit::window::Window) {}
fn prepare_frame(&mut self, _window: Arc<Mutex<glium::winit::window::Window>>) {}
fn render(&mut self, ctx: &mut RenderingContext);
fn initialize(display: &Display<WindowSurface>, window: &glium::winit::window::Window) -> Self
fn initialize(display: &Display<WindowSurface>, window: Arc<Mutex<glium::winit::window::Window>>) -> Self
where
Self: Sized;
}
@ -45,7 +46,7 @@ impl RenderingSystemManager {
}
}
pub fn add<R>(&mut self, display: &Display<WindowSurface>, window: &glium::winit::window::Window)
pub fn add<R>(&mut self, display: &Display<WindowSurface>, window: Arc<Mutex<glium::winit::window::Window>>)
where
R: RenderingSystem + 'static,
{