diff --git a/src/main.rs b/src/main.rs index f0f2f69..d6d3970 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,23 +1,10 @@ mod audio; mod player; mod camera; +mod world; -use bevy::{ - asset::LoadState, - window::{ - Window, - WindowMode, - PrimaryWindow, - CursorGrabMode, - }, - core_pipeline::Skybox, - prelude::*, - render::{ - render_resource::{TextureViewDescriptor, TextureViewDimension}, - renderer::RenderDevice, - texture::CompressedImageFormats, - }, -}; +use bevy::window::{Window, WindowMode, PrimaryWindow, CursorGrabMode }; +use bevy::prelude::*; fn main() { App::new() @@ -25,116 +12,27 @@ fn main() { setup, audio::setup, player::setup, + world::setup, )) .add_systems(Update, ( - asset_loaded.after(load_cubemap_asset), handle_input, audio::toggle_bgm, + world::asset_loaded.after(world::load_cubemap_asset), )) .add_plugins(DefaultPlugins.set(ImagePlugin::default_nearest())) .add_plugins(camera::CameraControllerPlugin) .run(); } -#[derive(Resource)] -struct Cubemap { - is_loaded: bool, - index: usize, - image_handle: Handle, -} - -const CUBEMAPS: &[(&str, CompressedImageFormats)] = &[ - ( - "textures/stars_cubemap.png", - CompressedImageFormats::NONE, - ), -]; - - fn setup( - mut commands: Commands, - asset_server: Res, + //mut commands: Commands, mut windows: Query<&mut Window, With> ) { - let skybox_handle = asset_server.load(CUBEMAPS[0].0); for mut window in &mut windows { window.cursor.grab_mode = CursorGrabMode::Locked; window.cursor.visible = false; window.mode = WindowMode::Fullscreen; } - - // camera - commands.spawn(( - Camera3dBundle { - transform: Transform::from_xyz(0.0, 0.0, 8.0).looking_at(Vec3::ZERO, Vec3::Y), - ..default() - }, - camera::CameraController::default(), - Skybox { - image: skybox_handle.clone(), - brightness: 150.0, - }, - )); - commands.insert_resource(Cubemap { - is_loaded: false, - index: 0, - image_handle: skybox_handle, - }); -} - -fn load_cubemap_asset( - mut cubemap: ResMut, - asset_server: Res, - render_device: Res, -) { - let supported_compressed_formats = - CompressedImageFormats::from_features(render_device.features()); - - let mut new_index = cubemap.index; - for _ in 0..CUBEMAPS.len() { - new_index = (new_index + 1) % CUBEMAPS.len(); - if supported_compressed_formats.contains(CUBEMAPS[new_index].1) { - break; - } - info!("Skipping unsupported format: {:?}", CUBEMAPS[new_index]); - } - - // Skip swapping to the same texture. Useful for when ktx2, zstd, or compressed texture support - // is missing - if new_index == cubemap.index { - return; - } - - cubemap.index = new_index; - cubemap.image_handle = asset_server.load(CUBEMAPS[cubemap.index].0); - cubemap.is_loaded = false; -} - -fn asset_loaded( - asset_server: Res, - mut images: ResMut>, - mut cubemap: ResMut, - mut skyboxes: Query<&mut Skybox>, -) { - if !cubemap.is_loaded && asset_server.load_state(&cubemap.image_handle) == LoadState::Loaded { - info!("Swapping to {}...", CUBEMAPS[cubemap.index].0); - let image = images.get_mut(&cubemap.image_handle).unwrap(); - // NOTE: PNGs do not have any metadata that could indicate they contain a cubemap texture, - // so they appear as one texture. The following code reconfigures the texture as necessary. - if image.texture_descriptor.array_layer_count() == 1 { - image.reinterpret_stacked_2d_as_array(image.height() / image.width()); - image.texture_view_descriptor = Some(TextureViewDescriptor { - dimension: Some(TextureViewDimension::Cube), - ..default() - }); - } - - for mut skybox in &mut skyboxes { - skybox.image = cubemap.image_handle.clone(); - } - - cubemap.is_loaded = true; - } } fn handle_input( diff --git a/src/world.rs b/src/world.rs new file mode 100644 index 0000000..5f60f69 --- /dev/null +++ b/src/world.rs @@ -0,0 +1,108 @@ +use crate::camera; +use bevy::prelude::*; +use bevy::core_pipeline::Skybox; +use bevy::asset::LoadState; +use bevy::render::{ + render_resource::{TextureViewDescriptor, TextureViewDimension}, + renderer::RenderDevice, + texture::CompressedImageFormats, +}; + +#[derive(Resource)] +pub struct Cubemap { + is_loaded: bool, + index: usize, + image_handle: Handle, +} + +const CUBEMAPS: &[(&str, CompressedImageFormats)] = &[ + ( + "textures/stars_cubemap.png", + CompressedImageFormats::NONE, + ), +]; + +pub fn setup( + mut commands: Commands, + asset_server: Res, +) { + let skybox_handle = asset_server.load(CUBEMAPS[0].0); + commands.spawn(( + Camera3dBundle { + transform: Transform::from_xyz(0.0, 0.0, 8.0).looking_at(Vec3::ZERO, Vec3::Y), + ..default() + }, + camera::CameraController::default(), + Skybox { + image: asset_server.load(CUBEMAPS[0].0).clone(), + brightness: 150.0, + }, + )); + commands.spawn(( + Skybox { + image: skybox_handle.clone(), + brightness: 150.0, + }, + )); + commands.insert_resource(Cubemap { + is_loaded: false, + index: 0, + image_handle: skybox_handle, + }); +} + +pub fn load_cubemap_asset( + mut cubemap: ResMut, + asset_server: Res, + render_device: Res, +) { + let supported_compressed_formats = + CompressedImageFormats::from_features(render_device.features()); + + let mut new_index = cubemap.index; + for _ in 0..CUBEMAPS.len() { + new_index = (new_index + 1) % CUBEMAPS.len(); + if supported_compressed_formats.contains(CUBEMAPS[new_index].1) { + break; + } + info!("Skipping unsupported format: {:?}", CUBEMAPS[new_index]); + } + + // Skip swapping to the same texture. Useful for when ktx2, zstd, or compressed texture support + // is missing + if new_index == cubemap.index { + return; + } + + cubemap.index = new_index; + cubemap.image_handle = asset_server.load(CUBEMAPS[cubemap.index].0); + cubemap.is_loaded = false; +} + + +pub fn asset_loaded( + asset_server: Res, + mut images: ResMut>, + mut cubemap: ResMut, + mut skyboxes: Query<&mut Skybox>, +) { + if !cubemap.is_loaded && asset_server.load_state(&cubemap.image_handle) == LoadState::Loaded { + info!("Swapping to {}...", CUBEMAPS[cubemap.index].0); + let image = images.get_mut(&cubemap.image_handle).unwrap(); + // NOTE: PNGs do not have any metadata that could indicate they contain a cubemap texture, + // so they appear as one texture. The following code reconfigures the texture as necessary. + if image.texture_descriptor.array_layer_count() == 1 { + image.reinterpret_stacked_2d_as_array(image.height() / image.width()); + image.texture_view_descriptor = Some(TextureViewDescriptor { + dimension: Some(TextureViewDimension::Cube), + ..default() + }); + } + + for mut skybox in &mut skyboxes { + skybox.image = cubemap.image_handle.clone(); + } + + cubemap.is_loaded = true; + } +}