Skip to content

Commit

Permalink
Fixes bevyengine#12000: When viewport is set to camera and switched t…
Browse files Browse the repository at this point in the history
…o SizedFullscreen, panic may occur

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.
The fix consists of matching the size of the viewport to the size of the window when it is smaller.
Also added a test to show that it does not panic.
  • Loading branch information
LuisFigueiredo73 committed Apr 3, 2024
1 parent 6840f95 commit 4ac25b3
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 0 deletions.
11 changes: 11 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,17 @@ pub fn camera_system<T: CameraProjection + Component>(
}
}
}
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 4ac25b3

Please sign in to comment.