Skip to content

Commit

Permalink
Fixes #12000: When viewport is set to camera and switched to SizedFul… (
Browse files Browse the repository at this point in the history
#12861)

# Objective

- When viewport is set to the same size as the window on creation, when
adjusting to SizedFullscreen, the window may be smaller than the
viewport for a moment, which caused the arguments to be invalid and
panic.
- Fixes #12000.

## Solution

- The fix consists of matching the size of the viewport to the lower
size of the window ( if the x value of the window is lower, I update
only the x value of the viewport, same for the y value). Also added a
test to show that it does not panic anymore.

---
  • Loading branch information
LuisFigueiredo73 authored Apr 6, 2024
1 parent a27ce27 commit ac91b19
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 0 deletions.
14 changes: 14 additions & 0 deletions crates/bevy_render/src/camera/camera.rs
Original file line number Diff line number Diff line change
Expand Up @@ -755,6 +755,20 @@ pub fn camera_system<T: CameraProjection + Component>(
}
}
}
// This check is needed because when changing WindowMode to SizedFullscreen, the viewport may have invalid
// arguments due to a sudden change on the window size to a lower value.
// If the size of the window is lower, the viewport will match that lower value.
if let Some(viewport) = &mut camera.viewport {
let target_info = &new_computed_target_info;
if let Some(target) = target_info {
if viewport.physical_size.x > target.physical_size.x {
viewport.physical_size.x = target.physical_size.x;
}
if viewport.physical_size.y > target.physical_size.y {
viewport.physical_size.y = target.physical_size.y;
}
}
}
camera.computed.target_info = new_computed_target_info;
if let Some(size) = camera.logical_viewport_size() {
camera_projection.update(size.x, size.y);
Expand Down
50 changes: 50 additions & 0 deletions tests/window/change_window_mode.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
//! a test that confirms that 'bevy' does not panic while changing from Windowed to SizedFullscreen when viewport is set
use bevy::
{ prelude::*,
render::camera::Viewport,
window::WindowMode,
};

//Having a viewport set to the same size as a window used to cause panic on some occasions when switching to SizedFullscreen
const WINDOW_WIDTH : f32 = 1366.0;
const WINDOW_HEIGHT: f32 = 768.0;

fn main()
{ //Specify Window Size.
let window = Window { resolution: ( WINDOW_WIDTH, WINDOW_HEIGHT ).into(), ..default() };
let primary_window = Some ( window );

App::new()
.add_plugins( DefaultPlugins.set( WindowPlugin { primary_window, ..default() } ) )
.add_systems( Startup, startup )
.add_systems( Update, toggle_window_mode )
.run();
}

fn startup( mut cmds: Commands )
{ //Match viewport to Window size.
let physical_position = UVec2::new( 0, 0 );
let physical_size = Vec2::new( WINDOW_WIDTH, WINDOW_HEIGHT ).as_uvec2();
let viewport = Some ( Viewport { physical_position, physical_size, ..default() } );

cmds.spawn( Camera2dBundle::default() ).insert( Camera { viewport, ..default() } );
}

fn toggle_window_mode
( mut qry_window: Query<&mut Window>,
)
{ let Ok( mut window ) = qry_window.get_single_mut() else { return };

window.mode = match window.mode {
WindowMode::Windowed => {
//it takes a while for the window to change from windowed to sizedfullscreen and back
std::thread::sleep(std::time::Duration::from_secs(4));
WindowMode::SizedFullscreen
},
_ => {
std::thread::sleep(std::time::Duration::from_secs(4));
WindowMode::Windowed
},
};
}

0 comments on commit ac91b19

Please sign in to comment.