From 8b8c4948ad156faae79a03e8173ad6890cf98fac Mon Sep 17 00:00:00 2001 From: Ed_ Date: Mon, 11 Mar 2024 02:05:30 -0400 Subject: [PATCH] Added screeenspace culling for ui boxes --- code/collision.odin | 11 +++++++++++ code/math.odin | 13 +++++++++++++ code/space.odin | 8 ++++---- code/tick_render.odin | 41 ++++++++++++++++++++++++++++++----------- scripts/build.ps1 | 6 ++++-- 5 files changed, 62 insertions(+), 17 deletions(-) diff --git a/code/collision.odin b/code/collision.odin index cde9c2c..0b7fa20 100644 --- a/code/collision.odin +++ b/code/collision.odin @@ -16,3 +16,14 @@ is_within_screenspace :: proc( pos : Vec2 ) -> b32 { within_y_bounds : b32 = pos.y >= -screen_extent.y && pos.y <= screen_extent.y return within_x_bounds && within_y_bounds } + +within_range2 :: #force_inline proc ( a, b : Range2 ) -> bool { + a_half_size := size_range2( a ) * 0.5 + b_half_size := size_range2( b ) * 0.5 + a_center := a.p0 + { a_half_size.x, -a_half_size.y } + b_center := b.p0 + { b_half_size.x, -b_half_size.y } + + within_x := abs(a_center.x - b_center.x) <= (a_half_size.x + b_half_size.y) + within_y := abs(a_center.y - b_center.y) <= (a_half_size.y + b_half_size.y) + return within_x && within_y +} diff --git a/code/math.odin b/code/math.odin index 6efa7cf..d3c3873 100644 --- a/code/math.odin +++ b/code/math.odin @@ -55,6 +55,19 @@ equal_range2 :: #force_inline proc "contextless" ( a, b : Range2 ) -> b32 { return b32(result) } + +// // Translated intersect_2f32 function +// intersect_2f32 :: proc(a, b: Rng2F32) -> Rng2F32 { +// c: Rng2F32 +// c.min.x = Max(a.min.x, b.min.x) +// c.min.y = Max(a.min.y, b.min.y) +// c.max.x = Min(a.max.x, b.max.x) +// c.max.y = Min(a.max.y, b.max.y) +// return c +// } + + + size_range2 :: #force_inline proc "contextless" ( value : Range2 ) -> Vec2 { return { value.p1.x - value.p0.x, value.p0.y - value.p1.y } } \ No newline at end of file diff --git a/code/space.odin b/code/space.odin index 6f80d04..8e2a6ac 100644 --- a/code/space.odin +++ b/code/space.odin @@ -142,13 +142,13 @@ screen_get_corners :: proc() -> BoundsCorners2 { return { top_left, top_right, bottom_left, bottom_right } } -view_get_bounds :: proc() -> Bounds2 { +view_get_bounds :: proc() -> Range2 { state := get_state(); using state cam := & project.workspace.cam screen_extent := state.app_window.extent - top_left := cam.target + Vec2 { -screen_extent.x, screen_extent.y} - bottom_right := cam.target + Vec2 { screen_extent.x, -screen_extent.y} - return { top_left, bottom_right } + top_left := Vec2 { cam.target.x, -cam.target.y } + Vec2 { -screen_extent.x, screen_extent.y} * (1/cam.zoom) + bottom_right := Vec2 { cam.target.x, -cam.target.y } + Vec2 { screen_extent.x, -screen_extent.y} * (1/cam.zoom) + return range2(top_left, bottom_right) } view_get_corners :: proc() -> BoundsCorners2 { diff --git a/code/tick_render.odin b/code/tick_render.odin index 541e706..3c70207 100644 --- a/code/tick_render.odin +++ b/code/tick_render.odin @@ -82,13 +82,17 @@ render :: proc() hot_box := ui_box_from_key( ui.curr_cache, ui.hot ) active_box := ui_box_from_key( ui.curr_cache, ui.active ) if hot_box != nil { - debug_text("Hot Box: %v", hot_box.label.str ) + debug_text("Hot Box : %v", hot_box.label.str ) + debug_text("Hot Range2: %v", hot_box.computed.bounds.pts) } if active_box != nil{ debug_text("Active Box: %v", active_box.label.str ) } // debug_text("Active Resizing: %v", ui.active_start_signal.resizing) + view := view_get_bounds() + debug_text("View Bounds (World): %v", view.pts ) + debug.draw_debug_text_y = 50 } //endregion Render Screenspace @@ -109,6 +113,22 @@ render_mode_2d :: proc() cam_zoom_ratio := 1.0 / cam.zoom + view_bounds := view_get_bounds() + when false + { + render_view := Range2 { pts = { + world_to_screen_pos(view_bounds.min), + world_to_screen_pos(view_bounds.max), + }} + view_rect := rl.Rectangle { + render_view.min.x, + render_view.min.y, + render_view.max.x - render_view.min.x, + render_view.max.y - render_view.min.y, + } + rl.DrawRectangleRounded( view_rect, 0.3, 9, { 255, 0, 0, 20 } ) + } + ImguiRender: { profile("Imgui Render") @@ -119,7 +139,7 @@ render_mode_2d :: proc() } current := root.first - for ; current != nil; + for ; current != nil; current = ui_box_tranverse_next( current ) { profile("Box") parent := current.parent @@ -127,9 +147,11 @@ render_mode_2d :: proc() style := current.style computed := & current.computed - // bg_color := + if ! within_range2( view_bounds, computed.bounds ) { + continue + } - // TODO(Ed) : Render Borders + // TODO(Ed) : Render Borders // profile_begin("Calculating Raylib rectangles") render_bounds := Range2 { pts = { @@ -195,14 +217,14 @@ render_mode_2d :: proc() // profile_begin("rl.DrawRectangleRoundedLines: padding & content") if equal_range2(computed.content, computed.padding) { - // draw_rectangle_lines( rect_padding, style, Color_Debug_UI_Padding_Bounds, line_thickness ) + draw_rectangle_lines( rect_padding, style, Color_Debug_UI_Padding_Bounds, line_thickness ) } else { - // draw_rectangle_lines( rect_padding, style, Color_Debug_UI_Content_Bounds, line_thickness ) + draw_rectangle_lines( rect_padding, style, Color_Debug_UI_Content_Bounds, line_thickness ) } // profile_end() - if .Mouse_Resizable in current.flags && false + if .Mouse_Resizable in current.flags { // profile("Resize Bounds") resize_border_width := cast(f32) get_state().config.ui_resize_border_width @@ -221,11 +243,10 @@ render_mode_2d :: proc() render_resize.max.x - render_resize.min.x, render_resize.max.y - render_resize.min.y, } - // rl.DrawRectangleRoundedLines( rect_resize, style.layout.corner_radii[0], 9, line_thickness, Color_Red ) draw_rectangle_lines( rect_padding, style, Color_Red, line_thickness ) } - point_radius := 2 * cam_zoom_ratio + point_radius := 3 * cam_zoom_ratio // profile_begin("circles") // rl.DrawCircleV( render_bounds.p0, point_radius, Color_Red ) @@ -235,8 +256,6 @@ render_mode_2d :: proc() if len(current.text.str) > 0 { draw_text_string_cached( current.text, world_to_screen_pos(computed.text_pos), style.font_size, style.text_color ) } - - current = ui_box_tranverse_next( current ) } } //endregion Imgui Render diff --git a/scripts/build.ps1 b/scripts/build.ps1 index d96e116..6a9ea96 100644 --- a/scripts/build.ps1 +++ b/scripts/build.ps1 @@ -156,9 +156,10 @@ push-location $path_root # $build_args += ($flag_collection + $pkg_collection_thirdparty) $build_args += $flag_use_separate_modules $build_args += $flag_thread_count + $CoreCount_Physical - $build_args += $flag_optimize_none + # $build_args += $flag_optimize_none # $build_args += $flag_optimize_minimal # $build_args += $flag_optimize_speed + $build_args += $falg_optimize_aggressive $build_args += $flag_debug $build_args += $flag_pdb_name + $pdb $build_args += $flag_subsystem + 'windows' @@ -228,7 +229,8 @@ push-location $path_root $build_args += $flag_thread_count + $CoreCount_Physical # $build_args += $flag_optimize_none # $build_args += $flag_optimize_minimal - $build_args += $flag_optimize_speed + # $build_args += $flag_optimize_speed + $build_args += $falg_optimize_aggressive $build_args += $flag_debug $build_args += $flag_pdb_name + $pdb $build_args += $flag_subsystem + 'windows'