diff options
Diffstat (limited to 'engine/src/rendering')
| -rw-r--r-- | engine/src/rendering/main_pipeline.rs | 129 |
1 files changed, 66 insertions, 63 deletions
diff --git a/engine/src/rendering/main_pipeline.rs b/engine/src/rendering/main_pipeline.rs index 70f0682..0695800 100644 --- a/engine/src/rendering/main_pipeline.rs +++ b/engine/src/rendering/main_pipeline.rs @@ -59,6 +59,7 @@ use crate::rendering::{ use crate::scene::{Active as ActiveScene, Scene}; use crate::sky_box::SkyBox; use crate::texture::{ + CubeMapFace, Filtering as TextureFiltering, Properties as TextureProperties, Texture, @@ -79,12 +80,6 @@ type RenderableEntity<'a> = ( Without<NoDraw>, ); -struct SkyBoxIds -{ - texture_object: ObjectId, - mesh_object: ObjectId, -} - #[derive(Debug, Default, Component)] pub struct PipelineResources { @@ -137,7 +132,7 @@ pub fn add_passes( return Ok(()); }; - let Some((scene_ent_id, (scene_env_lighting, scene_skybox, scene_skybox_state))) = + let Some((scene_ent_id, (scene_env_lighting, scene_sky_box, scene_sky_box_state))) = scene_query.iter_with_euids().next() else { return Ok(()); @@ -177,6 +172,20 @@ pub fn add_passes( backend_properties, )?; + let scene_sky_box_state = if let Some(scene_sky_box) = scene_sky_box.as_deref() { + get_or_load_load_sky_box( + scene_ent_id, + scene_sky_box, + scene_sky_box_state.as_deref(), + assets, + object_store, + render_pass, + &mut actions, + ) + } else { + Ok(None) + }; + let main_3d_shader_cursor = ShaderCursor::new( shaders .main_3d_shader @@ -219,7 +228,10 @@ pub fn add_passes( let mut buf_clear_mask = BufferClearMask::DEPTH; - buf_clear_mask.set(BufferClearMask::COLOR, scene_skybox.is_none()); + buf_clear_mask.set( + BufferClearMask::COLOR, + matches!(scene_sky_box_state, Ok(Some(_)) | Err(_)), + ); render_pass .commands @@ -299,23 +311,10 @@ pub fn add_passes( } } - if let Some(scene_skybox) = &scene_skybox { - let Some(sky_box_ids) = load_sky_box( - scene_ent_id, - scene_skybox, - scene_skybox_state.as_deref(), - assets, - object_store, - render_pass, - &mut actions, - )? - else { - continue; - }; - + if let Ok(Some(scene_sky_box_state)) = &scene_sky_box_state { add_sky_box_commands( render_pass, - &sky_box_ids, + scene_sky_box_state, &camera, &camera_transform, &window, @@ -792,7 +791,7 @@ fn add_set_3d_shader_renderable_bindings( fn add_sky_box_commands( render_pass: &mut RenderPass, - sky_box_ids: &SkyBoxIds, + sky_box_state: &SkyBoxState, camera: &Camera, camera_transform: &Transform, window: &Window, @@ -844,7 +843,7 @@ fn add_sky_box_commands( .binding(view.into())?, sky_box_shader_cursor.field("cube_texture").binding( ShaderBindingValue::Texture( - sky_box_ids.texture_object, + sky_box_state.texture_object_id, ShaderBindingTextureKind::Cube, ), )?, @@ -865,14 +864,14 @@ fn add_sky_box_commands( )); render_pass.commands.push(Command::DrawMesh( - sky_box_ids.mesh_object, + sky_box_state.mesh_object_id, DrawMeshOptions::default(), )); Ok(()) } -fn load_sky_box( +fn get_or_load_load_sky_box( scene_ent_id: Uid, sky_box: &SkyBox, sky_box_state: Option<&SkyBoxState>, @@ -880,7 +879,7 @@ fn load_sky_box( object_store: &mut ObjectStore, render_pass: &mut RenderPass, actions: &mut Actions, -) -> Result<Option<SkyBoxIds>, crate::Error> +) -> Result<Option<SkyBoxState>, ()> { let mesh_object_id = if let Some(sky_box_state) = &sky_box_state { sky_box_state.mesh_object_id @@ -900,35 +899,42 @@ fn load_sky_box( mesh_object_id }; - let texture_object_id = match &sky_box { - SkyBox::AssetPerCubeMapFace(cube_map_part_assets) => { - if let Some(sky_box_state) = sky_box_state { - sky_box_state.texture_object_id - } else { - let Some(part_images) = cube_map_part_assets - .iter() - .map_while(|(face, part_texture_asset)| { - let part_texture = assets.get(part_texture_asset)?; - - match part_texture { - Texture::Texture2D(part_texture) => { - Some((*face, &part_texture.image)) - } - Texture::CubeMap(_) => { - tracing::warn!( - "Cube map texture cannot be used as cube map part" - ); - - None - } + let texture_object_id = if let Some(sky_box_state) = sky_box_state { + sky_box_state.texture_object_id + } else { + match &sky_box { + SkyBox::AssetPerCubeMapFace(cube_map_face_assets) => { + let mut faces_images: [Option<(CubeMapFace, &Image)>; 6] = [None; 6]; + + let mut faces_image_index = 0; + + for (face, face_tex_asset) in cube_map_face_assets { + let Some(face_tex) = assets.get(face_tex_asset) else { + if assets.get_status(&face_tex_asset).is_failed() { + return Err(()); } - }) - .collect::<Vec<_>>() - .as_array::<6>() - .copied() - else { - return Ok(None); - }; + + return Ok(None); + }; + + let face_image = match face_tex { + Texture::Texture2D(face_tex) => &face_tex.image, + Texture::CubeMap(_) => { + tracing::error!(concat!( + "Cube map texture can't be used as face texture ", + "of a cube map" + )); + + return Err(()); + } + }; + + faces_images[faces_image_index] = Some((*face, face_image)); + + faces_image_index += 1; + } + + let faces_images = faces_images.map(Option::unwrap); let texture_object_id = ObjectId::new_sequential(); @@ -937,12 +943,12 @@ fn load_sky_box( render_pass.commands.push(Command::CreateTexture { obj_id: texture_object_id, pixel_data_format: TexturePixelDataFormat::for_image( - part_images[0].1, + faces_images[0].1, ) .expect("No texture pixel data format is available for image"), creation: TextureCreation::CubeMap { - size: part_images[0].1.dimensions(), - images: Some(Box::new(part_images.map(|(face, image)| { + size: faces_images[0].1.dimensions(), + images: Some(Box::new(faces_images.map(|(face, image)| { (face, image.as_bytes().to_vec().into_boxed_slice()) }))), }, @@ -965,10 +971,7 @@ fn load_sky_box( ); } - Ok(Some(SkyBoxIds { - texture_object: texture_object_id, - mesh_object: mesh_object_id, - })) + Ok(Some(SkyBoxState { texture_object_id, mesh_object_id })) } #[derive(Debug, Component)] |
