Add debug wireframe rendering support

This commit is contained in:
reo 2025-12-15 15:53:54 +03:00
parent 8041c7e01d
commit 73692b710e
12 changed files with 221 additions and 7 deletions

View file

@ -1,7 +1,7 @@
use std::cell::{RefCell, Cell};
use std::rc::Rc;
use std::sync::{Arc, Mutex, RwLock};
use raidillon_platform::{Platform, PlatformContext, TimeContext};
use raidillon_platform::{Platform, PlatformContext, TimeContext, DebugWireframes, DebugWireframesRef};
use glium::backend::glutin::Display;
use glium::backend::glutin::SimpleWindowBuilder;
use glium::glutin::surface::WindowSurface;
@ -14,7 +14,7 @@ use raidillon_assets::ModelManagerRef;
use raidillon_core::engine::EngineTrait;
use raidillon_core::time;
use raidillon_core::time::Time;
use crate::render::{BasicMeshRenderingSystem, EguiRenderer, SkyboxRenderingSystem};
use crate::render::{BasicMeshRenderingSystem, DebugWireframeRenderingSystem, EguiRenderer, SkyboxRenderingSystem};
use crate::GliumAssetManager;
use glam::Vec3;
use winit::event::DeviceEvent::MouseMotion;
@ -31,7 +31,7 @@ pub struct GliumPlatform<E: EngineTrait<PlatformCtx = PlatformContext>> {
time: time::Time,
egui_queue: Rc<RefCell<EguiQueue>>,
settings: Arc<RwLock<Settings>>,
/// Used for [`raidillon_platform::context::PlatformContext::should_egui_receive_input_events`]
debug_wireframes: DebugWireframesRef,
should_egui_receive_input_events: Rc<Cell<bool>>,
}
@ -57,6 +57,7 @@ impl<E: EngineTrait<PlatformCtx = PlatformContext>> Platform<E> for GliumPlatfor
// Install rendering systems in order
rendering_system_manager.add::<SkyboxRenderingSystem>(&display, window.clone(), &event_loop);
rendering_system_manager.add::<BasicMeshRenderingSystem>(&display, window.clone(), &event_loop);
rendering_system_manager.add::<DebugWireframeRenderingSystem>(&display, window.clone(), &event_loop);
rendering_system_manager.add::<EguiRenderer>(&display, window.clone(), &event_loop);
let egui_queue = Rc::new(RefCell::new(EguiQueue::new()));
@ -66,6 +67,7 @@ impl<E: EngineTrait<PlatformCtx = PlatformContext>> Platform<E> for GliumPlatfor
Settings::load_or_default(default_config_path()).unwrap()
)
);
let debug_wireframes = Rc::new(RefCell::new(DebugWireframes::new()));
let should_egui_receive_input_events = Rc::new(Cell::new(false));
Self {
@ -78,6 +80,7 @@ impl<E: EngineTrait<PlatformCtx = PlatformContext>> Platform<E> for GliumPlatfor
time,
egui_queue,
settings,
debug_wireframes,
should_egui_receive_input_events,
}
}
@ -96,6 +99,7 @@ impl<E: EngineTrait<PlatformCtx = PlatformContext>> Platform<E> for GliumPlatfor
window: self.window.clone(),
egui_queue: self.egui_queue.clone(),
settings: self.settings.clone(),
debug_wireframes: self.debug_wireframes.clone(),
should_egui_receive_input_events: self.should_egui_receive_input_events.clone(),
};
self.engine.initialize(ctx.clone());
@ -140,6 +144,7 @@ impl<E: EngineTrait<PlatformCtx = PlatformContext>> Platform<E> for GliumPlatfor
asset_manager: self.asset_manager.clone(),
window: self.window.clone(),
egui_queue: self.egui_queue.clone(),
debug_wireframes: self.debug_wireframes.clone(),
env_light_dir: Vec3::new(0.0, -1.0, 0.0),
should_egui_receive_input_events: self.should_egui_receive_input_events.clone(),
};
@ -149,6 +154,9 @@ impl<E: EngineTrait<PlatformCtx = PlatformContext>> Platform<E> for GliumPlatfor
.values_mut()
.for_each(|system| system.render(&mut context));
// clear debug wireframes after rendering
self.debug_wireframes.borrow_mut().clear();
target.finish().unwrap();
}
_ => {},

