mirror of
https://github.com/lisk77/comet.git
synced 2025-10-24 13:58:49 +00:00
feat: Added swappability of the renderer and added a Renderer trait to make custom renderers if needed. Also renamed Renderer2D component to Render2D because it is a "render component" and not a renderer (but also name to avoid name clashes)
This commit is contained in:
parent
29355335e6
commit
a3df3f4f17
5 changed files with 133 additions and 129 deletions
|
|
@ -1,8 +1,8 @@
|
|||
use std::sync::Arc;
|
||||
use std::sync::{Arc, Mutex};
|
||||
use std::time::{Duration, Instant};
|
||||
use comet_ecs::{Component, ComponentSet, Render, Renderer2D, Transform2D, World};
|
||||
use comet_ecs::{Component, ComponentSet, Render, Transform2D, World};
|
||||
use comet_resources::{ResourceManager, Vertex};
|
||||
use comet_renderer::{Renderer};
|
||||
use comet_renderer::{Renderer2D};
|
||||
|
||||
use winit::{
|
||||
event::{self, *},
|
||||
|
|
@ -19,6 +19,7 @@ use winit::platform::windows::WindowBuilderExtWindows;
|
|||
use winit_input_helper::WinitInputHelper;
|
||||
use comet_input::input_handler::InputHandler;
|
||||
use comet_input::keyboard::Key;
|
||||
use comet_renderer::renderer::Renderer;
|
||||
|
||||
pub enum ApplicationType {
|
||||
App2D,
|
||||
|
|
@ -30,7 +31,6 @@ pub struct App<'a> {
|
|||
icon: Option<Icon>,
|
||||
size: Option<LogicalSize<u32>>,
|
||||
clear_color: Option<LinearRgba>,
|
||||
setup: Option<fn(&mut World)>,
|
||||
input_manager: WinitInputHelper,
|
||||
delta_time: f32,
|
||||
update_timer: f32,
|
||||
|
|
@ -51,7 +51,6 @@ impl<'a> App<'a> {
|
|||
icon: None,
|
||||
size: None,
|
||||
clear_color: None,
|
||||
setup: None,
|
||||
input_manager: WinitInputHelper::new(),
|
||||
delta_time: 0.0,
|
||||
update_timer: 0.0166667,
|
||||
|
|
@ -81,11 +80,6 @@ impl<'a> App<'a> {
|
|||
self
|
||||
}
|
||||
|
||||
pub fn with_setup(mut self, setup: fn(&mut World)) -> Self {
|
||||
self.setup = Some(setup);
|
||||
self
|
||||
}
|
||||
|
||||
fn load_icon(path: &std::path::Path) -> Option<Icon> {
|
||||
let image = image::open(path).expect("Failed to open icon image");
|
||||
let rgba_image = image.to_rgba8();
|
||||
|
|
@ -117,114 +111,97 @@ impl<'a> App<'a> {
|
|||
self.input_manager.key_released(key)
|
||||
}
|
||||
|
||||
pub fn dt(&self) -> f32 {
|
||||
self.delta_time
|
||||
}
|
||||
|
||||
pub fn quit(&mut self) {
|
||||
self.should_quit = true;
|
||||
}
|
||||
|
||||
pub fn get_time_step(&self) -> f32 {
|
||||
pub fn dt(&self) -> f32 {
|
||||
self.update_timer
|
||||
}
|
||||
pub fn set_time_step(&mut self, time_step: f32) {
|
||||
self.update_timer = time_step;
|
||||
pub fn set_update_rate(&mut self, update_rate: u32) {
|
||||
if update_rate == 0 {
|
||||
self.update_timer = f32::INFINITY;
|
||||
return;
|
||||
}
|
||||
self.update_timer = 1.0/update_rate as f32;
|
||||
}
|
||||
|
||||
fn create_window(app_title: &str, app_icon: &Option<Icon>, window_size: &Option<LogicalSize<u32>>, event_loop: &EventLoop<()>) -> winit::window::Window {
|
||||
fn create_window(app_title: &str, app_icon: &Option<Icon>, window_size: &Option<LogicalSize<u32>>, event_loop: &EventLoop<()>) -> Window {
|
||||
let winit_window = winit::window::WindowBuilder::new()
|
||||
.with_title(app_title);
|
||||
|
||||
let winit_window = if let Some(icon) = app_icon.clone() {
|
||||
winit_window.with_window_icon(Some(icon))
|
||||
}
|
||||
else {
|
||||
winit_window
|
||||
};
|
||||
let winit_window = if let Some(icon) = app_icon.clone() {
|
||||
winit_window.with_taskbar_icon(Some(icon))
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
winit_window
|
||||
};
|
||||
|
||||
let winit_window = if let Some(size) = window_size.clone() {
|
||||
winit_window.with_inner_size(size)
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
winit_window
|
||||
};
|
||||
|
||||
winit_window.build(event_loop).unwrap()
|
||||
}
|
||||
|
||||
async fn run_app<U: Fn(&mut App, &mut Renderer, f32)>(mut self, update: U) {
|
||||
let event_loop = EventLoop::new().unwrap();
|
||||
let window = Self::create_window(self.title, &self.icon, &self.size ,&event_loop);
|
||||
let mut renderer = Renderer::new(&window, self.clear_color.clone()).await.unwrap();
|
||||
window.set_maximized(true);
|
||||
pub fn run<R: Renderer>(mut self, setup: fn(&mut App, &mut R), update: fn(&mut App, &mut R, f32)) {
|
||||
pollster::block_on(async {
|
||||
let event_loop = EventLoop::new().unwrap();
|
||||
let window = Arc::new(Self::create_window(self.title, &self.icon, &self.size ,&event_loop));
|
||||
let mut renderer = R::new(window.clone(), self.clear_color.clone()).await; // Pass Arc<Mutex<Window>> to renderer
|
||||
window.set_maximized(true); // Lock window to set maximized
|
||||
|
||||
if let Some(setup) = self.setup {
|
||||
setup(&mut self.world);
|
||||
}
|
||||
setup(&mut self, &mut renderer);
|
||||
|
||||
renderer.initialize_atlas();
|
||||
let mut time_stack = 0.0;
|
||||
|
||||
let mut time_stack = 0.0;
|
||||
event_loop.run(|event, elwt| {
|
||||
self.delta_time = renderer.update();
|
||||
|
||||
event_loop.run(|event, elwt| {
|
||||
self.delta_time = renderer.update();
|
||||
if self.should_quit {
|
||||
elwt.exit()
|
||||
}
|
||||
|
||||
if self.should_quit {
|
||||
elwt.exit()
|
||||
}
|
||||
self.input_manager.update(&event);
|
||||
|
||||
self.input_manager.update(&event);
|
||||
|
||||
time_stack += self.delta_time;
|
||||
while time_stack > self.update_timer {
|
||||
let time = self.get_time_step();
|
||||
update(&mut self, &mut renderer, time);
|
||||
time_stack -= self.update_timer;
|
||||
}
|
||||
|
||||
renderer.render_scene_2d(self.world());
|
||||
|
||||
match event {
|
||||
Event::WindowEvent { ref event, window_id, }
|
||||
if window_id == renderer.window().id() => {
|
||||
match event {
|
||||
WindowEvent::CloseRequested {} => elwt.exit(),
|
||||
WindowEvent::Resized(physical_size) => {
|
||||
renderer.resize(*physical_size);
|
||||
}
|
||||
WindowEvent::RedrawRequested => {
|
||||
renderer.window().request_redraw();
|
||||
|
||||
match renderer.render() {
|
||||
Ok(_) => {}
|
||||
Err(
|
||||
wgpu::SurfaceError::Lost | wgpu::SurfaceError::Outdated,
|
||||
) => renderer.resize(renderer.size()),
|
||||
Err(wgpu::SurfaceError::OutOfMemory) => {
|
||||
error!("OutOfMemory");
|
||||
elwt.exit();
|
||||
}
|
||||
Err(wgpu::SurfaceError::Timeout) => {
|
||||
warn!("Surface timeout")
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
if self.dt() != f32::INFINITY {
|
||||
time_stack += self.delta_time;
|
||||
while time_stack > self.update_timer {
|
||||
let time = self.dt();
|
||||
update(&mut self, &mut renderer, time);
|
||||
time_stack -= self.update_timer;
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}).unwrap();
|
||||
}
|
||||
|
||||
pub fn run<U: Fn(&mut App, &mut Renderer, f32)>(mut self, update: U) {
|
||||
pollster::block_on(self.run_app(update));
|
||||
match event {
|
||||
Event::WindowEvent { ref event, window_id, } =>
|
||||
match event {
|
||||
WindowEvent::CloseRequested {} => elwt.exit(),
|
||||
WindowEvent::Resized(physical_size) => {
|
||||
renderer.resize(*physical_size);
|
||||
}
|
||||
WindowEvent::RedrawRequested => {
|
||||
window.request_redraw();
|
||||
|
||||
match renderer.render() {
|
||||
Ok(_) => {}
|
||||
Err(wgpu::SurfaceError::Lost | wgpu::SurfaceError::Outdated) => renderer.resize(renderer.size()),
|
||||
Err(wgpu::SurfaceError::OutOfMemory) => {
|
||||
error!("OutOfMemory");
|
||||
elwt.exit();
|
||||
}
|
||||
Err(wgpu::SurfaceError::Timeout) => {
|
||||
warn!("Surface timeout")
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}).unwrap()
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue