Path: blob/main/examples/stress_tests/many_sprite_meshes.rs
9353 views
//! Renders a lot of sprites to allow performance testing.1//! See <https://github.com/bevyengine/bevy/pull/1492>2//!3//! This example sets up many sprites in different sizes, rotations, and scales in the world.4//! It also moves the camera over them to see how well frustum culling works.5//!6//! Add the `--colored` arg to run with color tinted sprites. This will cause the sprites to be rendered7//! in multiple batches, reducing performance but useful for testing.8//!9//! This is a modified version of `many_sprites` but based on [`SpriteMesh`]1011use bevy::{12color::palettes::css::*,13diagnostic::{FrameTimeDiagnosticsPlugin, LogDiagnosticsPlugin},14prelude::*,15window::{PresentMode, WindowResolution},16winit::WinitSettings,17};1819use rand::Rng;2021const CAMERA_SPEED: f32 = 1000.0;2223const COLORS: [Color; 3] = [Color::Srgba(BLUE), Color::Srgba(WHITE), Color::Srgba(RED)];2425#[derive(Resource)]26struct ColorTint(bool);2728fn main() {29App::new()30.insert_resource(ColorTint(31std::env::args().nth(1).unwrap_or_default() == "--colored",32))33// Since this is also used as a benchmark, we want it to display performance data.34.add_plugins((35LogDiagnosticsPlugin::default(),36FrameTimeDiagnosticsPlugin::default(),37DefaultPlugins.set(WindowPlugin {38primary_window: Some(Window {39present_mode: PresentMode::AutoNoVsync,40resolution: WindowResolution::new(1920, 1080).with_scale_factor_override(1.0),41..default()42}),43..default()44}),45))46.insert_resource(WinitSettings::continuous())47.add_systems(Startup, setup)48.add_systems(49Update,50(print_sprite_count, move_camera.after(print_sprite_count)),51)52.run();53}5455fn setup(mut commands: Commands, assets: Res<AssetServer>, color_tint: Res<ColorTint>) {56warn!(include_str!("warning_string.txt"));5758let mut rng = rand::rng();5960let tile_size = Vec2::splat(64.0);61let map_size = Vec2::splat(320.0);6263let half_x = (map_size.x / 2.0) as i32;64let half_y = (map_size.y / 2.0) as i32;6566let sprite_handle = assets.load("branding/icon.png");6768// Spawns the camera6970commands.spawn(Camera2d);7172// Builds and spawns the sprites73let mut sprites = vec![];74for y in -half_y..half_y {75for x in -half_x..half_x {76let position = Vec2::new(x as f32, y as f32);77let translation = (position * tile_size).extend(rng.random::<f32>());78let rotation = Quat::from_rotation_z(rng.random::<f32>());79let scale = Vec3::splat(rng.random::<f32>() * 2.0);8081sprites.push((82SpriteMesh {83image: sprite_handle.clone(),84custom_size: Some(tile_size),85color: if color_tint.0 {86COLORS[rng.random_range(0..3)]87} else {88Color::WHITE89},90..default()91},92Transform {93translation,94rotation,95scale,96},97));98}99}100commands.spawn_batch(sprites);101}102103// System for rotating and translating the camera104fn move_camera(time: Res<Time>, mut camera_transform: Single<&mut Transform, With<Camera>>) {105camera_transform.rotate_z(time.delta_secs() * 0.5);106**camera_transform = **camera_transform107* Transform::from_translation(Vec3::X * CAMERA_SPEED * time.delta_secs());108}109110#[derive(Deref, DerefMut)]111struct PrintingTimer(Timer);112113impl Default for PrintingTimer {114fn default() -> Self {115Self(Timer::from_seconds(1.0, TimerMode::Repeating))116}117}118119// System for printing the number of sprites on every tick of the timer120fn print_sprite_count(121time: Res<Time>,122mut timer: Local<PrintingTimer>,123sprites: Query<&SpriteMesh>,124) {125timer.tick(time.delta());126127if timer.just_finished() {128info!("Sprites: {}", sprites.iter().count());129}130}131132133