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

5
Cargo.lock generated
View file

@ -523,9 +523,9 @@ dependencies = [
[[package]] [[package]]
name = "glam" name = "glam"
version = "0.30.5" version = "0.30.8"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f2d1aab06663bdce00d6ca5e5ed586ec8d18033a771906c993a1e3755b368d85" checksum = "e12d847aeb25f41be4c0ec9587d624e9cd631bc007a8fd7ce3f5851e064c6460"
[[package]] [[package]]
name = "glium" name = "glium"
@ -1444,6 +1444,7 @@ dependencies = [
name = "raidillon_engine" name = "raidillon_engine"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"glam",
"hecs", "hecs",
"indexmap", "indexmap",
"raidillon_assets", "raidillon_assets",

View file

@ -10,3 +10,4 @@ raidillon_platform = { path = "../platform" }
winit = "0.30.12" winit = "0.30.12"
hecs = "0.10.5" hecs = "0.10.5"
indexmap = "2.10.0" indexmap = "2.10.0"
glam = "0.30.8"

View file

@ -5,11 +5,13 @@ use crate::system::{SystemContext, SystemManager};
use raidillon_platform::PlatformContext; use raidillon_platform::PlatformContext;
use raidillon_core::DebugUIBuffer; use raidillon_core::DebugUIBuffer;
use raidillon_core::engine::EngineTrait; use raidillon_core::engine::EngineTrait;
use crate::input::InputState;
pub struct Engine { pub struct Engine {
pub scene_manager: SceneManager, pub scene_manager: SceneManager,
pub system_manager: SystemManager, pub system_manager: SystemManager,
debug_ui_buffer: Rc<RefCell<DebugUIBuffer>>, debug_ui_buffer: Rc<RefCell<DebugUIBuffer>>,
input_state: Rc<RefCell<InputState>>,
} }
impl EngineTrait for Engine { impl EngineTrait for Engine {
@ -21,6 +23,7 @@ impl EngineTrait for Engine {
scene_manager, scene_manager,
system_manager, system_manager,
debug_ui_buffer: Rc::new(RefCell::new(DebugUIBuffer::new())), debug_ui_buffer: Rc::new(RefCell::new(DebugUIBuffer::new())),
input_state: Default::default(),
} }
} }
@ -35,6 +38,7 @@ impl EngineTrait for Engine {
scene: self.scene_manager.current_mut(), scene: self.scene_manager.current_mut(),
platform_context, platform_context,
debug_ui_buffer: self.debug_ui_buffer.clone(), debug_ui_buffer: self.debug_ui_buffer.clone(),
input_state: self.input_state.clone(),
}; };
// Engine Loading Stage 2: load world // Engine Loading Stage 2: load world
@ -50,6 +54,7 @@ impl EngineTrait for Engine {
scene: self.scene_manager.current_mut(), scene: self.scene_manager.current_mut(),
platform_context, platform_context,
debug_ui_buffer: self.debug_ui_buffer.clone(), debug_ui_buffer: self.debug_ui_buffer.clone(),
input_state: self.input_state.clone(),
}; };
for system in self.system_manager.systems.values_mut() { for system in self.system_manager.systems.values_mut() {
@ -62,6 +67,7 @@ impl EngineTrait for Engine {
scene: self.scene_manager.current_mut(), scene: self.scene_manager.current_mut(),
platform_context, platform_context,
debug_ui_buffer: self.debug_ui_buffer.clone(), debug_ui_buffer: self.debug_ui_buffer.clone(),
input_state: self.input_state.clone(),
}; };
for system in self.system_manager.systems.values_mut() { for system in self.system_manager.systems.values_mut() {
@ -70,10 +76,13 @@ impl EngineTrait for Engine {
} }
fn handle_event(&mut self, platform_context: PlatformContext) { fn handle_event(&mut self, platform_context: PlatformContext) {
self.input_state.borrow_mut().handle_event(&platform_context.current_event);
let mut ctx = SystemContext { let mut ctx = SystemContext {
scene: self.scene_manager.current_mut(), scene: self.scene_manager.current_mut(),
platform_context, platform_context,
debug_ui_buffer: self.debug_ui_buffer.clone(), debug_ui_buffer: self.debug_ui_buffer.clone(),
input_state: self.input_state.clone(),
}; };
for system in self.system_manager.systems.values_mut() { for system in self.system_manager.systems.values_mut() {

69
engine/src/input.rs Normal file
View file

@ -0,0 +1,69 @@
use std::collections::HashSet;
use winit::event::{ElementState, Event, MouseButton, WindowEvent};
use winit::keyboard::{KeyCode, PhysicalKey};
/// A utility to help with buffering input.
/// Meant to be plugged into systems.
#[derive(Default, Clone, Debug)]
pub struct InputState {
held_keys: HashSet<KeyCode>,
held_mouse: HashSet<MouseButton>,
}
impl InputState {
fn new() -> Self {
Default::default()
}
pub fn handle_event(&mut self, event: &Event<()>) {
if let Event::WindowEvent { event, .. } = event {
match event {
// Keyboard
WindowEvent::KeyboardInput { event: key_event, .. } => {
if let PhysicalKey::Code(code) = key_event.physical_key {
match key_event.state {
ElementState::Pressed => {
self.held_keys.insert(code);
}
ElementState::Released => {
self.held_keys.remove(&code);
}
}
}
}
// Mouse
WindowEvent::MouseInput { state, button, .. } => {
match state {
ElementState::Pressed => {
self.held_mouse.insert(*button);
}
ElementState::Released => {
self.held_mouse.remove(button);
}
}
}
WindowEvent::Focused(focused) => {
if !*focused {
self.clear();
}
}
_ => {}
}
}
}
pub fn key_held(&self, code: KeyCode) -> bool {
self.held_keys.contains(&code)
}
pub fn mouse_held(&self, button: MouseButton) -> bool {
self.held_mouse.contains(&button)
}
pub fn clear(&mut self) {
self.held_keys.clear();
self.held_mouse.clear();
}
}

View file

@ -1,4 +1,6 @@
pub mod engine; pub mod engine;
pub mod system; pub mod system;
mod input;
pub mod systems;
pub use crate::engine::Engine; pub use crate::engine::Engine;

View file

@ -5,12 +5,13 @@ use raidillon_platform::PlatformContext;
use std::any::TypeId; use std::any::TypeId;
use std::cell::RefCell; use std::cell::RefCell;
use std::rc::Rc; use std::rc::Rc;
use crate::input::InputState;
pub struct SystemContext<'a> { pub struct SystemContext<'a> {
// TODO: time delta etc.
pub scene: &'a mut Scene, pub scene: &'a mut Scene,
pub platform_context: PlatformContext, pub platform_context: PlatformContext,
pub debug_ui_buffer: Rc<RefCell<DebugUIBuffer>>, pub debug_ui_buffer: Rc<RefCell<DebugUIBuffer>>,
pub input_state: Rc<RefCell<InputState>>,
} }
pub trait System { pub trait System {

View file

@ -0,0 +1,114 @@
use crate::system::{System, SystemContext};
use glam::{Quat, Vec3};
use winit::event::DeviceEvent::MouseMotion;
use winit::event::{ElementState, Event, MouseButton, WindowEvent};
use winit::keyboard::PhysicalKey;
use winit::window::CursorGrabMode;
use raidillon_assets::model_path;
use raidillon_platform::Camera;
pub struct FPSCameraSystem {
mouse_delta: (f64, f64),
mouse_enabled: bool,
position: Vec3,
yaw: f32,
pitch: f32,
speed: f32,
sensitivity: f32,
}
impl Default for FPSCameraSystem {
fn default() -> Self {
Self {
mouse_delta: Default::default(),
mouse_enabled: Default::default(),
position: Vec3::new(0.0, 0.0, 2.0),
yaw: -90.0,
pitch: 0.0,
speed: 3.0,
sensitivity: 0.1,
}
}
}
impl System for FPSCameraSystem {
fn load_world(&mut self, ctx: &mut SystemContext) {
ctx.scene.world.spawn((Camera {
eye: Vec3::new(0.0, 0.0, 2.0),
center: Vec3::ZERO,
up: Vec3::Y,
fovy: 60_f32.to_radians(),
aspect: ctx.platform_context.frame_width / ctx.platform_context.frame_height,
znear: 0.1,
zfar: 100.0,
},));
}
fn handle_event(&mut self, ctx: &mut SystemContext) {
let event2 = ctx.platform_context.current_event.clone();
match event2 {
Event::DeviceEvent { device_id, event} => {
match event {
MouseMotion { delta } => {
self.mouse_delta.0 += delta.0;
self.mouse_delta.1 += delta.1;
},
_ => {}
}
},
Event::WindowEvent { event, .. } => match event {
WindowEvent::MouseInput { state, button, .. } => {
if button == MouseButton::Right {
// blood and tear
let window = ctx.platform_context.window.lock().unwrap();
match state {
ElementState::Pressed => {
if window
.set_cursor_grab(CursorGrabMode::Confined)
.or_else(|_| window.set_cursor_grab(CursorGrabMode::Locked))
.is_ok()
{
window.set_cursor_visible(false);
self.mouse_enabled = true;
}
}
ElementState::Released => {
let _ = window.set_cursor_grab(CursorGrabMode::None);
window.set_cursor_visible(true);
self.mouse_enabled = false;
}
}
}
}
_ => {},
},
_ => {},
}
}
fn frame_update(&mut self, ctx: &mut SystemContext) {
if self.mouse_enabled {
self.yaw += self.mouse_delta.0 as f32 * self.sensitivity;
self.pitch -= self.mouse_delta.1 as f32 * self.sensitivity;
self.pitch = self.pitch.clamp(-89.0, 89.0);
}
ctx.scene.world.query_mut::<&mut Camera>().into_iter().for_each(|(_, camera)| {
camera.eye = self.position;
camera.center = self.position + self.front();
});
self.mouse_delta = (0.0, 0.0);
}
}
impl FPSCameraSystem {
pub fn front(&self) -> Vec3 {
let yaw_rad = self.yaw.to_radians();
let pitch_rad = self.pitch.to_radians();
Vec3::new(
yaw_rad.cos() * pitch_rad.cos(),
pitch_rad.sin(),
yaw_rad.sin() * pitch_rad.cos(),
).normalize()
}
}

View file

@ -0,0 +1 @@
pub mod fps_camera;

View file

@ -10,12 +10,56 @@ use raidillon_ecs::Transform;
use raidillon_core::scene::Scene; use raidillon_core::scene::Scene;
#[cfg(feature = "glium")] #[cfg(feature = "glium")]
use raidillon_glium::GliumPlatform; use raidillon_glium::GliumPlatform;
use winit::event::{Event, WindowEvent}; use winit::event::{ElementState, Event, WindowEvent};
use winit::event::DeviceEvent::MouseMotion;
use winit::keyboard::{KeyCode, PhysicalKey};
use raidillon_engine::systems::fps_camera::FPSCameraSystem;
const TEST_GLTF: &str = "pink-monkey.gltf"; const TEST_GLTF: &str = "pink-monkey.gltf";
const MAIN_SCENE_ID: &str = "main_scene"; const MAIN_SCENE_ID: &str = "main_scene";
#[derive(Default)]
struct InputTestSystem {
mouse_delta: (f64, f64),
}
impl System for InputTestSystem {
fn handle_event(&mut self, ctx: &mut SystemContext) {
let event2 = ctx.platform_context.current_event.clone();
match event2 {
Event::DeviceEvent { device_id, event} => {
match event {
MouseMotion { delta } => {
self.mouse_delta.0 += delta.0;
self.mouse_delta.1 += delta.1;
println!("UPDATED mouse delta: ({},{})", self.mouse_delta.0, self.mouse_delta.1);
},
_ => {}
}
},
Event::WindowEvent { event, .. } => match event {
WindowEvent::KeyboardInput { device_id, event, is_synthetic} => {
let PhysicalKey::Code(key_code) = event.physical_key else {
return;
};
match event.state {
ElementState::Pressed => {
println!("Pressed Key: {:?}", key_code);
}
ElementState::Released => {
println!("Released Key: {:?}", key_code);
}
}
}
_ => {},
}
_ => {},
}
}
}
#[derive(Default)] #[derive(Default)]
struct UpdateAspectRatioSystem; struct UpdateAspectRatioSystem;
impl System for UpdateAspectRatioSystem { impl System for UpdateAspectRatioSystem {
@ -42,16 +86,6 @@ impl System for RenderingTestSystem {
fn load_world(&mut self, ctx: &mut SystemContext) { fn load_world(&mut self, ctx: &mut SystemContext) {
self.rotation_speed = std::rc::Rc::new(std::cell::RefCell::new(5.0)); self.rotation_speed = std::rc::Rc::new(std::cell::RefCell::new(5.0));
ctx.scene.world.spawn((Camera {
eye: Vec3::new(0.0, 0.0, 2.0),
center: Vec3::ZERO,
up: Vec3::Y,
fovy: 60_f32.to_radians(),
aspect: ctx.platform_context.frame_width / ctx.platform_context.frame_height,
znear: 0.1,
zfar: 100.0,
},));
let mut am = ctx.platform_context.asset_manager.borrow_mut(); let mut am = ctx.platform_context.asset_manager.borrow_mut();
am.load_gltf(TEST_GLTF, &model_path(TEST_GLTF)); am.load_gltf(TEST_GLTF, &model_path(TEST_GLTF));
@ -72,6 +106,20 @@ impl System for RenderingTestSystem {
dbg_ui.text(format!("Frame Delta: {}", ctx.platform_context.time_ctx.frame_dt)); dbg_ui.text(format!("Frame Delta: {}", ctx.platform_context.time_ctx.frame_dt));
dbg_ui.text(format!("Fixed Delta: {}", ctx.platform_context.time_ctx.fixed_dt)); dbg_ui.text(format!("Fixed Delta: {}", ctx.platform_context.time_ctx.fixed_dt));
dbg_ui.slider_f32("Rotation Speed", -10.0, 10.0, self.rotation_speed.clone()); dbg_ui.slider_f32("Rotation Speed", -10.0, 10.0, self.rotation_speed.clone());
let input = ctx.input_state.borrow();
if input.key_held(KeyCode::KeyW) {
dbg_ui.text("W".to_owned());
}
if input.key_held(KeyCode::KeyA) {
dbg_ui.text("A".to_owned());
}
if input.key_held(KeyCode::KeyS) {
dbg_ui.text("S".to_owned());
}
if input.key_held(KeyCode::KeyD) {
dbg_ui.text("D".to_owned());
}
} }
fn fixed_update(&mut self, ctx: &mut SystemContext) { fn fixed_update(&mut self, ctx: &mut SystemContext) {
@ -85,8 +133,10 @@ impl System for RenderingTestSystem {
fn main() { fn main() {
let mut engine = Engine::new(); let mut engine = Engine::new();
// Define systems // Define systems
engine.system_manager.add::<FPSCameraSystem>();
engine.system_manager.add::<RenderingTestSystem>(); engine.system_manager.add::<RenderingTestSystem>();
engine.system_manager.add::<UpdateAspectRatioSystem>(); engine.system_manager.add::<UpdateAspectRatioSystem>();
// engine.system_manager.add::<InputTestSystem>();
// Set up the scene // Set up the scene
let main_scene = Scene::new( let main_scene = Scene::new(
@ -102,7 +152,7 @@ fn main() {
engine, engine,
"Raidillon".to_string(), "Raidillon".to_string(),
2560, 2560,
1440, 1080,
); );
platform.run() platform.run()
}; };

View file

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

View file

@ -1,4 +1,5 @@
use std::any::Any; use std::any::Any;
use std::sync::{Arc, Mutex};
use glium::{uniform, Display, Program, Surface}; use glium::{uniform, Display, Program, Surface};
use glium::glutin::surface::WindowSurface; use glium::glutin::surface::WindowSurface;
use glium::texture::{RawImage2d, SrgbTexture2d}; use glium::texture::{RawImage2d, SrgbTexture2d};
@ -20,7 +21,7 @@ pub struct BasicMeshRenderingSystem {
} }
impl RenderingSystem for 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 VERT_SRC: &str = include_shader!("gl_textured.vert");
const FRAG_SRC: &str = include_shader!("gl_textured.frag"); 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 std::time::Instant;
use glium::Display; use glium::Display;
use glium::glutin::surface::WindowSurface; use glium::glutin::surface::WindowSurface;
@ -19,17 +20,19 @@ pub struct ImguiBridge {
} }
impl RenderingSystem for ImguiBridge { impl RenderingSystem for ImguiBridge {
fn handle_event(&mut self, window: &mut Window, event: Event<()>) { fn handle_event(&mut self, window: Arc<Mutex<Window>>, event: Event<()>) {
self.platform.handle_event(self.imgui.io_mut(), window, &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; self.rendered_this_frame = false;
let now = Instant::now(); let now = Instant::now();
self.imgui.io_mut().update_delta_time(now - self.last_frame); self.imgui.io_mut().update_delta_time(now - self.last_frame);
self.last_frame = now; self.last_frame = now;
let window = window.lock().unwrap();
self.platform self.platform
.prepare_frame(self.imgui.io_mut(), window) .prepare_frame(self.imgui.io_mut(), &*window)
.expect("Failed to prepare frame"); .expect("Failed to prepare frame");
} }
@ -40,7 +43,10 @@ impl RenderingSystem for ImguiBridge {
let ui = self.imgui.frame(); let ui = self.imgui.frame();
ctx.debug_ui_buffer.borrow().write_buffer(&ui); 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(); let draw_data = self.imgui.render();
if draw_data.total_vtx_count == 0 && draw_data.total_idx_count == 0 { if draw_data.total_vtx_count == 0 && draw_data.total_idx_count == 0 {
return; return;
@ -49,11 +55,12 @@ impl RenderingSystem for ImguiBridge {
self.renderer.render(ctx.target, draw_data).expect("imgui rendering failed"); 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(); let mut imgui = ImguiContext::create();
imgui.set_ini_filename(None); imgui.set_ini_filename(None);
let mut platform = WinitPlatform::new(&mut imgui); 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 }]); imgui.fonts().add_font(&[imgui::FontSource::DefaultFontData { config: None }]);
let renderer = ImguiGliumRenderer::new(&mut imgui, display).unwrap(); let renderer = ImguiGliumRenderer::new(&mut imgui, display).unwrap();

View file

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

View file

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

View file

@ -1,3 +1,4 @@
use std::sync::{Arc, Mutex};
use winit::event::Event; use winit::event::Event;
use raidillon_assets::ModelManagerRef; use raidillon_assets::ModelManagerRef;
@ -8,6 +9,7 @@ pub struct PlatformContext {
pub frame_width: f32, pub frame_width: f32,
pub frame_height: f32, pub frame_height: f32,
pub time_ctx: TimeContext, pub time_ctx: TimeContext,
pub window: Arc<Mutex<winit::window::Window>>,
} }
#[derive(Clone)] #[derive(Clone)]