Add debug wireframe rendering support
This commit is contained in:
parent
8041c7e01d
commit
73692b710e
12 changed files with 221 additions and 7 deletions
|
|
@ -11,6 +11,9 @@ pub use raidillon_platform::{
|
|||
Camera,
|
||||
PlatformContext,
|
||||
TimeContext,
|
||||
DebugWireframes,
|
||||
DebugWireframesRef,
|
||||
DebugWireframeVertex,
|
||||
settings::{Settings, WindowMode},
|
||||
};
|
||||
|
||||
|
|
|
|||
9
assets/shaders/debug_wireframe.frag
Normal file
9
assets/shaders/debug_wireframe.frag
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
#version 330 core
|
||||
|
||||
in vec4 v_color;
|
||||
|
||||
out vec4 frag_color;
|
||||
|
||||
void main() {
|
||||
frag_color = v_color;
|
||||
}
|
||||
14
assets/shaders/debug_wireframe.vert
Normal file
14
assets/shaders/debug_wireframe.vert
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
#version 330 core
|
||||
|
||||
in vec3 position;
|
||||
in vec4 color;
|
||||
|
||||
uniform mat4 view;
|
||||
uniform mat4 projection;
|
||||
|
||||
out vec4 v_color;
|
||||
|
||||
void main() {
|
||||
v_color = color;
|
||||
gl_Position = projection * view * vec4(position, 1.0);
|
||||
}
|
||||
|
|
@ -8,7 +8,8 @@ use winit::event::{Event, WindowEvent};
|
|||
use systems::debug_camera::FPSDebugCameraSystem;
|
||||
use crate::systems::common::should_draw_menu;
|
||||
use crate::systems::{
|
||||
DisplaySettings, KeybindsSystem, KinematicCharacterController, MenuSystem, PhysicsSystem
|
||||
DisplaySettings, KeybindsSystem, KinematicCharacterController, MenuSystem, PhysicsSystem,
|
||||
PhysicsDebugSystem,
|
||||
};
|
||||
|
||||
const TEST_GLTF: &str = "sphere.glb";
|
||||
|
|
@ -125,6 +126,7 @@ impl System for MainSystem {
|
|||
fn main() {
|
||||
raidillon_app::App::new()
|
||||
.add_system::<PhysicsSystem>()
|
||||
.add_system::<PhysicsDebugSystem>()
|
||||
.add_system::<KeybindsSystem>()
|
||||
.add_system::<KinematicCharacterController>()
|
||||
.add_system::<FPSDebugCameraSystem>()
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
mod physics;
|
||||
mod physics_debug;
|
||||
mod kinematic_character_controller;
|
||||
mod keybinds;
|
||||
mod menu;
|
||||
|
|
@ -7,6 +8,7 @@ pub mod common;
|
|||
mod display_settings;
|
||||
|
||||
pub use physics::PhysicsSystem;
|
||||
pub use physics_debug::PhysicsDebugSystem;
|
||||
pub use kinematic_character_controller::KinematicCharacterController;
|
||||
pub use keybinds::KeybindsSystem;
|
||||
pub use menu::MenuSystem;
|
||||
|
|
|
|||
35
game/src/systems/physics_debug.rs
Normal file
35
game/src/systems/physics_debug.rs
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
use raidillon_app::prelude::*;
|
||||
|
||||
/// renders aabb wireframes for all physics colliders
|
||||
#[derive(Default)]
|
||||
pub struct PhysicsDebugSystem;
|
||||
|
||||
impl System for PhysicsDebugSystem {
|
||||
fn frame_update(&mut self, res: &mut EngineResources, scene: &mut Scene) {
|
||||
let pctx = res.get::<PlatformContext>().expect("PlatformContext missing").clone();
|
||||
|
||||
let mut debug_wireframes = pctx.debug_wireframes.borrow_mut();
|
||||
if !debug_wireframes.enabled {
|
||||
return;
|
||||
}
|
||||
|
||||
let physics = match scene.resources.get::<Physics>() {
|
||||
Some(p) => p,
|
||||
None => return,
|
||||
};
|
||||
|
||||
let color = [1.0, 0.0, 0.0, 1.0];
|
||||
|
||||
for (_, collider) in physics.collider_set.iter() {
|
||||
let aabb = collider.compute_aabb();
|
||||
let min = aabb.mins;
|
||||
let max = aabb.maxs;
|
||||
|
||||
debug_wireframes.add_box(
|
||||
[min.x, min.y, min.z],
|
||||
[max.x, max.y, max.z],
|
||||
color,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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();
|
||||
}
|
||||
_ => {},
|
||||
|
|
|
|||
80
glium_platform/src/render/debug_wireframe.rs
Normal file
80
glium_platform/src/render/debug_wireframe.rs
Normal 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();
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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>>
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,6 +6,62 @@ use raidillon_assets::ModelManagerRef;
|
|||
use raidillon_core::EguiQueue;
|
||||
use crate::settings::Settings;
|
||||
|
||||
/// a single debug wireframe vertex with position and color
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct DebugWireframeVertex {
|
||||
pub position: [f32; 3],
|
||||
pub color: [f32; 4],
|
||||
}
|
||||
|
||||
/// shared buffer for debug wireframe rendering
|
||||
#[derive(Clone, Default)]
|
||||
pub struct DebugWireframes {
|
||||
pub vertices: Vec<DebugWireframeVertex>,
|
||||
pub enabled: bool,
|
||||
}
|
||||
|
||||
impl DebugWireframes {
|
||||
pub fn new() -> Self {
|
||||
Self { vertices: Vec::new(), enabled: true }
|
||||
}
|
||||
|
||||
pub fn clear(&mut self) {
|
||||
self.vertices.clear();
|
||||
}
|
||||
|
||||
/// add a single line segment
|
||||
pub fn add_line(&mut self, start: [f32; 3], end: [f32; 3], color: [f32; 4]) {
|
||||
self.vertices.push(DebugWireframeVertex { position: start, color });
|
||||
self.vertices.push(DebugWireframeVertex { position: end, color });
|
||||
}
|
||||
|
||||
/// add a wireframe box from min/max corners
|
||||
pub fn add_box(&mut self, min: [f32; 3], max: [f32; 3], color: [f32; 4]) {
|
||||
let [x0, y0, z0] = min;
|
||||
let [x1, y1, z1] = max;
|
||||
|
||||
// bottom face edges
|
||||
self.add_line([x0, y0, z0], [x1, y0, z0], color);
|
||||
self.add_line([x1, y0, z0], [x1, y0, z1], color);
|
||||
self.add_line([x1, y0, z1], [x0, y0, z1], color);
|
||||
self.add_line([x0, y0, z1], [x0, y0, z0], color);
|
||||
|
||||
// top face edges
|
||||
self.add_line([x0, y1, z0], [x1, y1, z0], color);
|
||||
self.add_line([x1, y1, z0], [x1, y1, z1], color);
|
||||
self.add_line([x1, y1, z1], [x0, y1, z1], color);
|
||||
self.add_line([x0, y1, z1], [x0, y1, z0], color);
|
||||
|
||||
// vertical edges
|
||||
self.add_line([x0, y0, z0], [x0, y1, z0], color);
|
||||
self.add_line([x1, y0, z0], [x1, y1, z0], color);
|
||||
self.add_line([x1, y0, z1], [x1, y1, z1], color);
|
||||
self.add_line([x0, y0, z1], [x0, y1, z1], color);
|
||||
}
|
||||
}
|
||||
|
||||
pub type DebugWireframesRef = Rc<RefCell<DebugWireframes>>;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct PlatformContext {
|
||||
pub current_event: Event<()>,
|
||||
|
|
@ -16,8 +72,9 @@ pub struct PlatformContext {
|
|||
pub window: Arc<Mutex<winit::window::Window>>,
|
||||
pub egui_queue: Rc<RefCell<EguiQueue>>,
|
||||
pub settings: Arc<RwLock<Settings>>,
|
||||
/// Sets whether or not egui will receive input events.
|
||||
/// Added to prevent the mouse state conflict between the engine and egui.
|
||||
/// shared debug wireframe buffer
|
||||
pub debug_wireframes: DebugWireframesRef,
|
||||
/// sets whether or not egui will receive input events
|
||||
pub should_egui_receive_input_events: Rc<Cell<bool>>,
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -6,4 +6,4 @@ pub mod settings;
|
|||
|
||||
pub use platform::Platform;
|
||||
pub use camera::Camera;
|
||||
pub use context::{PlatformContext, TimeContext};
|
||||
pub use context::{PlatformContext, TimeContext, DebugWireframes, DebugWireframesRef, DebugWireframeVertex};
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue