diff options
Diffstat (limited to 'engine/src')
| -rw-r--r-- | engine/src/ui/imgui.rs | 68 | ||||
| -rw-r--r-- | engine/src/windowing.rs | 68 |
2 files changed, 97 insertions, 39 deletions
diff --git a/engine/src/ui/imgui.rs b/engine/src/ui/imgui.rs index 75ce9c0..bb13d8d 100644 --- a/engine/src/ui/imgui.rs +++ b/engine/src/ui/imgui.rs @@ -63,9 +63,11 @@ use crate::rendering::{ Command as RenderingCommand, DrawMeshOptions, DrawProperties, + DrawPropertiesUpdateFlags, MeshUsage, RenderPass, RenderPasses, + ScissorBox, SurfaceId, SurfaceSpec, PRE_RENDER_PHASE, @@ -561,6 +563,7 @@ fn add_drawing_render_pass( }, depth_test_enabled: false, face_culling_enabled: false, + scissor_test_enabled: true, ..Default::default() }, }); @@ -644,14 +647,26 @@ fn add_drawing_render_pass( for command in draw_list.commands() { match command { ImguiDrawCmd::Elements { count, cmd_params, raw_cmd: _ } => { - render_pass.commands.push(RenderingCommand::DrawMesh( - mesh_obj_id, - DrawMeshOptions::builder() - .element_offset(cmd_params.idx_offset.try_into().unwrap()) - .vertex_offset(cmd_params.vtx_offset.try_into().unwrap()) - .element_cnt(count.try_into().unwrap()) - .build(), - )); + let Some(scissor_box) = + calc_draw_cmd_scissor_box(draw_data, &cmd_params) + else { + continue; + }; + + render_pass.commands.extend([ + RenderingCommand::UpdateDrawProperties( + DrawProperties { scissor_box, ..Default::default() }, + DrawPropertiesUpdateFlags::SCISSOR_BOX, + ), + RenderingCommand::DrawMesh( + mesh_obj_id, + DrawMeshOptions::builder() + .element_offset(cmd_params.idx_offset.try_into().unwrap()) + .vertex_offset(cmd_params.vtx_offset.try_into().unwrap()) + .element_cnt(count.try_into().unwrap()) + .build(), + ), + ]); } _ => {} } @@ -659,6 +674,43 @@ fn add_drawing_render_pass( } } +fn calc_draw_cmd_scissor_box( + draw_data: &dear_imgui_rs::DrawData, + cmd_params: &dear_imgui_rs::DrawCmdParams, +) -> Option<ScissorBox> +{ + let clip_rect = cmd_params.clip_rect; + + let clip_min_x = + (clip_rect[0] - draw_data.display_pos[0]) * draw_data.framebuffer_scale[0]; + + let clip_min_y = + (clip_rect[1] - draw_data.display_pos[1]) * draw_data.framebuffer_scale[1]; + + let clip_max_x = + (clip_rect[2] - draw_data.display_pos[0]) * draw_data.framebuffer_scale[0]; + + let clip_max_y = + (clip_rect[3] - draw_data.display_pos[1]) * draw_data.framebuffer_scale[1]; + + if clip_max_x <= clip_min_x || clip_max_y <= clip_min_y { + return None; + } + + let fb_height = draw_data.display_size[1] * draw_data.framebuffer_scale[1]; + + Some(ScissorBox { + size: Some(Dimens { + width: (clip_max_x - clip_min_x) as u16, + height: (clip_max_y - clip_min_y) as u16, + }), + lower_left_corner_pos: Vec2 { + x: clip_min_x as u16, + y: (fb_height - clip_max_y) as u16, + }, + }) +} + fn create_font_texture( font_texture_data: &dear_imgui_rs::texture::TextureData, ) -> Result<Texture, ImageFromBytesError> diff --git a/engine/src/windowing.rs b/engine/src/windowing.rs index dc378fa..adc5132 100644 --- a/engine/src/windowing.rs +++ b/engine/src/windowing.rs @@ -169,7 +169,13 @@ fn update_stuff( return Ok(()); }; - std::mem::take(&mut *input) + let new_input = Input { + relative_mouse_pos_delta: Vec2 { x: 0.0, y: 0.0 }, + absolute_mouse_pos: input.absolute_mouse_pos.clone(), + mouse_scroll_delta: MouseScrollDelta { vert_lines: 0.0, hor_lines: 0.0 }, + }; + + std::mem::replace(&mut *input, new_input) }; mouse.curr_tick_position_delta = input.relative_mouse_pos_delta; @@ -951,6 +957,36 @@ impl ApplicationHandler for App ); }; } + WindowEvent::MouseWheel { device_id: _, delta, phase: _ } => { + let (hor_lines, vert_lines) = match delta { + winit::event::MouseScrollDelta::LineDelta(hor_lines, vert_lines) => { + (hor_lines, vert_lines) + } + winit::event::MouseScrollDelta::PixelDelta(pos_delta) => { + let hor_lines = match pos_delta.x.partial_cmp(&0.0) { + Some(std::cmp::Ordering::Greater) => 1.0, + Some(std::cmp::Ordering::Less) => -1.0, + _ => 0.0, + }; + + let vert_lines = match pos_delta.y.partial_cmp(&0.0) { + Some(std::cmp::Ordering::Greater) => 1.0, + Some(std::cmp::Ordering::Less) => -1.0, + _ => 0.0, + }; + + (hor_lines, vert_lines) + } + }; + + let Some(mut input) = self.lock_input() else { + tracing::error!("Locking input mutex timed out after 100ms"); + return; + }; + + input.mouse_scroll_delta.hor_lines += hor_lines; + input.mouse_scroll_delta.vert_lines += vert_lines; + } WindowEvent::MouseInput { device_id: _, state, button } => { self.send_message(MessageFromApp::MouseButtonStateChanged( button.into(), @@ -984,36 +1020,6 @@ impl ApplicationHandler for App input.relative_mouse_pos_delta += Vec2::from(delta); } - DeviceEvent::MouseWheel { delta } => { - let (hor_lines, vert_lines) = match delta { - winit::event::MouseScrollDelta::LineDelta(hor_lines, vert_lines) => { - (hor_lines, vert_lines) - } - winit::event::MouseScrollDelta::PixelDelta(pos_delta) => { - let hor_lines = match pos_delta.x.partial_cmp(&0.0) { - Some(std::cmp::Ordering::Greater) => 1.0, - Some(std::cmp::Ordering::Less) => -1.0, - _ => 0.0, - }; - - let vert_lines = match pos_delta.y.partial_cmp(&0.0) { - Some(std::cmp::Ordering::Greater) => 1.0, - Some(std::cmp::Ordering::Less) => -1.0, - _ => 0.0, - }; - - (hor_lines, vert_lines) - } - }; - - let Some(mut input) = self.lock_input() else { - tracing::error!("Locking input mutex timed out after 100ms"); - return; - }; - - input.mouse_scroll_delta.hor_lines += hor_lines; - input.mouse_scroll_delta.vert_lines += vert_lines; - } _ => {} } } |
