- Introduced ECSRenderer struct to manage the connection between the renderer and the ECS. - Implemented methods for spawning and despawning meshes within the ECS. - Updated main function to utilize ECSRenderer for rendering and object management. - Added a new Time module to handle frame timing and updates.
94 lines
2.9 KiB
Rust
94 lines
2.9 KiB
Rust
mod camera;
|
|
mod ecs;
|
|
mod model;
|
|
mod render;
|
|
mod time;
|
|
|
|
use anyhow::Result;
|
|
use camera::Camera;
|
|
use ecs::{MeshHandle, Transform};
|
|
use glam::{Quat, Vec3};
|
|
use glium::backend::glutin::SimpleWindowBuilder;
|
|
use render::{Renderer, GliumRenderer};
|
|
|
|
fn main() -> Result<()> {
|
|
const ROTATION_SPEED: f32 = 1.0;
|
|
|
|
let event_loop = glium::winit::event_loop::EventLoop::builder()
|
|
.build()
|
|
.expect("create event-loop");
|
|
|
|
let (window, display) = SimpleWindowBuilder::new()
|
|
.with_title("fps")
|
|
.with_inner_size(1280, 720)
|
|
.build(&event_loop);
|
|
|
|
// Create ECS renderer which internally owns both the world and the renderer
|
|
let mut ecsr = {
|
|
let world = hecs::World::new();
|
|
let renderer = GliumRenderer::new(display.clone())?;
|
|
ecs::ECSRenderer::new(renderer, world)
|
|
};
|
|
|
|
let mut time = time::Time::new();
|
|
|
|
let object_ent = {
|
|
let mesh = model::load_gltf("resources/monkey-smooth.gltf", &display)?;
|
|
ecsr.spawn_mesh(mesh, Transform {
|
|
translation: Vec3::ZERO,
|
|
rotation: Quat::IDENTITY,
|
|
scale: Vec3::ONE,
|
|
})
|
|
};
|
|
|
|
|
|
let camera_ent = {
|
|
let (w, h): (u32, u32) = window.inner_size().into();
|
|
ecsr.world.spawn((Camera {
|
|
eye: Vec3::new(3.0, 2.0, 3.0),
|
|
center: Vec3::ZERO,
|
|
up: Vec3::Y,
|
|
fovy: 45_f32.to_radians(),
|
|
aspect: w as f32 / h as f32,
|
|
znear: 0.1,
|
|
zfar: 100.0,
|
|
},))
|
|
};
|
|
|
|
event_loop
|
|
.run(move |event, el| {
|
|
use glium::winit::event::{Event, WindowEvent};
|
|
|
|
match event {
|
|
Event::WindowEvent { event, .. } => match event {
|
|
WindowEvent::CloseRequested => el.exit(),
|
|
WindowEvent::Resized(sz) => {
|
|
ecsr.world.query_one_mut::<&mut crate::camera::Camera>(camera_ent).map(|mut cam| {
|
|
cam.aspect = sz.width as f32 / sz.height as f32;
|
|
});
|
|
}
|
|
WindowEvent::RedrawRequested => {
|
|
ecsr.render();
|
|
}
|
|
_ => {}
|
|
},
|
|
Event::AboutToWait => {
|
|
time.tick();
|
|
let dt = time.delta_seconds();
|
|
ecsr.world.query_one_mut::<&mut Transform>(object_ent).map(|mut object| {
|
|
object.rotation *= Quat::from_rotation_y(ROTATION_SPEED * dt);
|
|
});
|
|
|
|
// despawn the object after 3 seconds
|
|
if time.total_seconds() > 3.0 {
|
|
ecsr.despawn_mesh(object_ent);
|
|
}
|
|
|
|
// ask for next frame
|
|
window.request_redraw();
|
|
}
|
|
_ => {}
|
|
}
|
|
})
|
|
.map_err(Into::into)
|
|
}
|