raidillon/glium_platform/src/render/basic.rs
reo ce24354f3b egui support
- New Resource, EguiQueue: Utility to queue egui ui builders
- New Rendering System, EguiRenderer: Utilizes a modified egui_glium
  library to render egui UI
- Adjusted RenderingSystem trait and RenderingContext structure to
  provide event_loop and egui_queue.
- Various minor adjusments
2025-11-16 18:14:12 +03:00

109 lines
3.9 KiB
Rust

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<WindowSurface>, _window: Arc<Mutex<glium::winit::window::Window>>, 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::<Model>() {
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();
}
}
}