#![warn(absolute_paths_not_starting_with_crate)] // #![warn(box_pointers)] #![warn(elided_lifetimes_in_paths)] #![warn(explicit_outlives_requirements)] #![warn(keyword_idents)] #![warn(macro_use_extern_crate)] #![warn(meta_variable_misuse)] #![warn(missing_abi)] #![warn(missing_copy_implementations)] #![warn(missing_debug_implementations)] // #![warn(missing_docs)] #![warn(non_ascii_idents)] #![warn(noop_method_call)] #![warn(pointer_structural_match)] #![warn(rust_2021_incompatible_closure_captures)] #![warn(rust_2021_incompatible_or_patterns)] #![warn(rust_2021_prefixes_incompatible_syntax)] #![warn(rust_2021_prelude_collisions)] #![warn(single_use_lifetimes)] #![warn(trivial_casts)] #![warn(trivial_numeric_casts)] #![warn(unreachable_pub)] #![warn(unsafe_code)] #![warn(unsafe_op_in_unsafe_fn)] #![warn(unstable_features)] #![warn(unused_crate_dependencies)] #![warn(unused_extern_crates)] #![warn(unused_import_braces)] #![warn(unused_lifetimes)] #![warn(unused_macro_rules)] #![warn(unused_qualifications)] #![warn(unused_results)] #![warn(variant_size_differences)] use bevy::{ app::App, asset::Assets, core_pipeline::core_2d::Camera2dBundle, diagnostic::{FrameTimeDiagnosticsPlugin, LogDiagnosticsPlugin}, ecs::{ change_detection::ResMut, system::{Commands, Res}, }, hierarchy::BuildChildren, render::{ color::Color, render_resource::{ Extent3d, TextureDescriptor, TextureDimension, TextureFormat, TextureUsages, }, texture::{Image, ImageSettings}, }, ui::{ entity::{ImageBundle, NodeBundle}, Size, Style, UiImage, Val, }, utils::default, window::WindowDescriptor, winit::WinitSettings, DefaultPlugins, }; use save::*; fn get_color(cell: &TerrainCell) -> Color { let altitude_color = gen_altitude_color(cell.altitude); let rainfall_color = gen_rainfall_color(cell.rainfall); let normalized_rainfall = f32::max(cell.rainfall / World::MAX_RAINFALL, 0.0); let red = (altitude_color.r() * (1.0 - normalized_rainfall)) + rainfall_color.r() * normalized_rainfall; let green = (altitude_color.g() * (1.0 - normalized_rainfall)) + rainfall_color.g() * normalized_rainfall; let blue = (altitude_color.b() * (1.0 - normalized_rainfall)) + rainfall_color.b() * normalized_rainfall; Color::rgb(red, green, blue) } fn gen_altitude_color(altitude: f32) -> Color { if altitude < 0.0 { Color::BLUE } else { let mult = (altitude - World::MIN_ALTITUDE) / World::ALTITUDE_SPAN; Color::rgb(0.58 * mult, 0.29 * mult, 0.0) } } fn gen_rainfall_color(rainfall: f32) -> Color { if rainfall < 0.0 { Color::BLACK } else { let mult = rainfall / World::MAX_RAINFALL; Color::GREEN * mult } } fn generate_texture( mut commands: Commands<'_, '_>, mut images: ResMut<'_, Assets<Image>>, world_manager: Res<'_, WorldManager>, ) { let world = world_manager.get_world().unwrap(); let terrain_cells: Vec<_> = world.terrain.iter().rev().flatten().collect(); let colors: Vec<_> = terrain_cells.iter().map(|cell| get_color(cell)).collect(); let data: Vec<_> = colors .iter() .flat_map(|color| { color .as_rgba_f32() .iter() .flat_map(|num| num.to_le_bytes()) .collect::<Vec<u8>>() }) .collect(); let image_handle = images.add(Image { data, texture_descriptor: TextureDescriptor { label: None, size: Extent3d { width: world.width as u32, height: world.height as u32, ..default() }, dimension: TextureDimension::D2, format: TextureFormat::Rgba32Float, mip_level_count: 1, sample_count: 1, usage: TextureUsages::COPY_DST | TextureUsages::TEXTURE_BINDING, }, ..default() }); _ = commands.spawn_bundle(Camera2dBundle::default()); _ = commands .spawn_bundle(NodeBundle { style: Style { size: Size::new(Val::Percent(100.0), Val::Percent(100.0)), ..default() }, color: Color::NONE.into(), ..default() }) .with_children(|parent| { _ = parent.spawn_bundle(ImageBundle { style: Style { size: Size::new(Val::Percent(100.0), Val::Percent(100.0)), ..default() }, image: UiImage(image_handle), ..default() }); // }); }); } fn main() -> Result<(), Box<dyn std::error::Error>> { let mut manager = WorldManager::new(); let world = manager.new_world()?; App::new() // Only run the app when there is user input. This will significantly reduce CPU/GPU use. .insert_resource(WinitSettings::desktop_app()) // Use nearest-neighbor rendering for cripsier pixels .insert_resource(ImageSettings::default_nearest()) .insert_resource(WindowDescriptor { width: world.width as f32, height: world.height as f32, title: String::from("World-RS"), resizable: true, ..default() }) .insert_resource(manager) .add_startup_system(generate_texture) .add_plugins(DefaultPlugins) .add_plugin(LogDiagnosticsPlugin::default()) .add_plugin(FrameTimeDiagnosticsPlugin::default()) .run(); Ok(()) }