Add more windows, move rendering logic

This commit is contained in:
Tobias Berger 2022-11-08 21:46:32 +01:00
parent 23eed81343
commit a38cafc7b8
Signed by: toby
GPG key ID: 2D05EFAB764D6A88
14 changed files with 321 additions and 174 deletions

View file

@ -6,7 +6,7 @@ cargo build --no-default-features --features=logging &&
echo "Debug-build with features: render" && echo "Debug-build with features: render" &&
cargo build --no-default-features --features=render && cargo build --no-default-features --features=render &&
echo "Debug-build with features: logging render" && echo "Debug-build with features: logging render" &&
cargo build --no-default-features --features=logging,render && cargo build --no-default-features --features="logging,render" &&
echo "Release-build with features: minimal" echo "Release-build with features: minimal"
cargo build --release --no-default-features --features= && cargo build --release --no-default-features --features= &&
echo "Release-build with features: logging" && echo "Release-build with features: logging" &&
@ -14,5 +14,5 @@ cargo build --release --no-default-features --features=logging &&
echo "Release-build with features: render" && echo "Release-build with features: render" &&
cargo build --release --no-default-features --features=render && cargo build --release --no-default-features --features=render &&
echo "Release-build with features: logging render" && echo "Release-build with features: logging render" &&
cargo build --release --no-default-features --features=logging,render && cargo build --release --no-default-features --features="logging,render" &&
echo "Done!" echo "Done!"

View file

@ -41,4 +41,8 @@ pub use world_manager::WorldManager;
pub(crate) mod macros; pub(crate) mod macros;
pub mod math_util; pub mod math_util;
pub mod perlin; pub mod perlin;
#[cfg(feature = "render")]
pub mod rendering;
#[cfg(feature = "render")]
pub use rendering::*;
pub mod saving; pub mod saving;

View file

@ -1,7 +1,7 @@
macro_rules! iterable_enum { macro_rules! iterable_enum {
($Name:ident { $($Variant:ident),*$(,)? }) => ($Name:ident { $($Variant:ident),*$(,)? }) =>
{ {
#[derive(Debug, Copy, Clone, Eq, PartialEq, serde::Deserialize, serde::Serialize)] #[derive(Debug, Copy, Clone, Eq, PartialEq, Hash, serde::Deserialize, serde::Serialize)]
pub enum $Name { pub enum $Name {
$($Variant),*, $($Variant),*,
} }
@ -13,6 +13,20 @@ macro_rules! iterable_enum {
$Name::ITEMS.iter() $Name::ITEMS.iter()
} }
} }
impl From<$Name> for &'static str {
fn from(value: $Name) -> &'static str {
match value {
$($Name::$Variant => stringify!($Variant),)*
}
}
}
impl From<&$Name> for &'static str {
fn from(value: &$Name) -> &'static str {
match value {
$($Name::$Variant => stringify!($Variant),)*
}
}
}
} }
} }
pub(crate) use iterable_enum; pub(crate) use iterable_enum;

View file

@ -0,0 +1,45 @@
#[cfg(feature = "render")]
use bevy::asset::HandleId;
use {crate::macros::iterable_enum, bevy::utils::HashSet};
iterable_enum!(WorldView { Biomes, Topography });
iterable_enum!(WorldOverlay {
Temperature,
Rainfall
});
#[cfg(feature = "render")]
#[derive(Debug, Default)]
pub struct WorldRenderSettings {
pub map_image_handle_id: Option<HandleId>,
visible_overlays: HashSet<WorldOverlay>,
pub view: WorldView,
}
#[cfg(feature = "render")]
impl WorldRenderSettings {
pub fn overlay_visible(&self, overlay: &WorldOverlay) -> bool {
self.visible_overlays.contains(overlay)
}
pub fn toggle_overlay(&mut self, overlay: &WorldOverlay) {
if self.visible_overlays.contains(overlay) {
assert!(
self.visible_overlays.remove(overlay),
"Failed to remove overlay [{overlay:#?}], that shouldn't happen."
);
} else {
assert!(
self.visible_overlays.insert(*overlay),
"Failed to insert overlay [{overlay:#?}], that shouldn't happen."
);
}
}
}
impl Default for WorldView {
fn default() -> Self {
WorldView::Biomes
}
}

View file