View file

@ -0,0 +1,80 @@
use std::sync::{Arc, Mutex};
use glium::{Display, Program, Surface, VertexBuffer, implement_vertex};
use glium::glutin::surface::WindowSurface;
use glium::index::PrimitiveType;
use glium::uniform;
use winit::event_loop::EventLoop;
use raidillon_assets::include_shader;
use crate::system::RenderingContext;
use crate::RenderingSystem;
pub use raidillon_platform::Camera;
#[derive(Copy, Clone)]
struct DebugVertex {
position: [f32; 3],
color: [f32; 4],
}
implement_vertex!(DebugVertex, position, color);
/// renders debug wireframes from the shared buffer
pub struct DebugWireframeRenderingSystem {
program: Program,
params: glium::DrawParameters<'static>,
}
impl RenderingSystem for DebugWireframeRenderingSystem {
fn initialize(display: &Display<WindowSurface>, _window: Arc<Mutex<glium::winit::window::Window>>, _event_loop: &EventLoop<()>) -> Self {
const VERT_SRC: &str = include_shader!("debug_wireframe.vert");
const FRAG_SRC: &str = include_shader!("debug_wireframe.frag");
let program = Program::from_source(display, VERT_SRC, FRAG_SRC, None).unwrap();
let params = glium::DrawParameters {
depth: glium::Depth {
test: glium::draw_parameters::DepthTest::IfLess,
write: false,
..Default::default()
},
line_width: Some(1.0),
..Default::default()
};
Self { program, params }
}
fn render(&mut self, ctx: &mut RenderingContext) {
let debug_wireframes = ctx.debug_wireframes.borrow();
if !debug_wireframes.enabled || debug_wireframes.vertices.is_empty() {
return;
}
let cam = match ctx.scene.world.query::<&Camera>().iter().next() {
Some((_, cam)) => *cam,
None => return,
};
let vertices: Vec<DebugVertex> = debug_wireframes.vertices.iter()
.map(|v| DebugVertex { position: v.position, color: v.color })
.collect();
let vbuf = match VertexBuffer::new(ctx.display, &vertices) {
Ok(vb) => vb,
Err(_) => return,
};
let uniforms = uniform! {
view: cam.view().to_cols_array_2d(),
projection: cam.projection().to_cols_array_2d(),
};
ctx.target.draw(
&vbuf,
glium::index::NoIndices(PrimitiveType::LinesList),
&self.program,
&uniforms,
&self.params,
).ok();
}
}

View file

@ -1,7 +1,9 @@
mod basic;
mod skybox;
mod egui;
mod debug_wireframe;
pub use basic::BasicMeshRenderingSystem;
pub use skybox::SkyboxRenderingSystem;
pub use egui::EguiRenderer;
pub use debug_wireframe::DebugWireframeRenderingSystem;

View file

@ -8,6 +8,7 @@ use glium::glutin::surface::WindowSurface;
use raidillon_assets::ModelManagerRef;
use raidillon_core::{define_typemap, EguiQueue};
use raidillon_core::scene::Scene;
use raidillon_platform::DebugWireframesRef;
use glam::Vec3;
use winit::event_loop::EventLoop;
use std::cell::Cell;
@ -19,6 +20,7 @@ pub struct RenderingContext<'a> {
pub display: &'a Display<WindowSurface>,
pub asset_manager: ModelManagerRef,
pub egui_queue: Rc<RefCell<EguiQueue>>,
pub debug_wireframes: DebugWireframesRef,
pub env_light_dir: Vec3,
pub should_egui_receive_input_events: Rc<Cell<bool>>
}