summaryrefslogtreecommitdiff
path: root/engine/src/rendering/main_render_pass.rs
diff options
context:
space:
mode:
Diffstat (limited to 'engine/src/rendering/main_render_pass.rs')
-rw-r--r--engine/src/rendering/main_render_pass.rs170
1 files changed, 103 insertions, 67 deletions
diff --git a/engine/src/rendering/main_render_pass.rs b/engine/src/rendering/main_render_pass.rs
index 21c0745..895517b 100644
--- a/engine/src/rendering/main_render_pass.rs
+++ b/engine/src/rendering/main_render_pass.rs
@@ -2,6 +2,7 @@ use std::path::Path;
use std::sync::LazyLock;
use ecs::actions::Actions;
+use ecs::component::local::Local;
use ecs::pair::ChildOf;
use ecs::query::term::{Traverse, TraverseUp};
use ecs::uid::Uid;
@@ -9,11 +10,13 @@ use ecs::Component;
use crate::asset::{Assets, Id as AssetId, Label as AssetLabel};
use crate::camera::{Active as ActiveCamera, Camera};
-use crate::data_types::dimens::Dimens3;
+use crate::color::Rgba;
+use crate::data_types::dimens::{Dimens, Dimens3};
use crate::draw_flags::{DrawFlags, NoDraw, PolygonModeConfig};
use crate::ecs::query::term::{With, Without};
use crate::ecs::sole::Single;
use crate::ecs::Query;
+use crate::image::Image;
use crate::lighting::{
DirectionalLight,
Environmental as EnvironmentalLighting,
@@ -46,18 +49,19 @@ use crate::rendering::{
MeshUsage,
RenderPass,
RenderPasses,
+ RgbaTextureDataType,
Surface,
TargetWindow,
+ TextureCreation,
+ TexturePixelDataFormat,
};
use crate::scene::{Active as ActiveScene, Scene};
use crate::sky_box::SkyBox;
use crate::texture::{
Filtering as TextureFiltering,
Properties as TextureProperties,
- TexCubeMap,
Texture,
Wrapping as TextureWrapping,
- WHITE_1X1_ASSET_LABEL as TEXTURE_WHITE_1X1_ASSET_LABEL,
};
use crate::transform::Transform;
use crate::vector::Vec3;
@@ -92,6 +96,12 @@ struct SkyBoxIds
shader_asset: AssetId,
}
+#[derive(Debug, Default, Component)]
+pub struct MiscObjectIds
+{
+ white_1x1_tex_obj_id: Option<ObjectId>,
+}
+
#[tracing::instrument(skip_all)]
pub fn add_main_render_pass(
renderable_query: Query<RenderableEntity<'_>>,
@@ -123,6 +133,7 @@ pub fn add_main_render_pass(
mut render_passes: Single<RenderPasses>,
mut object_store: Single<ObjectStore>,
mut actions: Actions,
+ mut misc_object_ids: Local<MiscObjectIds>,
) -> Result<(), crate::Error>
{
let assets = assets.get_mut()?;
@@ -170,20 +181,33 @@ pub fn add_main_render_pass(
.commands
.push(Command::MakeCurrent(window_surface.id));
- let default_texture_asset = assets
- .get_handle_to_loaded::<Texture>(TEXTURE_WHITE_1X1_ASSET_LABEL.clone())
- .expect("Not possible");
+ let white_1x1_tex_obj_id =
+ *misc_object_ids.white_1x1_tex_obj_id.get_or_insert_with(|| {
+ let white_1x1_tex_obj_id = ObjectId::new_sequential();
- if !object_store
- .contains_maybe_pending_with_id(&ObjectId::Asset(default_texture_asset.id()))
- {
- object_store.insert_pending(ObjectId::Asset(default_texture_asset.id()));
+ object_store.insert_pending(white_1x1_tex_obj_id);
- render_pass.commands.push(Command::CreateTexture(
- ObjectId::Asset(default_texture_asset.id()),
- AssetOrValue::Asset(default_texture_asset),
- ));
- }
+ render_pass.commands.push(Command::CreateTexture {
+ obj_id: white_1x1_tex_obj_id,
+ pixel_data_format: TexturePixelDataFormat::Rgba(
+ RgbaTextureDataType::UnsignedByte,
+ ),
+ creation: TextureCreation::Texture2D {
+ size: Dimens { width: 1, height: 1 },
+ image: Some(
+ Image::from_color(
+ Rgba::<u8>::white(),
+ Dimens { width: 1, height: 1 },
+ )
+ .into_bytes()
+ .into_boxed_slice(),
+ ),
+ },
+ properties: TextureProperties::default(),
+ });
+
+ white_1x1_tex_obj_id
+ });
let sky_box_ids = if let Some(scene_skybox) = &scene_skybox {
load_sky_box(
@@ -279,16 +303,45 @@ pub fn add_main_render_pass(
.into_iter()
.flatten()
{
- if !object_store
- .contains_maybe_pending_with_id(&ObjectId::Asset(texture_asset.id()))
- {
- object_store.insert_pending(ObjectId::Asset(texture_asset.id()));
-
- render_pass.commands.push(Command::CreateTexture(
- ObjectId::Asset(texture_asset.id()),
- AssetOrValue::Asset(texture_asset.clone()),
- ));
+ let Some(texture) = assets.get(texture_asset) else {
+ continue;
+ };
+
+ let Texture::Texture2D(texture) = texture else {
+ tracing::error!(
+ texture_asset_id = ?texture_asset.id(),
+ texture_asset_label = ?assets.get_label(texture_asset),
+ "Material texture map is not 2D"
+ );
+ continue;
+ };
+
+ let texture_object_id = ObjectId::Asset(texture_asset.id());
+
+ if object_store.contains_maybe_pending_with_id(&texture_object_id) {
+ continue;
}
+
+ let Some(tex_pixel_data_format) =
+ TexturePixelDataFormat::for_image(&texture.image)
+ else {
+ tracing::error!(
+ "No texture pixel data format is available for image"
+ );
+ continue;
+ };
+
+ object_store.insert_pending(texture_object_id);
+
+ render_pass.commands.push(Command::CreateTexture {
+ obj_id: texture_object_id,
+ pixel_data_format: tex_pixel_data_format,
+ creation: TextureCreation::Texture2D {
+ size: texture.image.dimensions(),
+ image: Some(texture.image.as_bytes().to_vec().into_boxed_slice()),
+ },
+ properties: texture.properties.clone(),
+ });
}
add_set_3d_shader_bindings(
@@ -303,8 +356,8 @@ pub fn add_main_render_pass(
&window,
&point_light_query,
&directional_light_query,
- assets,
shader_program,
+ white_1x1_tex_obj_id,
)?;
if let Some(draw_flags) = draw_flags.as_deref().and_then(|draw_flags| {
@@ -448,8 +501,8 @@ fn add_set_3d_shader_bindings(
&DirectionalLight,
Traverse<(With<Scene>, With<ActiveScene>), TraverseUp, ChildOf>,
)>,
- assets: &Assets,
shader_program: &ShaderProgram,
+ white_1x1_tex_obj_id: ObjectId,
) -> Result<(), crate::Error>
{
let (material, material_flags, transform) = renderable;
@@ -524,16 +577,8 @@ fn add_set_3d_shader_bindings(
material
.ambient_map
.as_ref()
- .map(|ambient_map| ambient_map.clone())
- .unwrap_or_else(|| {
- assets
- .get_handle_to_loaded(
- TEXTURE_WHITE_1X1_ASSET_LABEL.clone(),
- )
- .expect("Not possible")
- })
- .id()
- .into(),
+ .map(|ambient_map| ObjectId::Asset(ambient_map.id()))
+ .unwrap_or(white_1x1_tex_obj_id),
ShaderBindingTextureKind::Texture2D,
))?,
shader_cursor
@@ -542,16 +587,8 @@ fn add_set_3d_shader_bindings(
material
.diffuse_map
.as_ref()
- .map(|diffuse_map| diffuse_map.clone())
- .unwrap_or_else(|| {
- assets
- .get_handle_to_loaded(
- TEXTURE_WHITE_1X1_ASSET_LABEL.clone(),
- )
- .expect("Not possible")
- })
- .id()
- .into(),
+ .map(|diffuse_map| ObjectId::Asset(diffuse_map.id()))
+ .unwrap_or(white_1x1_tex_obj_id),
ShaderBindingTextureKind::Texture2D,
))?,
shader_cursor
@@ -560,16 +597,8 @@ fn add_set_3d_shader_bindings(
material
.specular_map
.as_ref()
- .map(|specular_map| specular_map.clone())
- .unwrap_or_else(|| {
- assets
- .get_handle_to_loaded(
- TEXTURE_WHITE_1X1_ASSET_LABEL.clone(),
- )
- .expect("Not possible")
- })
- .id()
- .into(),
+ .map(|specular_map| ObjectId::Asset(specular_map.id()))
+ .unwrap_or(white_1x1_tex_obj_id),
ShaderBindingTextureKind::Texture2D,
))?,
material_shader_cursor
@@ -769,17 +798,24 @@ fn load_sky_box(
object_store.insert_pending(texture_object_id);
- render_pass.commands.push(Command::CreateTexture(
- texture_object_id,
- AssetOrValue::Value(Texture::CubeMap(TexCubeMap {
- images: part_images.map(|(face, image)| (face, image.clone())),
- properties: TextureProperties::builder()
- .minifying_filter(TextureFiltering::Linear)
- .magnifying_filter(TextureFiltering::Linear)
- .wrap(TextureWrapping::ClampToEdge)
- .build(),
- })),
- ));
+ render_pass.commands.push(Command::CreateTexture {
+ obj_id: texture_object_id,
+ pixel_data_format: TexturePixelDataFormat::for_image(
+ part_images[0].1,
+ )
+ .expect("No texture pixel data format is available for image"),
+ creation: TextureCreation::CubeMap {
+ size: part_images[0].1.dimensions(),
+ images: Some(part_images.map(|(face, image)| {
+ (face, image.as_bytes().to_vec().into_boxed_slice())
+ })),
+ },
+ properties: TextureProperties::builder()
+ .minifying_filter(TextureFiltering::Linear)
+ .magnifying_filter(TextureFiltering::Linear)
+ .wrap(TextureWrapping::ClampToEdge)
+ .build(),
+ });
texture_object_id
}