@ -1,7 +1,14 @@
#[cfg(all(feature = "logging", feature = "render"))] #[cfg(feature = "render")]
use bevy::log::debug;
use { use {
crate::{macros::iterable_enum, World, WorldGenError}, crate::{BiomeStats, TerrainCell, WorldOverlay, WorldRenderSettings, WorldView},
bevy::{
asset::Assets,
render::render_resource::Extent3d,
render::{color::Color, texture::Image},
},
};
use {
crate::{World, WorldGenError},
bevy::{log::warn, utils::default}, bevy::{log::warn, utils::default},
rand::random, rand::random,
std::{ std::{
@ -12,15 +19,6 @@ use {
path::Path, path::Path,
}, },
}; };
#[cfg(feature = "render")]
use {
crate::{BiomeStats, TerrainCell},
bevy::{
asset::{Assets, HandleId},
render::render_resource::Extent3d,
render::{color::Color, texture::Image},
},
};
#[derive(Debug)] #[derive(Debug)]
pub enum LoadError { pub enum LoadError {
@ -85,71 +83,9 @@ impl Display for SaveError {
} }
} }
iterable_enum!(PlanetView { Biomes, Altitude });
#[cfg(feature = "render")]
#[derive(Debug, Default)]
pub struct WorldRenderSettings {
pub map_image_handle_id: Option<HandleId>,
rainfall_visible: bool,
temperature_visible: bool,
view: PlanetView,
}
#[cfg(feature = "render")]
impl WorldRenderSettings {
#[cfg(feature = "render")]
pub fn toggle_rainfall(&mut self) {
#[cfg(feature = "logging")]
if self.rainfall_visible {
debug!("Turning rainfall off");
} else {
debug!("Turning rainfall on");
}
self.rainfall_visible = !self.rainfall_visible;
}
#[cfg(feature = "render")]
pub fn toggle_temperature(&mut self) {
#[cfg(feature = "logging")]
if self.temperature_visible {
debug!("Turning temperature off");
} else {
debug!("Turning temperature on");
}
self.temperature_visible = !self.temperature_visible;
}
#[cfg(feature = "render")]
pub fn cycle_view(&mut self) {
let idx = (PlanetView::iterator()
.position(|view| *view == self.view)
.unwrap()
+ 1)
% PlanetView::ITEM_COUNT;
#[cfg(feature = "logging")]
debug!(
"Cycling view from {:#?} to {:#?}",
self.view,
PlanetView::ITEMS[idx]
);
self.view = PlanetView::ITEMS[idx];
}
}
impl Default for PlanetView {
fn default() -> Self {
PlanetView::Biomes
}
}
#[derive(Debug, Default)] #[derive(Debug, Default)]
pub struct WorldManager { pub struct WorldManager {
world: Option<World>, world: Option<World>,
#[cfg(feature = "render")]
pub render_settings: WorldRenderSettings,
} }
impl WorldManager { impl WorldManager {
@ -191,6 +127,7 @@ impl WorldManager {
pub fn load_world<P: AsRef<Path>>( pub fn load_world<P: AsRef<Path>>(
&mut self, &mut self,
path: P, path: P,
#[cfg(feature = "render")] render_settings: &WorldRenderSettings,
#[cfg(feature = "render")] images: &mut Assets<Image>, #[cfg(feature = "render")] images: &mut Assets<Image>,
) -> Result<(), LoadError> { ) -> Result<(), LoadError> {
let mut file = match File::open(path) { let mut file = match File::open(path) {
@ -214,7 +151,7 @@ impl WorldManager {
#[cfg(feature = "render")] #[cfg(feature = "render")]
{ {
let image_handle = &images.get_handle( let image_handle = &images.get_handle(
self.render_settings render_settings
.map_image_handle_id .map_image_handle_id
.expect("Missing image handle, even though world is present"), .expect("Missing image handle, even though world is present"),
); );
@ -264,8 +201,8 @@ impl WorldManager {
#[cfg(feature = "render")] #[cfg(feature = "render")]
#[must_use] #[must_use]
fn generate_color(&self, cell: &TerrainCell) -> Color { fn generate_color(&self, cell: &TerrainCell, render_settings: &WorldRenderSettings) -> Color {
if self.render_settings.view == PlanetView::Biomes { if render_settings.view == WorldView::Biomes {
return WorldManager::biome_color(cell); return WorldManager::biome_color(cell);
} }
@ -282,7 +219,7 @@ impl WorldManager {
let mut green = altitude_color.g(); let mut green = altitude_color.g();
let mut blue = altitude_color.b(); let mut blue = altitude_color.b();
if self.render_settings.rainfall_visible { if render_settings.overlay_visible(&WorldOverlay::Rainfall) {
layer_count += 1.0; layer_count += 1.0;
let rainfall_color = self.rainfall_contour_color(cell.rainfall); let rainfall_color = self.rainfall_contour_color(cell.rainfall);
// if self.contours { // if self.contours {
@ -296,7 +233,7 @@ impl WorldManager {
blue += rainfall_color.b(); blue += rainfall_color.b();
} }
if self.render_settings.temperature_visible { if render_settings.overlay_visible(&WorldOverlay::Temperature) {
layer_count += 1.0; layer_count += 1.0;
let temperature_color = self.temperature_contour_color(cell.temperature); let temperature_color = self.temperature_contour_color(cell.temperature);
// if self.contours { // if self.contours {
@ -399,14 +336,14 @@ impl WorldManager {
#[cfg(feature = "render")] #[cfg(feature = "render")]
#[must_use] #[must_use]
pub fn map_color_bytes(&self) -> Vec<u8> { pub fn map_color_bytes(&self, render_settings: &WorldRenderSettings) -> Vec<u8> {
self.world() self.world()
.terrain .terrain
.iter() .iter()
.rev() .rev()
.flatten() .flatten()
.flat_map(|cell| { .flat_map(|cell| {
self.generate_color(cell) self.generate_color(cell, render_settings)
.as_rgba_f32() .as_rgba_f32()
.iter() .iter()
.flat_map(|num| num.to_le_bytes()) .flat_map(|num| num.to_le_bytes())

View file

@ -10,18 +10,20 @@ use {
crate::gui::{open_window, WidgetId, WidgetSystem}, crate::gui::{open_window, WidgetId, WidgetSystem},
bevy::{ bevy::{
asset::Assets, asset::Assets,
ecs::change_detection::Mut,
log::debug, log::debug,
render::{render_resource::Extent3d, texture::Image}, render::{render_resource::Extent3d, texture::Image},
}, },
planet::WorldManager, planet::{WorldManager, WorldRenderSettings},
}; };
fn update_textures(world_manager: &WorldManager, images: &mut Mut<Assets<Image>>) { pub(crate) fn update_textures(
world_manager: &WorldManager,
render_settings: &WorldRenderSettings,
images: &mut Assets<Image>,
) {
debug!("refreshing world texture"); debug!("refreshing world texture");
let map_image_handle = images.get_handle( let map_image_handle = images.get_handle(
world_manager render_settings
.render_settings
.map_image_handle_id .map_image_handle_id
.expect("No map image handle"), .expect("No map image handle"),
); );
@ -33,5 +35,5 @@ fn update_textures(world_manager: &WorldManager, images: &mut Mut<Assets<Image>>
height: world_manager.world().height, height: world_manager.world().height,
depth_or_array_layers: 1, depth_or_array_layers: 1,
}); });
map_image.data = world_manager.map_color_bytes(); map_image.data = world_manager.map_color_bytes(render_settings);
} }

View file

@ -1,6 +1,12 @@
use { use {
crate::{ crate::{
gui::{open_window, update_textures, windows::Overlay, WidgetId, WidgetSystem}, gui::{
open_window,
update_textures,
windows::{SaveLoad, WorldOverlaySelection, WorldViewSelection},
WidgetId,
WidgetSystem,
},
macros::iterable_enum, macros::iterable_enum,
resources::OpenedWindows, resources::OpenedWindows,
}, },
@ -16,50 +22,48 @@ use {
render::texture::Image, render::texture::Image,
}, },
bevy_egui::egui::{Layout, Ui}, bevy_egui::egui::{Layout, Ui},
planet::WorldManager, planet::{WorldManager, WorldRenderSettings},
std::marker::PhantomData, std::marker::PhantomData,
}; };
iterable_enum!(ToolbarButton { iterable_enum!(ToolbarButton {
GenerateWorld, GenerateWorld,
SaveWorld, SaveLoad,
LoadWorld, Views,
Overlays, Overlays,
ToggleBiomes,
}); });
impl ToolbarButton { impl ToolbarButton {
fn clicked(self, world: &mut World) { fn clicked(self, world: &mut World) {
world.resource_scope(|world, mut world_manager: Mut<'_, WorldManager>| { world.resource_scope(|world, mut world_manager: Mut<'_, WorldManager>| {
match self { world.resource_scope(|world, render_settings: Mut<'_, WorldRenderSettings>| {
ToolbarButton::GenerateWorld => { match self {
if let Err(err) = world_manager.new_world() { ToolbarButton::GenerateWorld => {
eprintln!("Failed to generate world: {}", err); if let Err(err) = world_manager.new_world() {
} else { eprintln!("Failed to generate world: {}", err);
update_textures(&world_manager, &mut world.resource_mut::<Assets<Image>>()); } else {
} update_textures(
}, &world_manager,
ToolbarButton::SaveWorld => { &render_settings,
if let Err(err) = world_manager.save_world("planet.ron") { &mut world.resource_mut::<Assets<Image>>(),
eprintln!("Failed to save planet.ron: {}", err); );
} }
}, },
ToolbarButton::LoadWorld => { ToolbarButton::SaveLoad => {
let mut images = world.resource_mut::<Assets<Image>>(); open_window::<SaveLoad>(&mut world.resource_mut::<OpenedWindows>());
if let Err(err) = world_manager.load_world("planet.ron", &mut images) { },
eprintln!("Failed to load planet.ron: {}", err); ToolbarButton::Views => {
} else { open_window::<WorldViewSelection>(
update_textures(&world_manager, &mut images); &mut world.resource_mut::<OpenedWindows>(),
} );
}, },
ToolbarButton::Overlays => { ToolbarButton::Overlays => {
open_window::<Overlay>(&mut world.resource_mut::<OpenedWindows>()); open_window::<WorldOverlaySelection>(
}, &mut world.resource_mut::<OpenedWindows>(),
ToolbarButton::ToggleBiomes => { );
world_manager.render_settings.cycle_view(); },
update_textures(&world_manager, &mut world.resource_mut::<Assets<Image>>()); };
}, });
};
}); });
} }
} }
@ -67,11 +71,10 @@ impl ToolbarButton {
impl From<ToolbarButton> for &'static str { impl From<ToolbarButton> for &'static str {
fn from(button: ToolbarButton) -> Self { fn from(button: ToolbarButton) -> Self {
match button { match button {
ToolbarButton::Views => "Change view",
ToolbarButton::Overlays => "Overlays", ToolbarButton::Overlays => "Overlays",
ToolbarButton::ToggleBiomes => "Toggle biome view",
ToolbarButton::GenerateWorld => "Generate new world", ToolbarButton::GenerateWorld => "Generate new world",
ToolbarButton::SaveWorld => "Save", ToolbarButton::SaveLoad => "Save/Load",
ToolbarButton::LoadWorld => "Load",
} }
} }
} }

View file

@ -21,10 +21,13 @@ pub(crate) trait WindowSystem: SystemParam {
} }
pub(crate) fn render_windows(world: &mut World, ctx: &Context) { pub(crate) fn render_windows(world: &mut World, ctx: &Context) {
// TODO: Windows are hard-coded here instead of being iterable. // TODO: Windows are hard-coded here instead of being iterable, and allows
// Is that good enough? Probably, yea. // creating new windows that are never rendered.
window::<windows::Overlay>(world, ctx); // Is that good enough?
window::<windows::TileInfo>(world, ctx); window::<windows::TileInfo>(world, ctx);
window::<windows::WorldViewSelection>(world, ctx);
window::<windows::WorldOverlaySelection>(world, ctx);
window::<windows::SaveLoad>(world, ctx);
} }
pub(crate) fn open_window<S: 'static + WindowSystem>(windows: &mut OpenedWindows) { pub(crate) fn open_window<S: 'static + WindowSystem>(windows: &mut OpenedWindows) {

View file

@ -1,4 +1,8 @@
mod overlay;
pub(crate) use overlay::Overlay;
mod tile_info; mod tile_info;
pub(crate) use tile_info::TileInfo; pub(crate) use tile_info::TileInfo;
mod world_view_selection;
pub(crate) use world_view_selection::WorldViewSelection;
mod world_overlay_selection;
pub(crate) use world_overlay_selection::WorldOverlaySelection;
mod save_load;
pub(crate) use save_load::SaveLoad;

View file

@ -1,25 +0,0 @@
use {
crate::gui::WindowSystem,
bevy::ecs::{
system::{SystemParam, SystemState},
world::World,
},
bevy_egui::egui::Ui,
std::marker::PhantomData,
};
#[derive(SystemParam)]
pub(crate) struct Overlay<'w, 's> {
#[system_param(ignore)]
_phantom: PhantomData<(&'w (), &'s ())>,
}
impl WindowSystem for Overlay<'_, '_> {
fn draw_contents(world: &mut World, _state: &mut SystemState<Self>, ui: &mut Ui) {
ui.label(format!("{world:#?}"));
}
fn name() -> &'static str {
"Overlay Selection"
}
}

View file

@ -0,0 +1,57 @@
use {
crate::gui::WindowSystem,
bevy::{
ecs::{
change_detection::Mut,
system::{Local, SystemParam, SystemState},
world::World,
},
log::error,
prelude::{Assets, Image},
},
bevy_egui::egui::Ui,
planet::{WorldManager, WorldRenderSettings},
std::marker::PhantomData,
};
#[derive(SystemParam)]
pub(crate) struct SaveLoad<'w, 's> {
pub file_name: Local<'s, String>,
#[system_param(ignore)]
_phantom: PhantomData<(&'w (), &'s ())>,
}
impl WindowSystem for SaveLoad<'_, '_> {
fn draw_contents(world: &mut World, state: &mut SystemState<Self>, ui: &mut Ui) {
world.resource_scope(|world, mut world_manager: Mut<WorldManager>| {
world.resource_scope(|world, mut images: Mut<Assets<Image>>| {
world.resource_scope(|world, render_settings: Mut<WorldRenderSettings>| {
let mut state = state.get_mut(world);
// TODO: File selection dialog.
ui.text_edit_singleline(&mut *state.file_name);
if ui.button("Save").clicked() {
if let Err(err) = world_manager.save_world(&*state.file_name) {
// TODO: Error popup
error!("Failed to save: {err:#?}");
}
}
if ui.button("Load").clicked() {
if let Err(err) = world_manager.load_world(
&*state.file_name,
&render_settings,
&mut images,
) {
error!("Failed to load: {err:#?}");
}
}
});
});
});
}
fn name() -> &'static str {
"Save/Load world"
}
}

View file

@ -0,0 +1,50 @@
use {
crate::gui::{update_textures, WindowSystem},
bevy::{
asset::Assets,
ecs::{
change_detection::Mut,
system::{SystemParam, SystemState},
world::World,
},
render::texture::Image,
},
bevy_egui::egui::Ui,
planet::{WorldManager, WorldOverlay, WorldRenderSettings},
std::marker::PhantomData,
};
#[derive(SystemParam)]
pub(crate) struct WorldOverlaySelection<'w, 's> {
#[system_param(ignore)]
_phantom: PhantomData<(&'w (), &'s ())>,
}
impl WindowSystem for WorldOverlaySelection<'_, '_> {
fn draw_contents(world: &mut World, _state: &mut SystemState<Self>, ui: &mut Ui) {
world.resource_scope(|world, mut render_settings: Mut<WorldRenderSettings>| {
for overlay in WorldOverlay::iterator() {
if ui
.selectable_label(
render_settings.overlay_visible(overlay),
<&'static str>::from(overlay),
)
.clicked()
{
render_settings.toggle_overlay(overlay);
world.resource_scope(|world, mut images: Mut<Assets<Image>>| {
update_textures(
world.resource::<WorldManager>(),
&render_settings,
&mut images,
);
});
}
}
});
}
fn name() -> &'static str {
"Overlay Selection"
}
}

View file

@ -0,0 +1,50 @@
use {
crate::gui::{update_textures, WindowSystem},
bevy::{
asset::Assets,
ecs::{
change_detection::Mut,
system::{SystemParam, SystemState},
world::World,
},
render::texture::Image,
},
bevy_egui::egui::Ui,
planet::{WorldManager, WorldRenderSettings, WorldView},
std::marker::PhantomData,
};
#[derive(SystemParam)]
pub(crate) struct WorldViewSelection<'w, 's> {
#[system_param(ignore)]
_phantom: PhantomData<(&'w (), &'s ())>,
}
impl WindowSystem for WorldViewSelection<'_, '_> {
fn draw_contents(world: &mut World, _state: &mut SystemState<Self>, ui: &mut Ui) {
world.resource_scope(|world, mut render_settings: Mut<WorldRenderSettings>| {
let current_selection = render_settings.view;
for view in WorldView::iterator() {
let view = *view;
if ui
.selectable_label(view == current_selection, <&'static str>::from(view))
.clicked()
&& render_settings.view != view
{
render_settings.view = view;
world.resource_scope(|world, mut images: Mut<Assets<Image>>| {
update_textures(
world.resource::<WorldManager>(),
&render_settings,
&mut images,
);
});
}
}
});
}
fn name() -> &'static str {
"View Selection"
}
}

View file

@ -1,3 +1,5 @@
#![cfg_attr(not(feature = "logging"), windows_subsystem = "windows")]
pub(crate) mod components; pub(crate) mod components;
#[cfg(feature = "render")] #[cfg(feature = "render")]
pub(crate) mod gui; pub(crate) mod gui;
@ -35,13 +37,7 @@ use {
prelude::Vec2, prelude::Vec2,
render::{ render::{
camera::{Camera, RenderTarget}, camera::{Camera, RenderTarget},
render_resource::{ render_resource::{TextureDescriptor, TextureDimension, TextureFormat, TextureUsages},
Extent3d,
TextureDescriptor,
TextureDimension,
TextureFormat,
TextureUsages,
},
texture::{Image, ImageSettings}, texture::{Image, ImageSettings},
}, },
sprite::{Sprite, SpriteBundle}, sprite::{Sprite, SpriteBundle},
@ -54,7 +50,15 @@ use {
EguiContext, EguiContext,
}, },
components::panning::Pan2d, components::panning::Pan2d,
gui::{render_windows, widget, widgets::ToolbarWidget, window::open_window, windows::TileInfo}, gui::{
render_windows,
update_textures,
widget,
widgets::ToolbarWidget,
window::open_window,
windows::TileInfo,
},
planet::WorldRenderSettings,
resources::{CursorMapPosition, OpenedWindows}, resources::{CursorMapPosition, OpenedWindows},
}; };
@ -93,9 +97,10 @@ fn update_cursor_map_position(
#[cfg(feature = "render")] #[cfg(feature = "render")]
fn generate_graphics( fn generate_graphics(
mut commands: Commands<'_, '_>, mut commands: Commands<'_, '_>,
mut world_manager: ResMut<'_, WorldManager>, world_manager: ResMut<'_, WorldManager>,
mut images: ResMut<'_, Assets<Image>>, mut images: ResMut<'_, Assets<Image>>,
mut egui_context: ResMut<'_, EguiContext>, mut egui_context: ResMut<'_, EguiContext>,
mut render_settings: ResMut<'_, WorldRenderSettings>,
) { ) {
// Add Julia-Mono font to egui // Add Julia-Mono font to egui
{ {
@ -127,14 +132,10 @@ fn generate_graphics(
// Set up 2D map mode // Set up 2D map mode
{ {
let map_image_handle = images.add(Image { let map_image_handle = images.add(Image {
data: world_manager.map_color_bytes(), data: vec![],
texture_descriptor: TextureDescriptor { texture_descriptor: TextureDescriptor {
label: None, label: None,
size: Extent3d { size: default(),
width: world.width,
height: world.height,
..default()
},
dimension: TextureDimension::D2, dimension: TextureDimension::D2,
format: TextureFormat::Rgba32Float, format: TextureFormat::Rgba32Float,
mip_level_count: 1, mip_level_count: 1,
@ -143,14 +144,14 @@ fn generate_graphics(
}, },
..default() ..default()
}); });
world_manager.render_settings.map_image_handle_id = Some(map_image_handle.id); render_settings.map_image_handle_id = Some(map_image_handle.id);
_ = commands _ = commands
.spawn_bundle(Camera2dBundle::default()) .spawn_bundle(Camera2dBundle::default())
.insert(Pan2d::new()); .insert(Pan2d::new());
// TODO: Switch to egui // TODO: Switch to egui
_ = commands.spawn_bundle(SpriteBundle { _ = commands.spawn_bundle(SpriteBundle {
texture: images.get_handle(world_manager.render_settings.map_image_handle_id.unwrap()), texture: images.get_handle(map_image_handle.id),
sprite: Sprite { sprite: Sprite {
custom_size: Some(custom_sprite_size), custom_size: Some(custom_sprite_size),
..default() ..default()
@ -159,6 +160,7 @@ fn generate_graphics(
}); });
} }
update_textures(&world_manager, &render_settings, &mut images);
} }
#[cfg(feature = "render")] #[cfg(feature = "render")]
@ -222,6 +224,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
}) })
.insert_resource(CursorMapPosition::default()) .insert_resource(CursorMapPosition::default())
.insert_resource(OpenedWindows::default()) .insert_resource(OpenedWindows::default())
.insert_resource(WorldRenderSettings::default())
.add_startup_system(generate_graphics) .add_startup_system(generate_graphics)
.add_system(update_gui.exclusive_system()) .add_system(update_gui.exclusive_system())
.add_system(update_cursor_map_position) .add_system(update_cursor_map_position)