use std::any::Any; use std::sync::{Arc, Mutex}; use glium::{uniform, Display, Program, Surface}; use glium::glutin::surface::WindowSurface; use glium::texture::{RawImage2d, SrgbTexture2d}; use crate::{GliumAssetManager, RenderingSystem}; use crate::system::RenderingContext; use raidillon_assets::include_shader; pub use raidillon_platform::Camera; use glam::Vec3; use glium::uniforms::{MagnifySamplerFilter, MinifySamplerFilter, SamplerWrapFunction}; use winit::event::Event; use winit::event_loop::EventLoop; use raidillon_ecs::{Transform, ModelID}; use raidillon_ecs::components::ModelHandle; use crate::model::Model; /// A basic renderer pipeline step. pub struct BasicMeshRenderingSystem { program: Program, white_tex: SrgbTexture2d, params: glium::DrawParameters<'static>, } impl RenderingSystem for BasicMeshRenderingSystem { fn initialize(display: &Display, _window: Arc>, event_loop: &EventLoop<()>) -> Self { const VERT_SRC: &str = include_shader!("gl_textured.vert"); const FRAG_SRC: &str = include_shader!("gl_textured.frag"); let program = Program::from_source(display, VERT_SRC, FRAG_SRC, None).unwrap(); let white_tex = { let data = vec![255u8, 255u8, 255u8, 255u8]; let raw = RawImage2d::from_raw_rgba(data, (1, 1)); SrgbTexture2d::new(display, raw).unwrap() }; let params = glium::DrawParameters { depth: glium::Depth { test: glium::draw_parameters::DepthTest::IfLess, write: true, .. Default::default() }, .. Default::default() }; Self { program, white_tex, params } } fn render(&mut self, ctx: &mut RenderingContext) { let cam = match ctx.scene.world.query::<&Camera>().iter().next() { Some((_, cam)) => *cam, None => { eprintln!("[renderer] No camera component found. Skipping frame"); return; } }; // Use HDR-derived environment light direction if provided, otherwise default to downward let light_dir: Vec3 = if ctx.env_light_dir.length_squared() > 0.0 { ctx.env_light_dir.normalize() } else { Vec3::new(0.0, -1.0, 0.0) }; let asset_manager = ctx.asset_manager.borrow(); for (_, (tr, mh)) in ctx.scene.world.query::<(&Transform, &ModelHandle)>().iter() { let model = match asset_manager.get_model(&mh.0) { Some(model) => model, _ => continue, }; let model = match model.downcast_ref::() { Some(model) => model, None => continue, }; let mesh = &model.mesh; let mat = &model.material; let tex_ref: &SrgbTexture2d = mat.base_color.as_ref().unwrap_or(&self.white_tex); let mut sampler = tex_ref.sampled(); sampler = sampler.wrap_function(SamplerWrapFunction::Repeat); sampler = sampler.minify_filter(MinifySamplerFilter::Linear); sampler = sampler.magnify_filter(MagnifySamplerFilter::Linear); let c = mat.base_color_factor; let uniforms = uniform! { model: tr.matrix().to_cols_array_2d(), view: cam.view().to_cols_array_2d(), projection: cam.projection().to_cols_array_2d(), u_light: [light_dir.x, light_dir.y, light_dir.z], tex: sampler, color: [c[0], c[1], c[2]], uv_offset: [mat.uv_offset.x, mat.uv_offset.y], uv_scale: [mat.uv_scale.x, mat.uv_scale.y], }; ctx.target.draw( &mesh.vbuf, &mesh.ibuf, &self.program, &uniforms, &self.params, ).unwrap(); } } }