diff options
Diffstat (limited to 'engine/src/renderer/opengl.rs')
| -rw-r--r-- | engine/src/renderer/opengl.rs | 133 |
1 files changed, 86 insertions, 47 deletions
diff --git a/engine/src/renderer/opengl.rs b/engine/src/renderer/opengl.rs index fb7dfbe..8f10215 100644 --- a/engine/src/renderer/opengl.rs +++ b/engine/src/renderer/opengl.rs @@ -15,26 +15,26 @@ use ecs::phase::Phase; use ecs::query::term::Without; use ecs::sole::Single; use ecs::system::observer::Observe; -use ecs::{declare_entity, Component, Query}; +use ecs::{Component, Query, declare_entity}; use glutin::display::GetGlDisplay; use glutin::prelude::GlDisplay; use glutin::surface::GlSurface; use opengl_bindings::debug::{ - set_debug_message_callback, - set_debug_message_control, MessageIdsAction, MessageSeverity, MessageSource, MessageType, SetDebugMessageControlError as GlSetDebugMessageControlError, + set_debug_message_callback, + set_debug_message_control, }; use opengl_bindings::misc::{ - clear_buffers, - enable, - set_enabled, BufferClearMask, Capability, SetViewportError as GlSetViewportError, + clear_buffers, + enable, + set_enabled, }; use opengl_bindings::shader::{ Error as GlShaderError, @@ -66,10 +66,10 @@ use crate::image::{ColorType as ImageColorType, Image}; use crate::lighting::{DirectionalLight, GlobalLight, PointLight}; use crate::material::{Flags as MaterialFlags, Material}; use crate::matrix::Matrix; -use crate::model::Model; +use crate::model::{Materials as ModelMaterials, Model, Spec as ModelSpec}; use crate::opengl::glsl::{ - preprocess as glsl_preprocess, PreprocessingError as GlslPreprocessingError, + preprocess as glsl_preprocess, }; use crate::projection::{ClipVolume, Projection}; use crate::renderer::opengl::glutin_compat::{ @@ -86,13 +86,13 @@ use crate::texture::{ use crate::transform::{Scale, WorldPosition}; use crate::util::MapVec; use crate::vector::{Vec2, Vec3}; +use crate::windowing::Context as WindowingContext; use crate::windowing::window::{ Closed as WindowClosed, CreationAttributes as WindowCreationAttributes, CreationReady, Window, }; -use crate::windowing::Context as WindowingContext; mod glutin_compat; mod graphics_mesh; @@ -648,6 +648,43 @@ fn init_window_graphics( } } +enum MaterialSearchResult<'a> +{ + Found(&'a Material), + NotFound, + NoMaterials, +} + +fn find_first_model_material<'assets>( + model_spec: &'assets ModelSpec, + assets: &'assets Assets, +) -> MaterialSearchResult<'assets> +{ + let Some(material_name) = model_spec.material_names.first() else { + return MaterialSearchResult::NoMaterials; + }; + + let Some(material_asset) = (match &model_spec.materials { + ModelMaterials::Maps(material_asset_map_assets) => material_asset_map_assets + .iter() + .find_map(|mat_asset_map_asset| { + let mat_asset_map = assets.get(mat_asset_map_asset)?; + + mat_asset_map.assets.get(material_name) + }), + ModelMaterials::Direct(material_assets) => material_assets.get(material_name), + }) else { + return MaterialSearchResult::NotFound; + }; + + let Some(material) = assets.get(material_asset) else { + tracing::trace!("Missing material asset"); + return MaterialSearchResult::NotFound; + }; + + MaterialSearchResult::Found(material) +} + #[tracing::instrument(skip_all)] #[allow(clippy::too_many_arguments)] fn render( @@ -730,11 +767,31 @@ fn render( ), ) in query.iter_with_euids() { - let Some(model_data) = assets.get(&model.asset_handle) else { - tracing::trace!("Missing model asset"); + let Some(model_spec) = assets.get(&model.spec_asset) else { + tracing::trace!("Missing model spec asset"); + continue; + }; + + let Some(mesh_asset) = &model_spec.mesh_asset else { + tracing::debug!("Model spec mesh asset is None"); continue; }; + let Some(model_mesh) = assets.get(&mesh_asset) else { + tracing::trace!("Missing mesh asset"); + continue; + }; + + debug_assert!(model_spec.material_names.len() <= 1); + + let model_material = match find_first_model_material(model_spec, &assets) { + MaterialSearchResult::Found(model_material) => model_material, + MaterialSearchResult::NotFound => { + continue; + } + MaterialSearchResult::NoMaterials => &Material::default(), + }; + let material_flags = material_flags .map(|material_flags| material_flags.clone()) .unwrap_or_default(); @@ -762,23 +819,21 @@ fn render( data_in_graphics_ctx.graphics_mesh_id } None => { - let graphics_mesh = match GraphicsMesh::new( - ¤t_graphics_context, - &model_data.mesh, - ) { - Ok(graphics_mesh) => graphics_mesh, - Err(err) => { - tracing::error!( - "Failed to create {}: {err}", - type_name::<GraphicsMesh>() - ); - - // This system should not try again - actions.add_components(euid, (NoDraw,)); - - continue; - } - }; + let graphics_mesh = + match GraphicsMesh::new(¤t_graphics_context, model_mesh) { + Ok(graphics_mesh) => graphics_mesh, + Err(err) => { + tracing::error!( + "Failed to create {}: {err}", + type_name::<GraphicsMesh>() + ); + + // This system should not try again + actions.add_components(euid, (NoDraw,)); + + continue; + } + }; let graphics_mesh_id = graphics_mesh_store.insert(graphics_mesh); @@ -813,25 +868,9 @@ fn render( window.inner_size(), ); - if model_data.materials.len() > 1 { - tracing::warn!(concat!( - "Multiple model materials are not supported ", - "so only the first material will be used" - )); - } - - let material = match model_data.materials.values().next() { - Some(material) => material, - None => { - tracing::warn!("Model has no materials. Using default material"); - - &Material::default() - } - }; - apply_light( ¤t_graphics_context, - &material, + model_material, &material_flags, &global_light, shader_program, @@ -846,7 +885,7 @@ fn render( match create_bind_material_textures( ¤t_graphics_context, - &material, + model_material, &assets, textures_objs, default_1x1_texture_obj, @@ -1466,7 +1505,7 @@ fn opengl_debug_message_cb( { use std::backtrace::{Backtrace, BacktraceStatus}; - use tracing::{event, Level}; + use tracing::{Level, event}; macro_rules! create_event { ($level: expr) => { |
