diff options
| -rw-r--r-- | engine/src/image.rs | 44 | ||||
| -rw-r--r-- | engine/src/lib.rs | 3 | ||||
| -rw-r--r-- | engine/src/material.rs | 19 | ||||
| -rw-r--r-- | engine/src/material/asset.rs | 13 | ||||
| -rw-r--r-- | engine/src/renderer.rs | 38 | ||||
| -rw-r--r-- | engine/src/renderer/opengl.rs | 12 | ||||
| -rw-r--r-- | engine/src/shader/cursor.rs | 4 | ||||
| -rw-r--r-- | engine/src/shader/default.rs | 17 | ||||
| -rw-r--r-- | engine/src/texture.rs | 90 |
9 files changed, 110 insertions, 130 deletions
diff --git a/engine/src/image.rs b/engine/src/image.rs index 9296167..7c18bf7 100644 --- a/engine/src/image.rs +++ b/engine/src/image.rs @@ -4,12 +4,10 @@ use std::path::Path; use image_rs::GenericImageView as _; -use crate::asset::{Assets, Submitter as AssetSubmitter}; -use crate::builder; use crate::color::Color; use crate::data_types::dimens::Dimens; -#[derive(Debug)] +#[derive(Debug, Clone)] pub struct Image { inner: image_rs::DynamicImage, @@ -68,30 +66,6 @@ impl Image } } -builder! { -#[builder(name = SettingsBuilder, derives=(Debug, Clone))] -#[derive(Debug, Default, Clone)] -#[non_exhaustive] -pub struct Settings { -} -} - -impl Settings -{ - pub fn builder() -> SettingsBuilder - { - SettingsBuilder::default() - } -} - -impl Default for SettingsBuilder -{ - fn default() -> Self - { - Settings::default().into() - } -} - /// An enumeration over supported color types and bit depths #[derive(Copy, PartialEq, Eq, Debug, Clone, Hash)] #[non_exhaustive] @@ -150,11 +124,6 @@ impl From<image_rs::ColorType> for ColorType } } -pub fn set_asset_importers(assets: &mut Assets) -{ - assets.set_importer::<_, _>(["png", "jpg"], import_asset); -} - #[derive(Debug, thiserror::Error)] pub enum Error { @@ -171,14 +140,3 @@ pub enum Error #[derive(Debug, thiserror::Error)] #[error(transparent)] pub struct DecodeError(image_rs::ImageError); - -fn import_asset( - asset_submitter: &mut AssetSubmitter<'_>, - path: &Path, - _settings: Option<&'_ Settings>, -) -> Result<(), Error> -{ - asset_submitter.submit_store::<Image>(Image::open(path)?); - - Ok(()) -} diff --git a/engine/src/lib.rs b/engine/src/lib.rs index 560d288..0941de0 100644 --- a/engine/src/lib.rs +++ b/engine/src/lib.rs @@ -78,7 +78,8 @@ impl Engine crate::model::asset::add_importers(&mut assets); crate::material::asset::add_importers(&mut assets); crate::shader::add_asset_importers(&mut assets); - crate::image::set_asset_importers(&mut assets); + + crate::texture::initialize(&mut assets); world.add_extension(AssetExtension { assets }); world.add_extension(ShaderExtension); diff --git a/engine/src/material.rs b/engine/src/material.rs index 94ab24e..ed1c139 100644 --- a/engine/src/material.rs +++ b/engine/src/material.rs @@ -1,5 +1,6 @@ use ecs::Component; +use crate::asset::Handle as AssetHandle; use crate::builder; use crate::color::Color; use crate::texture::Texture; @@ -13,9 +14,9 @@ pub struct Material pub ambient: Color<f32>, pub diffuse: Color<f32>, pub specular: Color<f32>, - pub ambient_map: Option<Texture>, - pub diffuse_map: Option<Texture>, - pub specular_map: Option<Texture>, + pub ambient_map: Option<AssetHandle<Texture>>, + pub diffuse_map: Option<AssetHandle<Texture>>, + pub specular_map: Option<AssetHandle<Texture>>, pub shininess: f32, } @@ -42,9 +43,9 @@ pub struct Builder ambient: Color<f32>, diffuse: Color<f32>, specular: Color<f32>, - ambient_map: Option<Texture>, - diffuse_map: Option<Texture>, - specular_map: Option<Texture>, + ambient_map: Option<AssetHandle<Texture>>, + diffuse_map: Option<AssetHandle<Texture>>, + specular_map: Option<AssetHandle<Texture>>, shininess: f32, } @@ -89,7 +90,7 @@ impl Builder } #[must_use] - pub fn ambient_map(mut self, ambient_map: Texture) -> Self + pub fn ambient_map(mut self, ambient_map: AssetHandle<Texture>) -> Self { self.ambient_map = Some(ambient_map); @@ -97,7 +98,7 @@ impl Builder } #[must_use] - pub fn diffuse_map(mut self, diffuse_map: Texture) -> Self + pub fn diffuse_map(mut self, diffuse_map: AssetHandle<Texture>) -> Self { self.diffuse_map = Some(diffuse_map); @@ -105,7 +106,7 @@ impl Builder } #[must_use] - pub fn specular_map(mut self, specular_map: Texture) -> Self + pub fn specular_map(mut self, specular_map: AssetHandle<Texture>) -> Self { self.specular_map = Some(specular_map); diff --git a/engine/src/material/asset.rs b/engine/src/material/asset.rs index 1f53dad..b210154 100644 --- a/engine/src/material/asset.rs +++ b/engine/src/material/asset.rs @@ -5,7 +5,6 @@ use std::path::{Path, PathBuf}; use crate::asset::{Assets, Handle as AssetHandle, Submitter as AssetSubmitter}; use crate::material::Material; -use crate::texture::Texture; #[derive(Debug, Clone)] pub struct Map @@ -46,21 +45,21 @@ fn import_wavefront_mtl_asset( .shininess(material.shininess); if let Some(ambient_map) = material.ambient_map { - material_builder = material_builder.ambient_map(Texture::new( + material_builder = material_builder.ambient_map( asset_submitter.submit_load_other(ambient_map.path.as_path()), - )); + ); } if let Some(diffuse_map) = material.diffuse_map { - material_builder = material_builder.diffuse_map(Texture::new( + material_builder = material_builder.diffuse_map( asset_submitter.submit_load_other(diffuse_map.path.as_path()), - )); + ); } if let Some(specular_map) = material.specular_map { - material_builder = material_builder.specular_map(Texture::new( + material_builder = material_builder.specular_map( asset_submitter.submit_load_other(specular_map.path.as_path()), - )); + ); } let material_name = material.name; diff --git a/engine/src/renderer.rs b/engine/src/renderer.rs index 8b37989..7865ac4 100644 --- a/engine/src/renderer.rs +++ b/engine/src/renderer.rs @@ -1,7 +1,5 @@ use std::any::type_name; use std::collections::VecDeque; -use std::path::Path; -use std::sync::LazyLock; use std::sync::atomic::{AtomicU64, Ordering}; use bitflags::bitflags; @@ -12,12 +10,9 @@ use ecs::query::term::Without; use ecs::sole::Single; use ecs::{Component, Query, declare_entity}; -use crate::asset::{Assets, Label as AssetLabel}; +use crate::asset::{Assets, Handle as AssetHandle}; use crate::builder; -use crate::color::Color; -use crate::data_types::dimens::Dimens; use crate::draw_flags::{DrawFlags, NoDraw, PolygonModeConfig}; -use crate::image::Image; use crate::mesh::Mesh; use crate::model::{MaterialSearchResult, Model}; use crate::renderer::object::{Id as ObjectId, Store as ObjectStore}; @@ -33,7 +28,7 @@ use crate::shader::{ Program as ShaderProgram, Shader, }; -use crate::texture::{Properties as TextureProperties, Texture}; +use crate::texture::{Texture, WHITE_1X1_ASSET_LABEL as TEXTURE_WHITE_1X1_ASSET_LABEL}; use crate::windowing::window::Window; pub mod object; @@ -41,12 +36,6 @@ pub mod opengl; static NEXT_SURFACE_ID: AtomicU64 = AtomicU64::new(0); -pub static DEFAULT_TEXTURE_ASSET_LABEL: LazyLock<AssetLabel> = - LazyLock::new(|| AssetLabel { - path: Path::new("").into(), - name: Some("default_texture".into()), - }); - declare_entity!( pub PRE_RENDER_PHASE, ( @@ -163,7 +152,7 @@ pub enum Command CreateShaderProgram(ObjectId, ShaderProgram), ActivateShader(ObjectId), SetShaderBinding(ShaderBindingLocation, ShaderBindingValue), - CreateTexture(Texture), + CreateTexture(AssetHandle<Texture>), CreateMesh(ObjectId, Mesh), DrawMesh(ObjectId), SetPolygonModeConfig(PolygonModeConfig), @@ -221,14 +210,6 @@ type RenderableEntity<'a> = ( Option<&'a mut PendingShaderBindings>, ); -pub fn init(mut assets: Single<Assets>) -{ - assets.store_with_label( - DEFAULT_TEXTURE_ASSET_LABEL.clone(), - Image::from_color(Dimens { width: 1, height: 1 }, Color::WHITE_U8), - ); -} - #[tracing::instrument(skip_all)] pub fn enqueue_commands( renderer_ctx_query: Query<( @@ -291,16 +272,13 @@ pub fn enqueue_commands( command_queue.push(Command::MakeCurrent(surface_spec.id)); let default_texture_asset = assets - .get_handle_to_loaded::<Image>(DEFAULT_TEXTURE_ASSET_LABEL.clone()) + .get_handle_to_loaded::<Texture>(TEXTURE_WHITE_1X1_ASSET_LABEL.clone()) .expect("Not possible"); if !object_store .contains_with_id(&ObjectId::Asset(default_texture_asset.id())) { - command_queue.push(Command::CreateTexture(Texture { - asset_handle: default_texture_asset, - properties: TextureProperties::default(), - })); + command_queue.push(Command::CreateTexture(default_texture_asset)); } command_queue.push(Command::ClearBuffers( @@ -373,7 +351,7 @@ pub fn enqueue_commands( unreachable!(); }; - for texture in [ + for texture_asset in [ &model_material.ambient_map, &model_material.diffuse_map, &model_material.specular_map, @@ -382,9 +360,9 @@ pub fn enqueue_commands( .flatten() { if !object_store - .contains_with_id(&ObjectId::Asset(texture.asset_handle.id())) + .contains_with_id(&ObjectId::Asset(texture_asset.id())) { - command_queue.push(Command::CreateTexture(texture.clone())); + command_queue.push(Command::CreateTexture(texture_asset.clone())); } } diff --git a/engine/src/renderer/opengl.rs b/engine/src/renderer/opengl.rs index 2dd5467..a280073 100644 --- a/engine/src/renderer/opengl.rs +++ b/engine/src/renderer/opengl.rs @@ -8,7 +8,7 @@ use ecs::actions::Actions; use ecs::entity::obtainer::Obtainer as EntityObtainer; use ecs::event::component::{Changed, Removed}; use ecs::pair::{ChildOf, Pair, Wildcard}; -use ecs::phase::{Phase, START as START_PHASE}; +use ecs::phase::Phase; use ecs::query::term::Without; use ecs::sole::Single; use ecs::system::observer::Observe; @@ -156,8 +156,6 @@ impl ecs::extension::Extension for Extension collector.add_declared_entity(&RENDER_PHASE); collector.add_declared_entity(&POST_RENDER_PHASE); - collector.add_system(*START_PHASE, super::init); - collector.add_system(*RENDER_PHASE, super::enqueue_commands); collector.add_system(*RENDER_PHASE, handle_commands); @@ -893,13 +891,13 @@ fn handle_commands( ) .unwrap(); } - RendererCommand::CreateTexture(texture) => { + RendererCommand::CreateTexture(texture_asset) => { let Some(curr_gl_ctx) = &opt_curr_gl_ctx else { tracing::error!("No GL context is current"); continue; }; - let Some(texture_image) = assets.get(&texture.asset_handle) else { + let Some(texture) = assets.get(&texture_asset) else { tracing::error!("Texture asset is not loaded",); continue; }; @@ -907,8 +905,8 @@ fn handle_commands( if let Err(err) = create_texture_object( curr_gl_ctx, &mut renderer_object_store, - texture.asset_handle.id(), - texture_image, + texture_asset.id(), + &texture.image, &texture.properties, ) { tracing::error!("Failed to create texture object: {err}"); diff --git a/engine/src/shader/cursor.rs b/engine/src/shader/cursor.rs index b5ba4e0..0522858 100644 --- a/engine/src/shader/cursor.rs +++ b/engine/src/shader/cursor.rs @@ -1,7 +1,7 @@ use crate::asset::Handle as AssetHandle; -use crate::image::Image; use crate::matrix::Matrix; use crate::shader::{TypeKind, TypeLayout, VariableLayout}; +use crate::texture::Texture; use crate::vector::Vec3; /// Shader cursor @@ -116,7 +116,7 @@ pub enum BindingValue Float(f32), FVec3(Vec3<f32>), FMat4x4(Matrix<f32, 4, 4>), - Texture(AssetHandle<Image>), + Texture(AssetHandle<Texture>), } impl From<u32> for BindingValue diff --git a/engine/src/shader/default.rs b/engine/src/shader/default.rs index 28bbdc9..bc8202c 100644 --- a/engine/src/shader/default.rs +++ b/engine/src/shader/default.rs @@ -15,13 +15,14 @@ use crate::material::{Flags as MaterialFlags, Material}; use crate::matrix::Matrix; use crate::model::{MaterialSearchResult, Model}; use crate::projection::{ClipVolume as ProjectionClipVolume, Projection}; -use crate::renderer::{DEFAULT_TEXTURE_ASSET_LABEL, PendingShaderBindings}; +use crate::renderer::PendingShaderBindings; use crate::shader::cursor::{BindingValue as ShaderBindingValue, Cursor as ShaderCursor}; use crate::shader::{ Context as ShaderContext, ModuleSource as ShaderModuleSource, Shader, }; +use crate::texture::WHITE_1X1_ASSET_LABEL as TEXTURE_WHITE_1X1_ASSET_LABEL; use crate::transform::{Scale, Transform, WorldPosition}; use crate::vector::Vec3; use crate::windowing::window::Window; @@ -122,7 +123,7 @@ pub fn enqueue_set_shader_bindings( ] .into_iter() .flatten() - .any(|texture| !assets.is_loaded_and_has_type(&texture.asset_handle)) + .any(|texture_asset| !assets.is_loaded_and_has_type(&texture_asset)) { continue; } @@ -270,10 +271,10 @@ pub fn enqueue_set_shader_bindings( model_material .ambient_map .as_ref() - .map(|ambient_map| ambient_map.asset_handle.clone()) + .map(|ambient_map| ambient_map.clone()) .unwrap_or_else(|| { assets - .get_handle_to_loaded(DEFAULT_TEXTURE_ASSET_LABEL.clone()) + .get_handle_to_loaded(TEXTURE_WHITE_1X1_ASSET_LABEL.clone()) .expect("Not possible") }), ), @@ -285,10 +286,10 @@ pub fn enqueue_set_shader_bindings( model_material .diffuse_map .as_ref() - .map(|diffuse_map| diffuse_map.asset_handle.clone()) + .map(|diffuse_map| diffuse_map.clone()) .unwrap_or_else(|| { assets - .get_handle_to_loaded(DEFAULT_TEXTURE_ASSET_LABEL.clone()) + .get_handle_to_loaded(TEXTURE_WHITE_1X1_ASSET_LABEL.clone()) .expect("Not possible") }), ), @@ -300,10 +301,10 @@ pub fn enqueue_set_shader_bindings( model_material .specular_map .as_ref() - .map(|specular_map| specular_map.asset_handle.clone()) + .map(|specular_map| specular_map.clone()) .unwrap_or_else(|| { assets - .get_handle_to_loaded(DEFAULT_TEXTURE_ASSET_LABEL.clone()) + .get_handle_to_loaded(TEXTURE_WHITE_1X1_ASSET_LABEL.clone()) .expect("Not possible") }), ), diff --git a/engine/src/texture.rs b/engine/src/texture.rs index d02b9ff..b92bc2e 100644 --- a/engine/src/texture.rs +++ b/engine/src/texture.rs @@ -1,34 +1,24 @@ -use crate::asset::Handle as AssetHandle; -use crate::image::Image; +use std::path::Path; +use std::sync::LazyLock; + +use crate::asset::{Assets, Label as AssetLabel, Submitter as AssetSubmitter}; use crate::builder; +use crate::color::Color; +use crate::data_types::dimens::Dimens; +use crate::image::{Error as ImageError, Image}; + +pub static WHITE_1X1_ASSET_LABEL: LazyLock<AssetLabel> = LazyLock::new(|| AssetLabel { + path: Path::new("").into(), + name: Some("white_1x1_texture".into()), +}); #[derive(Debug, Clone)] -#[non_exhaustive] pub struct Texture { - pub asset_handle: AssetHandle<Image>, + pub image: Image, pub properties: Properties, } -impl Texture -{ - pub fn new(asset_handle: AssetHandle<Image>) -> Self - { - Self { - asset_handle, - properties: Properties::default(), - } - } - - pub fn with_properties( - asset_handle: AssetHandle<Image>, - properties: Properties, - ) -> Self - { - Self { asset_handle, properties } - } -} - builder! { /// Texture properties #[builder(name = PropertiesBuilder, derives=(Debug, Clone))] @@ -88,3 +78,57 @@ pub enum Wrapping ClampToEdge, ClampToBorder, } + +builder! { +#[builder(name = ImportSettingsBuilder, derives=(Debug, Clone))] +#[derive(Debug, Default, Clone)] +#[non_exhaustive] +pub struct ImportSettings { + properties: Properties, +} +} + +impl ImportSettings +{ + pub fn builder() -> ImportSettingsBuilder + { + ImportSettingsBuilder::default() + } +} + +impl Default for ImportSettingsBuilder +{ + fn default() -> Self + { + ImportSettings::default().into() + } +} + +pub(crate) fn initialize(assets: &mut Assets) +{ + assets.set_importer::<_, _>(["png", "jpg"], import); + + assets.store_with_label( + WHITE_1X1_ASSET_LABEL.clone(), + Texture { + image: Image::from_color(Dimens { width: 1, height: 1 }, Color::WHITE_U8), + properties: Properties::default(), + }, + ); +} + +fn import( + asset_submitter: &mut AssetSubmitter<'_>, + path: &Path, + settings: Option<&'_ ImportSettings>, +) -> Result<(), ImageError> +{ + asset_submitter.submit_store(Texture { + image: Image::open(path)?, + properties: settings + .map(|settings| settings.properties.clone()) + .unwrap_or_default(), + }); + + Ok(()) +} |
