Huge input update, FPS Camera controls system
Long day. I now store winit:🪟:Window in a mutex.
This commit is contained in:
parent
1e9b997aeb
commit
46c8c32819
15 changed files with 307 additions and 39 deletions
5
Cargo.lock
generated
5
Cargo.lock
generated
|
|
@ -523,9 +523,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "glam"
|
||||
version = "0.30.5"
|
||||
version = "0.30.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f2d1aab06663bdce00d6ca5e5ed586ec8d18033a771906c993a1e3755b368d85"
|
||||
checksum = "e12d847aeb25f41be4c0ec9587d624e9cd631bc007a8fd7ce3f5851e064c6460"
|
||||
|
||||
[[package]]
|
||||
name = "glium"
|
||||
|
|
@ -1444,6 +1444,7 @@ dependencies = [
|
|||
name = "raidillon_engine"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"glam",
|
||||
"hecs",
|
||||
"indexmap",
|
||||
"raidillon_assets",
|
||||
|
|
|
|||
|
|
@ -10,3 +10,4 @@ raidillon_platform = { path = "../platform" }
|
|||
winit = "0.30.12"
|
||||
hecs = "0.10.5"
|
||||
indexmap = "2.10.0"
|
||||
glam = "0.30.8"
|
||||
|
|
@ -5,11 +5,13 @@ use crate::system::{SystemContext, SystemManager};
|
|||
use raidillon_platform::PlatformContext;
|
||||
use raidillon_core::DebugUIBuffer;
|
||||
use raidillon_core::engine::EngineTrait;
|
||||
use crate::input::InputState;
|
||||
|
||||
pub struct Engine {
|
||||
pub scene_manager: SceneManager,
|
||||
pub system_manager: SystemManager,
|
||||
debug_ui_buffer: Rc<RefCell<DebugUIBuffer>>,
|
||||
input_state: Rc<RefCell<InputState>>,
|
||||
}
|
||||
|
||||
impl EngineTrait for Engine {
|
||||
|
|
@ -21,6 +23,7 @@ impl EngineTrait for Engine {
|
|||
scene_manager,
|
||||
system_manager,
|
||||
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(),
|
||||
platform_context,
|
||||
debug_ui_buffer: self.debug_ui_buffer.clone(),
|
||||
input_state: self.input_state.clone(),
|
||||
};
|
||||
|
||||
// Engine Loading Stage 2: load world
|
||||
|
|
@ -50,6 +54,7 @@ impl EngineTrait for Engine {
|
|||
scene: self.scene_manager.current_mut(),
|
||||
platform_context,
|
||||
debug_ui_buffer: self.debug_ui_buffer.clone(),
|
||||
input_state: self.input_state.clone(),
|
||||
};
|
||||
|
||||
for system in self.system_manager.systems.values_mut() {
|
||||
|
|
@ -62,6 +67,7 @@ impl EngineTrait for Engine {
|
|||
scene: self.scene_manager.current_mut(),
|
||||
platform_context,
|
||||
debug_ui_buffer: self.debug_ui_buffer.clone(),
|
||||
input_state: self.input_state.clone(),
|
||||
};
|
||||
|
||||
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) {
|
||||
self.input_state.borrow_mut().handle_event(&platform_context.current_event);
|
||||
|
||||
let mut ctx = SystemContext {
|
||||
scene: self.scene_manager.current_mut(),
|
||||
platform_context,
|
||||
debug_ui_buffer: self.debug_ui_buffer.clone(),
|
||||
input_state: self.input_state.clone(),
|
||||
};
|
||||
|
||||
for system in self.system_manager.systems.values_mut() {
|
||||
|
|
|
|||
69
engine/src/input.rs
Normal file
69
engine/src/input.rs
Normal 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();
|
||||
}
|
||||
}
|
||||
|
|
@ -1,4 +1,6 @@
|
|||
pub mod engine;
|
||||
pub mod system;
|
||||
mod input;
|
||||
pub mod systems;
|
||||
|
||||
pub use crate::engine::Engine;
|
||||
|
|
|
|||
|
|
@ -5,12 +5,13 @@ use raidillon_platform::PlatformContext;
|
|||
use std::any::TypeId;
|
||||
use std::cell::RefCell;
|
||||
use std::rc::Rc;
|
||||
use crate::input::InputState;
|
||||
|
||||
pub struct SystemContext<'a> {
|
||||
// TODO: time delta etc.
|
||||
pub scene: &'a mut Scene,
|
||||
pub platform_context: PlatformContext,
|
||||
pub debug_ui_buffer: Rc<RefCell<DebugUIBuffer>>,
|
||||
pub input_state: Rc<RefCell<InputState>>,
|
||||
}
|
||||
|
||||
pub trait System {
|
||||
|
|
|
|||
114
engine/src/systems/fps_camera.rs
Normal file
114
engine/src/systems/fps_camera.rs
Normal 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()
|
||||
}
|
||||
}
|
||||
1
engine/src/systems/mod.rs
Normal file
1
engine/src/systems/mod.rs
Normal file
|
|
@ -0,0 +1 @@
|
|||
pub mod fps_camera;
|
||||
|
|
@ -10,12 +10,56 @@ use raidillon_ecs::Transform;
|
|||
use raidillon_core::scene::Scene;
|
||||
#[cfg(feature = "glium")]
|
||||
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 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)]
|
||||
struct UpdateAspectRatioSystem;
|
||||
impl System for UpdateAspectRatioSystem {
|
||||
|
|
@ -42,16 +86,6 @@ impl System for RenderingTestSystem {
|
|||
fn load_world(&mut self, ctx: &mut SystemContext) {
|
||||
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();
|
||||
|
||||
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!("Fixed Delta: {}", ctx.platform_context.time_ctx.fixed_dt));
|
||||
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) {
|
||||
|
|
@ -85,8 +133,10 @@ impl System for RenderingTestSystem {
|
|||
fn main() {
|
||||
let mut engine = Engine::new();
|
||||
// Define systems
|
||||
engine.system_manager.add::<FPSCameraSystem>();
|
||||
engine.system_manager.add::<RenderingTestSystem>();
|
||||
engine.system_manager.add::<UpdateAspectRatioSystem>();
|
||||
// engine.system_manager.add::<InputTestSystem>();
|
||||
|
||||
// Set up the scene
|
||||
let main_scene = Scene::new(
|
||||
|
|
@ -102,7 +152,7 @@ fn main() {
|
|||
engine,
|
||||
"Raidillon".to_string(),
|
||||
2560,
|
||||
1440,
|
||||
1080,
|
||||
);
|
||||
platform.run()
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
_ => {},
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
use std::sync::{Arc, Mutex};
|
||||
use winit::event::Event;
|
||||
use raidillon_assets::ModelManagerRef;
|
||||
|
||||
|
|
@ -8,6 +9,7 @@ pub struct PlatformContext {
|
|||
pub frame_width: f32,
|
||||
pub frame_height: f32,
|
||||
pub time_ctx: TimeContext,
|
||||
pub window: Arc<Mutex<winit::window::Window>>,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue