From 4ba6fecc27259f66572d8ae30e5f6b73c6f1485f Mon Sep 17 00:00:00 2001 From: StephenAdamson Date: Sat, 8 Feb 2025 00:23:49 +0000 Subject: [PATCH] batch sprite 1 --- assets/default.png | Bin 0 -> 649 bytes src/citizen.rs | 13 ++-- src/main.rs | 41 +++++------ src/tile.rs | 4 +- src/tilemap.rs | 28 ++++---- src/tiles.rs | 171 +++++++++++++++++++++++++++++---------------- 6 files changed, 151 insertions(+), 106 deletions(-) create mode 100644 assets/default.png diff --git a/assets/default.png b/assets/default.png new file mode 100644 index 0000000000000000000000000000000000000000..59b7c150fa3856fafa2d334b5c12d4cdd267bc44 GIT binary patch literal 649 zcmV;40(Sk0P)EX>4Tx04R}tkv&MmKpe$iQ>7x64rUN>$WWcyMMWG-6^me@v=v%)FuC*#ni!H4 z7e~Rh;NZt%)xpJCR|i)?5c~jf7n~Gbq{ROvg%&X$9QWhhy~o`Q>B~8;(;Pzzi%25_2?`php$;2yT6Iz^WNAO?;~#bX8FDG)s)3PX z9vjdgyMFLL_}#5lo|^QM!bzb2#c@8yfzU3{ZaU8QvE#H)fZ#K5rFZ=sEnxPO^k!F! z9s!YU;NrTgDSN=>4lwd$$foQ{L7GCj47{JwHx+^5TVQb2>#eho(+40=T`k=J2Zz8! zg|gRt-aXLU+rMWz{rv!(9dfszqZcgz000SaNLh0L04^f{04^f|c%?sf00007bV*G` z2k8O_6fPt-qitdU000?uMObu0Z*6U5Zgc=ca%Ew3Wn>_CX>@2HM@dakSAh-}0001V zNklnN zA2Vw}^W2-WzCdH{^#hb) { // Spawn a handful of citizens for _ in 0..5 { - let x: f32 = rng.gen_range(-8.0..8.0); - let y: f32 = rng.gen_range(-8.0..8.0); + let x: f32 = rng.random_range(-8.0..8.0); + let y: f32 = rng.random_range(-8.0..8.0); let mut position = Vec3::new(x.round(), y.round(), 30.0) * TILE_SIZE; position.z += 0.1; diff --git a/src/main.rs b/src/main.rs index 97b6ea9..e3972b1 100644 --- a/src/main.rs +++ b/src/main.rs @@ -20,14 +20,16 @@ use bevy::diagnostic::FrameTimeDiagnosticsPlugin; fn main() { App::new() .insert_resource(game::ZIndex(0.0)) - .add_systems(Startup, tiles::initialize_textures) + .insert_resource(tiles::CurrentWorldSpriteState { + state: tiles::WorldSpriteState::Inactive, + }) + .add_systems(PreStartup, tiles::initialize_textures) .add_plugins( DefaultPlugins .set(WindowPlugin { primary_window: Some(Window { title: String::from("Dorf"), - resizable: false, - mode: WindowMode::BorderlessFullscreen(MonitorSelection::Primary), + // mode: WindowMode::BorderlessFullscreen(MonitorSelection::Primary), ..Default::default() }), ..Default::default() @@ -51,29 +53,24 @@ fn main() { ( // camera::camera_movement, cursor::move_cursor, - // citizen::check_citizen_positions_for_chunks, + tiles::build_world_sprites, + tile::update_tile_visibility.run_if(|cwss: Res| { + cwss.state == tiles::WorldSpriteState::RenderReady + }), ), ) .init_resource::() - .add_systems( - Update, - ( - // tile::camera_z_movement, - tile::update_tile_visibility - .run_if(|camera_moved: Res| camera_moved.0), - // log_fps_system, - ), - ) + // .add_systems( + // Update, + // ( + // tile::camera_z_movement, + // tile::update_tile_visibility + // .run_if(|camera_moved: Res| camera_moved.0), + // log_fps_system, + // ), + // ) .init_resource::() - .add_systems( - Update, - ( - start_recording_system, - record_diagnostics_system, - tile::update_tile_visibility - .run_if(|camera_moved: Res| camera_moved.0), - ), - ) + .add_systems(Update, (start_recording_system, record_diagnostics_system)) .run(); } diff --git a/src/tile.rs b/src/tile.rs index 164212a..d192733 100644 --- a/src/tile.rs +++ b/src/tile.rs @@ -1,10 +1,9 @@ -use crate::game; +use crate::{game, tiles}; use bevy::ecs::system::ParamSet; use bevy::prelude::*; use std::collections::HashMap; #[derive(Component, Clone)] -#[require(Sprite)] pub struct FloorTile { pub id: u32, pub opaque: bool, @@ -76,6 +75,7 @@ pub struct TileMap { pub fixture_tiles: HashMap, } +//TODO, redo pub fn update_tile_visibility( z_index: ResMut, mut query_set: ParamSet<( diff --git a/src/tilemap.rs b/src/tilemap.rs index b714036..bacb984 100644 --- a/src/tilemap.rs +++ b/src/tilemap.rs @@ -1,7 +1,8 @@ use crate::constants::{ITILE_SIZE, TILE_SIZE}; use crate::tile::{self, FixtureTile, FloorTile, NeedsOccluded, TileMap}; -use crate::tiles::{FixtureTilePrefab, FloorTilePrefab, Textures}; +use crate::tiles::{self, FixtureTilePrefab, FloorTilePrefab, Textures}; use bevy::prelude::*; +use bevy::text::cosmic_text::ttf_parser::gpos::PositioningSubtable; use noise::{NoiseFn, Perlin}; use std::collections::HashMap; @@ -38,6 +39,7 @@ pub fn handle_tile_occlusion_updates( Query<(&mut FixtureTile, &Transform, &mut NeedsOccluded)>, Query<(Entity, &mut NeedsOccluded)>, )>, + mut cwss: ResMut, ) { query_set .p0() @@ -68,6 +70,7 @@ pub fn handle_tile_occlusion_updates( commands.entity(entity).remove::(); } } + cwss.state = tiles::WorldSpriteState::WaitingForRender; } pub fn calculate_visibility(pos: IVec3, tilemap: &TileMap) -> [u32; 8] { @@ -211,19 +214,19 @@ fn handle_chunk_loading( z as f64 * 0.05, ]); if noise_value < -0.5 { - FloorTilePrefab::air(position, &textures).spawn(&mut commands); + FloorTilePrefab::air(position).spawn(&mut commands); tilemap .floor_tiles .insert(pos_ivec, (0, false, true, 0, [0; 8])); // Air tile floor_positions.push((position, "air")); } else if noise_value < 0.8 { - FloorTilePrefab::rock(position, &textures).spawn(&mut commands); + FloorTilePrefab::rock(position).spawn(&mut commands); tilemap .floor_tiles .insert(pos_ivec, (2, true, false, 50, [0; 8])); // Rock tile floor_positions.push((position, "rock")); } else { - FloorTilePrefab::dirt(position, &textures).spawn(&mut commands); + FloorTilePrefab::dirt(position).spawn(&mut commands); tilemap .floor_tiles .insert(pos_ivec, (1, true, true, 85, [0; 8])); // Dirt tile @@ -233,20 +236,20 @@ fn handle_chunk_loading( if (generate_surface_noise(world_x, world_y) * TILE_SIZE).round() <= position.z + TILE_SIZE { - FloorTilePrefab::grass(position, &textures).spawn(&mut commands); + FloorTilePrefab::grass(position).spawn(&mut commands); tilemap .floor_tiles .insert(pos_ivec, (1, true, true, 100, [0; 8])); // Dirt tile (grass) floor_positions.push((position, "dirt")); } else { - FloorTilePrefab::dirt(position, &textures).spawn(&mut commands); + FloorTilePrefab::dirt(position).spawn(&mut commands); tilemap .floor_tiles .insert(pos_ivec, (1, true, true, 85, [0; 8])); // Dirt tile floor_positions.push((position, "dirt")); } } else { - FloorTilePrefab::air(position, &textures).spawn(&mut commands); + FloorTilePrefab::air(position).spawn(&mut commands); tilemap .floor_tiles .insert(pos_ivec, (0, false, true, 0, [0; 8])); // Air tile @@ -263,17 +266,17 @@ fn handle_chunk_loading( match *floor_type { "dirt" => { - FixtureTilePrefab::dirt_wall(above_pos, &textures).spawn(&mut commands); + FixtureTilePrefab::dirt_wall(above_pos).spawn(&mut commands); tilemap.fixture_tiles.insert(above_ivec, (1, true, [0; 8])); // Dirt wall } "rock" => { - FixtureTilePrefab::rock_wall(above_pos, &textures).spawn(&mut commands); + FixtureTilePrefab::rock_wall(above_pos).spawn(&mut commands); tilemap.fixture_tiles.insert(above_ivec, (2, true, [0; 8])); // Rock wall } "bedrock" => { - FixtureTilePrefab::bedrock_wall(above_pos, &textures).spawn(&mut commands); + FixtureTilePrefab::bedrock_wall(above_pos).spawn(&mut commands); tilemap.fixture_tiles.insert(above_ivec, (3, true, [0; 8])); // Bedrock wall } @@ -310,9 +313,6 @@ impl Plugin for TilemapPlugin { ) .chain(), ) - .add_systems( - FixedUpdate, - (handle_chunk_loading, handle_tile_occlusion_updates).chain(), - ); + .add_systems(FixedUpdate, (handle_chunk_loading).chain()); } } diff --git a/src/tiles.rs b/src/tiles.rs index ef5289c..5330d87 100644 --- a/src/tiles.rs +++ b/src/tiles.rs @@ -1,47 +1,133 @@ +use std::process::exit; + use crate::constants::*; use crate::tile::{FixtureTile, FloorTile, NeedsOccluded, TileState}; -use bevy::prelude::*; use bevy::utils::HashMap; +use bevy::{prelude::*, transform}; #[derive(Resource)] pub struct Textures { pub handles: HashMap>, } +#[derive(Resource)] +pub struct TextureIDs { + pub refs: HashMap, +} + +const FLOOR_ID_OFFSET: u32 = 0; +const FIXTURE_ID_OFFSET: u32 = 500000; + +pub const DEFAULT_TEXTURE: &str = "default.png"; + +const GRASS_FLOOR_PATH: &str = "grass_floor.png"; +const DIRT_FLOOR_PATH: &str = "dirt_floor.png"; +const ROCK_FLOOR_PATH: &str = "rock_floor.png"; +const BEDROCK_FLOOR_PATH: &str = "bedrock_floor.png"; +const SKY_PATH: &str = "sky.png"; +const DIRT_WALL_PATH: &str = "dirt_wall.png"; +const ROCK_WALL_PATH: &str = "rock_wall.png"; +const BEDROCK_WALL_PATH: &str = "bedrock_wall.png"; + pub fn initialize_textures(mut commands: Commands, asset_server: Res) { - let mut textures = HashMap::new(); + let mut textures: HashMap> = HashMap::new(); + let mut texture_ids: HashMap = HashMap::new(); + texture_ids.insert(u32::MAX, DEFAULT_TEXTURE.to_string()); + + texture_ids.insert(FLOOR_ID_OFFSET + 0, SKY_PATH.to_string()); + textures.insert(SKY_PATH.to_string(), asset_server.load(SKY_PATH)); + texture_ids.insert(FLOOR_ID_OFFSET + 1, GRASS_FLOOR_PATH.to_string()); textures.insert( - "grass_floor".to_string(), - asset_server.load("grass_floor.png"), + GRASS_FLOOR_PATH.to_string(), + asset_server.load(GRASS_FLOOR_PATH), ); + texture_ids.insert(FLOOR_ID_OFFSET + 2, DIRT_FLOOR_PATH.to_string()); textures.insert( - "dirt_floor".to_string(), - asset_server.load("dirt_floor.png"), + DIRT_FLOOR_PATH.to_string(), + asset_server.load(DIRT_FLOOR_PATH), ); + texture_ids.insert(FLOOR_ID_OFFSET + 3, ROCK_FLOOR_PATH.to_string()); textures.insert( - "rock_floor".to_string(), - asset_server.load("rock_floor.png"), + ROCK_FLOOR_PATH.to_string(), + asset_server.load(ROCK_FLOOR_PATH), ); + texture_ids.insert(FLOOR_ID_OFFSET + 4, BEDROCK_FLOOR_PATH.to_string()); textures.insert( - "bedrock_floor".to_string(), - asset_server.load("bedrock_floor.png"), + BEDROCK_FLOOR_PATH.to_string(), + asset_server.load(BEDROCK_FLOOR_PATH), ); - textures.insert("sky".to_string(), asset_server.load("sky.png")); - textures.insert("dirt_wall".to_string(), asset_server.load("dirt_wall.png")); - textures.insert("rock_wall".to_string(), asset_server.load("rock_wall.png")); + + texture_ids.insert(FIXTURE_ID_OFFSET + 1, DIRT_WALL_PATH.to_string()); textures.insert( - "bedrock_wall".to_string(), - asset_server.load("bedrock_wall.png"), + DIRT_WALL_PATH.to_string(), + asset_server.load(DIRT_WALL_PATH), + ); + texture_ids.insert(FIXTURE_ID_OFFSET + 2, ROCK_WALL_PATH.to_string()); + textures.insert( + ROCK_WALL_PATH.to_string(), + asset_server.load(ROCK_WALL_PATH), + ); + texture_ids.insert(FIXTURE_ID_OFFSET + 3, BEDROCK_WALL_PATH.to_string()); + textures.insert( + BEDROCK_WALL_PATH.to_string(), + asset_server.load(BEDROCK_WALL_PATH), ); // Insert the textures resource into the world commands.insert_resource(Textures { handles: textures }); + commands.insert_resource(TextureIDs { refs: texture_ids }); +} + +#[derive(Debug, PartialEq)] +pub enum WorldSpriteState { + Inactive, + WaitingForRender, + InProgress, + RenderReady, +} + +#[derive(Resource)] +pub struct CurrentWorldSpriteState { + pub state: WorldSpriteState, +} +use std::time::Instant; + +pub fn build_world_sprites( + mut query: Query<(&FloorTile, &Transform)>, + mut commands: Commands, + mut cwss: ResMut, + textures: Res, + texture_ids: Res, +) { + if cwss.state != WorldSpriteState::WaitingForRender { + return; + } + let now = Instant::now(); + if cwss.state == WorldSpriteState::WaitingForRender { + cwss.state = WorldSpriteState::InProgress; + // async/thread this so we don't block the main thread + + for (floortile, transform) in query.iter_mut() { + let id = floortile.id; + let texture_id = texture_ids.refs.get(&id).unwrap(); + let texture = textures.handles.get(texture_id).unwrap(); + let sprite = Sprite { + image: texture.clone(), + ..Default::default() + }; + commands.spawn((sprite, *transform)); + } + cwss.state = WorldSpriteState::RenderReady; + } + println!("{:?}", cwss.state); + let elapsed = now.elapsed(); + println!("Elapsed: {:.2?}", elapsed); + // exit(0); } #[derive(Bundle)] pub struct FloorTilePrefab { transform: Transform, - sprite: Sprite, tile: FloorTile, tile_state: TileState, visibility: Visibility, @@ -49,13 +135,9 @@ pub struct FloorTilePrefab { } impl FloorTilePrefab { - pub fn grass(position: Vec3, textures: &Res) -> Self { + pub fn grass(position: Vec3) -> Self { FloorTilePrefab { transform: Transform::from_translation(position).with_scale(Vec3::splat(PIXEL_RATIO)), - sprite: Sprite { - image: textures.handles.get("grass_floor").unwrap().clone(), - ..Default::default() - }, tile: FloorTile { id: 1, astar_weight: 100, @@ -71,13 +153,9 @@ impl FloorTilePrefab { } } - pub fn dirt(position: Vec3, textures: &Res) -> Self { + pub fn dirt(position: Vec3) -> Self { FloorTilePrefab { transform: Transform::from_translation(position).with_scale(Vec3::splat(PIXEL_RATIO)), - sprite: Sprite { - image: textures.handles.get("dirt_floor").unwrap().clone(), - ..Default::default() - }, tile: FloorTile { id: 2, astar_weight: 85, @@ -93,13 +171,9 @@ impl FloorTilePrefab { } } - pub fn rock(position: Vec3, textures: &Res) -> Self { + pub fn rock(position: Vec3) -> Self { FloorTilePrefab { transform: Transform::from_translation(position).with_scale(Vec3::splat(PIXEL_RATIO)), - sprite: Sprite { - image: textures.handles.get("rock_floor").unwrap().clone(), - ..Default::default() - }, tile: FloorTile { id: 3, astar_weight: 50, @@ -115,13 +189,9 @@ impl FloorTilePrefab { } } - pub fn air(position: Vec3, textures: &Res) -> Self { + pub fn air(position: Vec3) -> Self { FloorTilePrefab { transform: Transform::from_translation(position).with_scale(Vec3::splat(PIXEL_RATIO)), - sprite: Sprite { - image: textures.handles.get("sky").unwrap().clone(), - ..Default::default() - }, tile: FloorTile { id: 0, opaque: false, @@ -138,13 +208,9 @@ impl FloorTilePrefab { } } - pub fn bedrock(position: Vec3, textures: &Res) -> Self { + pub fn bedrock(position: Vec3) -> Self { FloorTilePrefab { transform: Transform::from_translation(position).with_scale(Vec3::splat(PIXEL_RATIO)), - sprite: Sprite { - image: textures.handles.get("bedrock_floor").unwrap().clone(), - ..Default::default() - }, tile: FloorTile { id: 4, astar_weight: 150, @@ -164,7 +230,6 @@ impl FloorTilePrefab { commands.spawn(( self.tile, self.transform, - self.sprite, self.tile_state, self.visibility, self.needs_occluded, @@ -175,22 +240,17 @@ impl FloorTilePrefab { #[derive(Bundle)] pub struct FixtureTilePrefab { transform: Transform, - sprite: Sprite, tile: FixtureTile, visibility: Visibility, needs_occluded: NeedsOccluded, } impl FixtureTilePrefab { - pub fn dirt_wall(position: Vec3, textures: &Res) -> Self { + pub fn dirt_wall(position: Vec3) -> Self { FixtureTilePrefab { transform: Transform::from_translation(position).with_scale(Vec3::splat(PIXEL_RATIO)), - sprite: Sprite { - image: textures.handles.get("dirt_wall").unwrap().clone(), - ..Default::default() - }, tile: FixtureTile { - id: 1, + id: FIXTURE_ID_OFFSET + 1, ..Default::default() }, visibility: Visibility::Hidden, @@ -200,13 +260,9 @@ impl FixtureTilePrefab { } } - pub fn rock_wall(position: Vec3, textures: &Res) -> Self { + pub fn rock_wall(position: Vec3) -> Self { FixtureTilePrefab { transform: Transform::from_translation(position).with_scale(Vec3::splat(PIXEL_RATIO)), - sprite: Sprite { - image: textures.handles.get("rock_wall").unwrap().clone(), - ..Default::default() - }, tile: FixtureTile { id: 2, ..Default::default() @@ -218,13 +274,9 @@ impl FixtureTilePrefab { } } - pub fn bedrock_wall(position: Vec3, textures: &Res) -> Self { + pub fn bedrock_wall(position: Vec3) -> Self { FixtureTilePrefab { transform: Transform::from_translation(position).with_scale(Vec3::splat(PIXEL_RATIO)), - sprite: Sprite { - image: textures.handles.get("bedrock_wall").unwrap().clone(), - ..Default::default() - }, tile: FixtureTile { id: 0, ..Default::default() @@ -240,7 +292,6 @@ impl FixtureTilePrefab { commands.spawn(( self.tile, self.transform, - self.sprite, self.visibility, self.needs_occluded, ));