From fb1702190d3a8dfda1d202f16b951d1d6f4e765b Mon Sep 17 00:00:00 2001 From: Jason Hilder Date: Fri, 11 Sep 2026 07:51:38 +0200 Subject: [PATCH] Multiple scene rendering setup. --- src/scene_manager.odin | 109 +++++++++++++++++++++-------------------- 1 file changed, 55 insertions(+), 54 deletions(-) diff --git a/src/scene_manager.odin b/src/scene_manager.odin index e788e86..edb1453 100644 --- a/src/scene_manager.odin +++ b/src/scene_manager.odin @@ -2,26 +2,36 @@ package game import rl "vendor:raylib" +// ------------------------------------------------------------------------------ +// Scene & Overlay Definitions +// ------------------------------------------------------------------------------ +Scene_Gameplay :: struct { + level: Level, +} + +Scene_Menu :: struct { + // @todo: ui_canvas layout state +} + +Scene_PauseMenu :: struct { + // @todo: pause option state +} + Scene :: union { Scene_Menu, Scene_Gameplay, } -Scene_Menu :: struct { - // Ui_Canvas - // as in a struct so that we cleanly have either Level or Ui_Canvas -} - -Scene_Gameplay :: struct { - level: Level, +Overlay_Scene :: union { + Scene_PauseMenu, } // ------------------------------------------------------------------------------ -// Scene Dispatchers +// Base Scene Dispatchers // ------------------------------------------------------------------------------ scene_update :: proc(game: ^Game, input: Input_Event, dt: f32) { switch &s in game.scene { - case Scene_Menu: // update_menu(&s, game, dt) + case Scene_Menu: // update_menu(&s, game, input, dt) case Scene_Gameplay: update_gameplay(&s, game, input, dt) } } @@ -29,27 +39,45 @@ scene_update :: proc(game: ^Game, input: Input_Event, dt: f32) { scene_render :: proc(game: ^Game) { switch &s in game.scene { case Scene_Menu: // render_menu(s) - case Scene_Gameplay: render_gameplay(s, game.viewport, game.paused) + case Scene_Gameplay: render_gameplay(s) } } // ------------------------------------------------------------------------------ -// Menu Scene +// Overlay Scene Dispatchers // ------------------------------------------------------------------------------ -// @TODO: -// update_menu :: proc - // if input.move_dir.y < 0 { // UP - // menu.selected_option = max(0, menu.selected_option - 1) - // } else if input.move_dir.y > 0 { // DOWN - // menu.selected_option = min(MAX_OPTIONS - 1, menu.selected_option + 1) - // } +overlay_update :: proc(game: ^Game, input: Input_Event, dt: f32) -> bool { + overlay := game.overlay_scene.? or_return - // if input.confirm_pressed { - // // Execute menu selection - // } + switch &o in overlay { + case Scene_PauseMenu: + if input.pause_pressed { + game.overlay_scene = nil + return true + } + // @todo: handle overlay menu option selection (resume, settings, quit) + } + + return true +} + +overlay_render :: proc(game: ^Game) -> bool { + overlay := game.overlay_scene.? or_return + + switch &o in overlay { + case Scene_PauseMenu: + // Translucent dark tint across virtual canvas space + rl.DrawRectangleRec(rl.Rectangle{0, 0, VIEWPORT_W, VIEWPORT_H}, rl.Color{0, 0, 0, 140}) + // Pause Menu UI elements + rl.DrawText("PAUSED", VIEWPORT_W / 2 - 80, VIEWPORT_H / 2 - 40, 40, rl.WHITE) + rl.DrawText("Press Q to Quit to Menu", VIEWPORT_W / 2 - 110, VIEWPORT_H / 2 + 10, 20, rl.LIGHTGRAY) + } + + return true +} // ------------------------------------------------------------------------------ -// Gameplay Scene +// Gameplay Scene Procedures // ------------------------------------------------------------------------------ init_gameplay_scene :: proc() -> Scene_Gameplay { return Scene_Gameplay{ @@ -59,41 +87,14 @@ init_gameplay_scene :: proc() -> Scene_Gameplay { update_gameplay :: proc(scene: ^Scene_Gameplay, game: ^Game, input: Input_Event, dt: f32) { if input.pause_pressed { - game.paused = !game.paused + game.overlay_scene = Scene_PauseMenu{} + return } - if game.paused do return update_level(&scene.level, input, dt) } -render_gameplay :: proc(scene: Scene_Gameplay, viewport_texture: rl.RenderTexture2D, is_paused: bool) { - // Offscreen Pass: Render all game objects at low/fixed virtual resolution - rl.BeginTextureMode(viewport_texture) - rl.ClearBackground(rl.BLACK) - - render_level(scene.level) - - if is_paused { - // UI coordinates aligned relative to internal 1280x720 viewport space - rl.DrawRectangleRec(rl.Rectangle{0,0, VIEWPORT_W, VIEWPORT_H}, rl.Color{0,0,0,140}) - rl.DrawText("PAUSED", VIEWPORT_W / 2 - 80, VIEWPORT_H / 2 - 40, 40, rl.WHITE) - rl.DrawText("Press Q to Quit to Menu", VIEWPORT_W / 2 - 110, VIEWPORT_H / 2 + 10, 20, rl.LIGHTGRAY) - } - rl.EndTextureMode() - - // Upscale Pass: Stretch render buffer onto actual window display - render_game_to_window(viewport_texture.texture) -} - -render_game_to_window :: proc(texture: rl.Texture) { - rl.DrawTexturePro( - texture, - // src: OpenGL render targets have inverted Y coordinates (-height flips it) - rl.Rectangle{0, 0, f32(texture.width), -f32(texture.height)}, - // dst: Scales viewport canvas to fill window res (WINDOW_WIDTHxWINDOW_HEIGHT) - rl.Rectangle{0, 0, f32(WINDOW_W), f32(WINDOW_H)}, - rl.Vector2{}, - 0, - rl.WHITE - ) +render_gameplay :: proc(scene: Scene_Gameplay) { + render_level(scene.level) + render_hud(scene.level) } \ No newline at end of file