From 7d578207c76a9fd51c370cd06839410675f28e03 Mon Sep 17 00:00:00 2001 From: HampusM Date: Sat, 18 Apr 2026 15:50:04 +0200 Subject: feat(engine): add renderer draw properties --- engine/src/renderer.rs | 81 +++++++++++++++++++++++++++++++++++++++---- engine/src/renderer/opengl.rs | 22 ++++++++---- 2 files changed, 90 insertions(+), 13 deletions(-) diff --git a/engine/src/renderer.rs b/engine/src/renderer.rs index bf1cb51..066f3fc 100644 --- a/engine/src/renderer.rs +++ b/engine/src/renderer.rs @@ -156,6 +156,7 @@ pub struct RenderPass pub renderer_ctx_ent_id: Uid, pub surface_id: SurfaceId, pub commands: Vec, + pub draw_properties: DrawProperties, } #[derive(Debug)] @@ -187,7 +188,7 @@ pub enum Command usage: MeshUsage, }, DrawMesh(ObjectId), - SetPolygonModeConfig(PolygonModeConfig), + UpdateDrawProperties(DrawProperties, DrawPropertiesUpdateFlags), } bitflags! { @@ -212,6 +213,27 @@ pub enum MeshUsage Dynamic, } +#[derive(Debug, Default, Clone, PartialEq, Eq)] +#[non_exhaustive] +pub struct DrawProperties +{ + pub polygon_mode_config: PolygonModeConfig, +} + +bitflags! { + #[derive(Debug, Clone, Copy)] + pub struct DrawPropertiesUpdateFlags: usize + { + const POLYGON_MODE_CONFIG = 1 << 0; + } +} + +#[derive(Debug, Default, Clone, Component)] +pub struct ActiveDrawProperties +{ + pub draw_properties: DrawProperties, +} + /// Renderer command FIFO queue. /// /// This component is present in renderer context entities. @@ -318,6 +340,9 @@ pub fn add_main_render_passes( renderer_ctx_ent_id, surface_id: surface_spec.id, commands: Vec::with_capacity(30), + draw_properties: DrawProperties { + polygon_mode_config: PolygonModeConfig::default(), + }, }); let render_pass = render_passes.passes.front_mut().expect("Not possible"); @@ -440,8 +465,11 @@ pub fn add_main_render_passes( if let Some(draw_flags) = draw_flags.as_deref() && draw_flags.polygon_mode_config != PolygonModeConfig::default() { - render_pass.commands.push(Command::SetPolygonModeConfig( - draw_flags.polygon_mode_config.clone(), + render_pass.commands.push(Command::UpdateDrawProperties( + DrawProperties { + polygon_mode_config: draw_flags.polygon_mode_config.clone(), + }, + DrawPropertiesUpdateFlags::POLYGON_MODE_CONFIG, )); } @@ -460,8 +488,11 @@ pub fn add_main_render_passes( if let Some(draw_flags) = draw_flags.as_deref() && draw_flags.polygon_mode_config != PolygonModeConfig::default() { - render_pass.commands.push(Command::SetPolygonModeConfig( - PolygonModeConfig::default(), + render_pass.commands.push(Command::UpdateDrawProperties( + DrawProperties { + polygon_mode_config: PolygonModeConfig::default(), + }, + DrawPropertiesUpdateFlags::POLYGON_MODE_CONFIG, )); } } @@ -471,11 +502,21 @@ pub fn add_main_render_passes( #[tracing::instrument(skip_all)] pub fn enqueue_commands_from_render_passes( - renderer_ctx_query: Query<(&mut CommandQueue, &[Pair])>, + renderer_ctx_query: Query<( + &mut CommandQueue, + &[Pair], + &mut ActiveDrawProperties, + )>, mut render_passes: Single, entity_obtainer: EntityObtainer, ) { + let Some((_, _, mut active_draw_props)) = renderer_ctx_query.iter().next() else { + return; + }; + + let mut last_render_pass_draw_props = active_draw_props.draw_properties.clone(); + for render_pass in render_passes.passes.drain(..) { let Some(renderer_ctx_ent) = entity_obtainer.get_entity(render_pass.renderer_ctx_ent_id) @@ -498,12 +539,38 @@ pub fn enqueue_commands_from_render_passes( continue; }; + if render_pass.draw_properties != last_render_pass_draw_props { + renderer_ctx_command_queue.push(Command::UpdateDrawProperties( + render_pass.draw_properties.clone(), + DrawPropertiesUpdateFlags::all(), + )); + + last_render_pass_draw_props = render_pass.draw_properties; + } + + let last_updated_draw_props = render_pass + .commands + .iter() + .filter_map(|command| match command { + Command::UpdateDrawProperties(draw_props, _) => Some(draw_props.clone()), + _ => None, + }) + .last(); + renderer_ctx_command_queue .queue .extend(render_pass.commands); + + if let Some(last_updated_draw_props) = last_updated_draw_props { + last_render_pass_draw_props = last_updated_draw_props; + } } - for (mut command_queue, used_by_windows) in &renderer_ctx_query { + active_draw_props.draw_properties = last_render_pass_draw_props; + + drop(active_draw_props); + + for (mut command_queue, used_by_windows, _) in &renderer_ctx_query { for ctx_used_by_window in used_by_windows { let window_ent_id = ctx_used_by_window.id().target_entity(); diff --git a/engine/src/renderer/opengl.rs b/engine/src/renderer/opengl.rs index f1ca7a5..f80237a 100644 --- a/engine/src/renderer/opengl.rs +++ b/engine/src/renderer/opengl.rs @@ -79,10 +79,12 @@ use crate::renderer::opengl::glutin_compat::{ }; use crate::renderer::opengl::graphics_mesh::GraphicsMesh; use crate::renderer::{ + ActiveDrawProperties, BufferClearMask, Command as RendererCommand, CommandQueue as RendererCommandQueue, CtxUsedByWindow as RendererCtxUsedByWindow, + DrawPropertiesUpdateFlags, GraphicsProperties, PRE_RENDER_PHASE, RENDER_PHASE, @@ -655,6 +657,7 @@ fn init_window_graphics( .relation::() .target_id(window_ent_id) .build(), + ActiveDrawProperties::default(), )); actions.add_components( @@ -1137,17 +1140,24 @@ fn handle_commands( tracing::error!("Failed to draw mesh: {err}"); }; } - RendererCommand::SetPolygonModeConfig(polygon_mode_config) => { + RendererCommand::UpdateDrawProperties( + draw_props, + draw_props_update_flags, + ) => { let Some(curr_gl_ctx) = &opt_curr_gl_ctx else { tracing::error!("No GL context is current"); continue; }; - opengl_bindings::misc::set_polygon_mode( - &curr_gl_ctx, - polygon_mode_config.face, - polygon_mode_config.mode, - ); + if draw_props_update_flags + .contains(DrawPropertiesUpdateFlags::POLYGON_MODE_CONFIG) + { + opengl_bindings::misc::set_polygon_mode( + &curr_gl_ctx, + draw_props.polygon_mode_config.face, + draw_props.polygon_mode_config.mode, + ); + } } } } -- cgit v1.2.3-18-g5258