From 8a40b1462b4c5503846a8b5d7cdc83e3a31a61d2 Mon Sep 17 00:00:00 2001 From: Ed_ Date: Mon, 18 Mar 2024 11:44:58 -0400 Subject: [PATCH] Setup a 3d viewport for some extra stuff. Want to mess aroudn with my math notes possibly in this prototype... --- code/api.odin | 3 + code/colors.odin | 3 + code/env.odin | 4 + code/grime.odin | 4 + code/grime_stack.odin | 1 + code/logger.odin | 3 +- code/math.odin | 17 ---- code/math_pga.odin | 0 code/tick_render.odin | 183 +++++++++++++++++++++++++----------------- code/tick_update.odin | 13 +-- 10 files changed, 134 insertions(+), 97 deletions(-) create mode 100644 code/math_pga.odin diff --git a/code/api.odin b/code/api.odin index 8e0ff04..dbbdbd3 100644 --- a/code/api.odin +++ b/code/api.odin @@ -219,6 +219,9 @@ startup :: proc( prof : ^SpallProfiler, persistent_mem, frame_mem, transient_mem debug.lorem_parse, alloc_error = pws_parser_parse( transmute(string) debug.lorem_content, persistent_slab_allocator() ) verify( alloc_error == .None, "Faield to parse due to allocation failure" ) + + // Render texture test + debug.viewport_rt = rl.LoadRenderTexture( 1280, 720 ) } startup_ms := duration_ms( time.tick_lap_time( & startup_tick)) diff --git a/code/colors.odin b/code/colors.odin index da007a3..ba1a5af 100644 --- a/code/colors.odin +++ b/code/colors.odin @@ -17,6 +17,9 @@ Color_Frame_Hover :: Color { 122, 122, 125, 200 } Color_Frame_Select :: Color { 188, 188, 188, 220 } Color_GreyRed :: Color { 220, 100, 100, 165 } Color_White_A125 :: Color { 255, 255, 255, 165 } +Color_Black :: Color { 0, 0, 0, 255 } + +Color_3D_BG :: Color { 188, 182 , 170, 255 } Color_Debug_UI_Padding_Bounds :: Color { 40, 195, 170, 160 } Color_Debug_UI_Content_Bounds :: Color { 170, 120, 240, 160 } diff --git a/code/env.odin b/code/env.odin index 4d31a58..80a01a0 100644 --- a/code/env.odin +++ b/code/env.odin @@ -272,4 +272,8 @@ DebugData :: struct { path_lorem : string, lorem_content : []byte, lorem_parse : PWS_ParseResult, + + // Test 3d Viewport + cam_vp : rl.Camera3D, + viewport_rt : rl.RenderTexture, } diff --git a/code/grime.odin b/code/grime.odin index b683a48..f812794 100644 --- a/code/grime.odin +++ b/code/grime.odin @@ -136,6 +136,10 @@ released :: proc { btn_released, } +to_rl_rect :: proc { + range2_to_rl_rect, +} + to_runes :: proc { string_to_runes, } diff --git a/code/grime_stack.odin b/code/grime_stack.odin index 2c1d0e2..ce14e2f 100644 --- a/code/grime_stack.odin +++ b/code/grime_stack.odin @@ -40,6 +40,7 @@ stack_peek :: proc ( using stack : ^StackFixed( $ Type, $ Size ) ) -> Type { //region Stack Allocator +// TODO(Ed) : This is untested and problably filled with bugs. /* Growing Stack allocator This implementation can support growing if the backing allocator supports it without fragmenting the backing allocator. diff --git a/code/logger.odin b/code/logger.odin index 89cd351..9fe5e2e 100644 --- a/code/logger.odin +++ b/code/logger.odin @@ -44,7 +44,8 @@ logger_init :: proc( logger : ^ Logger, id : string, file_path : string, file : context.logger = { logger_interface, logger, core_log.Level.Debug, core_log.Default_File_Logger_Opts } log("Initialized Logger") when false { - log("This sentence is over 80 characters long on purpose to test the ability of this fucking logger to properfly fucking wrap long as fuck logs with a new line and then at the end of that pad it with the appropraite signature.") + log("This sentence is over 80 characters long on purpose to test the ability of this logger to properfly wrap long as logs with a new line and then at the end of that pad it with the appropraite signature.") + } } diff --git a/code/math.odin b/code/math.odin index 7a26418..a22d480 100644 --- a/code/math.odin +++ b/code/math.odin @@ -50,10 +50,6 @@ range2 :: #force_inline proc "contextless" ( a, b : Vec2 ) -> Range2 { return result } -Rect :: struct { - top_left, bottom_right : Vec2 -} - add_range2 :: #force_inline proc "contextless" ( a, b : Range2 ) -> Range2 { result := Range2 { pts = { a.p0 + b.p0, @@ -67,19 +63,6 @@ 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 } } diff --git a/code/math_pga.odin b/code/math_pga.odin new file mode 100644 index 0000000..e69de29 diff --git a/code/tick_render.odin b/code/tick_render.odin index 09585e4..35eff01 100644 --- a/code/tick_render.odin +++ b/code/tick_render.odin @@ -9,6 +9,21 @@ render :: proc() { profile(#procedure) state := get_state(); using state + + render_mode_3d() + + rl.BeginDrawing() + rl.ClearBackground( Color_BG ) + + render_mode_2d() + render_mode_screenspace() + + rl.EndDrawing() +} + +render_mode_screenspace :: proc () +{ + state := get_state(); using state replay := & Memory_App.replay cam := & project.workspace.cam win_extent := state.app_window.extent @@ -18,86 +33,78 @@ render :: proc() -win_extent.y + cam.target.y, } - rl.BeginDrawing() - rl.ClearBackground( Color_BG ) - render_mode_2d() - //region Render Screenspace + profile("Render Screenspace") + fps_msg := str_fmt_tmp( "FPS: %f", fps_avg) + fps_msg_width := measure_text_size( fps_msg, default_font, 16.0, 0.0 ).x + fps_msg_pos := screen_get_corners().top_right - { fps_msg_width, 0 } + debug_draw_text( fps_msg, fps_msg_pos, 16.0, color = rl.GREEN ) + + debug_text :: proc( format : string, args : ..any ) { - profile("Render Screenspace") - fps_msg := str_fmt_tmp( "FPS: %f", fps_avg) - fps_msg_width := measure_text_size( fps_msg, default_font, 16.0, 0.0 ).x - fps_msg_pos := screen_get_corners().top_right - { fps_msg_width, 0 } - debug_draw_text( fps_msg, fps_msg_pos, 16.0, color = rl.GREEN ) + @static draw_text_scratch : [Kilobyte * 64]u8 - debug_text :: proc( format : string, args : ..any ) - { - @static draw_text_scratch : [Kilobyte * 64]u8 - - state := get_state(); using state - if debug.draw_debug_text_y > 800 { - debug.draw_debug_text_y = 50 - } - - cam := & project.workspace.cam - screen_corners := screen_get_corners() - - position := screen_corners.top_right - position.x -= 800 - position.y += debug.draw_debug_text_y - - content := str_fmt_buffer( draw_text_scratch[:], format, ..args ) - debug_draw_text( content, position, 14.0 ) - - debug.draw_debug_text_y += 14 + state := get_state(); using state + if debug.draw_debug_text_y > 800 { + debug.draw_debug_text_y = 50 } - // Debug Text - { - // debug_text( "Screen Width : %v", rl.GetScreenWidth () ) - // debug_text( "Screen Height: %v", rl.GetScreenHeight() ) - debug_text( "frametime_target_ms : %f ms", frametime_target_ms ) - debug_text( "frametime : %f ms", frametime_delta_ms ) - // debug_text( "frametime_last_elapsed_ms : %f ms", frametime_elapsed_ms ) - if replay.mode == ReplayMode.Record { - debug_text( "Recording Input") - } - if replay.mode == ReplayMode.Playback { - debug_text( "Replaying Input") - } - } + cam := & project.workspace.cam + screen_corners := screen_get_corners() - debug_text("Zoom Target: %v", project.workspace.zoom_target) + position := screen_corners.top_right + position.x -= 800 + position.y += debug.draw_debug_text_y - if debug.mouse_vis { - debug_text( "Mouse Vertical Wheel: %v", input.mouse.vertical_wheel ) - debug_text( "Mouse Position (Screen): %v", input.mouse.pos ) - debug_text("Mouse Position (World): %v", screen_to_world(input.mouse.pos) ) - cursor_pos := transmute(Vec2) state.app_window.extent + input.mouse.pos - rl.DrawCircleV( cursor_pos, 10, Color_White_A125 ) - } + content := str_fmt_buffer( draw_text_scratch[:], format, ..args ) + debug_draw_text( content, position, 14.0 ) - ui := project.workspace.ui - - // debug_text("Box Count: %v", ui.built_box_count ) - - 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 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 + debug.draw_debug_text_y += 14 } - //endregion Render Screenspace - rl.EndDrawing() + + // Debug Text + { + // debug_text( "Screen Width : %v", rl.GetScreenWidth () ) + // debug_text( "Screen Height: %v", rl.GetScreenHeight() ) + debug_text( "frametime_target_ms : %f ms", frametime_target_ms ) + debug_text( "frametime : %f ms", frametime_delta_ms ) + // debug_text( "frametime_last_elapsed_ms : %f ms", frametime_elapsed_ms ) + if replay.mode == ReplayMode.Record { + debug_text( "Recording Input") + } + if replay.mode == ReplayMode.Playback { + debug_text( "Replaying Input") + } + } + + debug_text("Zoom Target: %v", project.workspace.zoom_target) + + if debug.mouse_vis { + debug_text( "Mouse Vertical Wheel: %v", input.mouse.vertical_wheel ) + debug_text( "Mouse Position (Screen): %v", input.mouse.pos ) + debug_text("Mouse Position (World): %v", screen_to_world(input.mouse.pos) ) + cursor_pos := transmute(Vec2) state.app_window.extent + input.mouse.pos + rl.DrawCircleV( cursor_pos, 10, Color_White_A125 ) + } + + ui := project.workspace.ui + + // debug_text("Box Count: %v", ui.built_box_count ) + + 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 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 } render_mode_2d :: proc() @@ -110,6 +117,19 @@ render_mode_2d :: proc() rl.BeginMode2D( project.workspace.cam ) + // Draw 3D Viewport + { + viewport_size := Vec2 { 1280.0, 720.0 } + vp_half_size := viewport_size * 0.5 + viewport_box := range2( -vp_half_size, vp_half_size ) + viewport_render := range2( + world_to_screen_pos( viewport_box.min), + world_to_screen_pos( viewport_box.max), + ) + viewport_rect := range2_to_rl_rect( viewport_render ) + rl.DrawTextureRec( debug.viewport_rt.texture, viewport_rect, -vp_half_size, Color_White ) + } + // draw_text( "This is text in world space", { 0, 200 }, 16.0 ) cam_zoom_ratio := 1.0 / cam.zoom @@ -154,6 +174,7 @@ render_mode_2d :: proc() continue } + // TODO(Ed) : Render Borders // profile_begin("Calculating Raylib rectangles") @@ -269,7 +290,23 @@ render_mode_2d :: proc() rl.DrawCircleV( world_to_screen_pos(cursor_world_pos), 5, Color_GreyRed ) } - rl.DrawCircleV( { 0, 0 }, 1 * cam_zoom_ratio, Color_White ) + // rl.DrawCircleV( { 0, 0 }, 1 * cam_zoom_ratio, Color_White ) rl.EndMode2D() } + +render_mode_3d :: proc() +{ + profile(#procedure) + + state := get_state(); using state + + rl.BeginDrawing() + rl.BeginTextureMode( debug.viewport_rt ) + rl.BeginMode3D( debug.cam_vp ) + rl.ClearBackground( Color_3D_BG ) + + rl.EndMode3D() + rl.EndTextureMode() + rl.EndDrawing() +} diff --git a/code/tick_update.odin b/code/tick_update.odin index 3a9f958..7e92d5b 100644 --- a/code/tick_update.odin +++ b/code/tick_update.odin @@ -148,7 +148,7 @@ update :: proc( delta_time : f64 ) -> b32 debug.mouse_vis = !debug.mouse_vis } - //region Camera Manual Nav + //region 2D Camera Manual Nav { // profile("Camera Manual Nav") digital_move_speed : f32 = 200.0 @@ -157,6 +157,7 @@ update :: proc( delta_time : f64 ) -> b32 workspace.zoom_target = cam.zoom } + config.cam_max_zoom = 30.0 config.cam_zoom_smooth_snappiness = 10.0 config.cam_zoom_mode = .Smooth switch config.cam_zoom_mode @@ -164,15 +165,15 @@ update :: proc( delta_time : f64 ) -> b32 case .Smooth: zoom_delta := input.mouse.vertical_wheel * config.cam_zoom_sensitivity_smooth workspace.zoom_target *= 1 + zoom_delta * f32(delta_time) - workspace.zoom_target = clamp(workspace.zoom_target, 0.05, 10.0) + workspace.zoom_target = clamp(workspace.zoom_target, 0.05, config.cam_max_zoom) // Linearly interpolate cam.zoom towards zoom_target lerp_factor := config.cam_zoom_smooth_snappiness // Adjust this value to control the interpolation speed cam.zoom += (workspace.zoom_target - cam.zoom) * lerp_factor * f32(delta_time) - cam.zoom = clamp(cam.zoom, 0.05, 10.0) // Ensure cam.zoom stays within bounds + cam.zoom = clamp(cam.zoom, 0.05, config.cam_max_zoom) // Ensure cam.zoom stays within bounds case .Digital: zoom_delta := input.mouse.vertical_wheel * config.cam_zoom_sensitivity_digital - workspace.zoom_target = clamp(workspace.zoom_target + zoom_delta, 0.05, 10.0) + workspace.zoom_target = clamp(workspace.zoom_target + zoom_delta, 0.05, config.cam_max_zoom) cam.zoom = workspace.zoom_target } @@ -191,7 +192,7 @@ update :: proc( delta_time : f64 ) -> b32 } } } - //endregion Camera Manual Nav + //endregion 2D Camera Manual Nav //region Imgui Tick { @@ -242,7 +243,7 @@ update :: proc( delta_time : f64 ) -> b32 // test_text_box() // test_parenting() - if true + if false { // frame := ui_widget( "Frame", {} ) // ui_parent(frame)