summaryrefslogtreecommitdiff
path: root/engine/src/rendering/main_pipeline.rs
diff options
context:
space:
mode:
Diffstat (limited to 'engine/src/rendering/main_pipeline.rs')
-rw-r--r--engine/src/rendering/main_pipeline.rs129
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)]