-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Fixes #249
- Loading branch information
Showing
39 changed files
with
1,912 additions
and
823 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,185 @@ | ||
use std::time::Instant; | ||
|
||
use orbital::{ | ||
app::{App, AppChange}, | ||
cgmath::Vector2, | ||
game::{CacheSettings, World, WorldChange}, | ||
input::InputState, | ||
log::{debug, info, warn}, | ||
renderer::Renderer, | ||
resources::realizations::{Material, Pipeline}, | ||
timer::Timer, | ||
wgpu::{Device, Queue, SurfaceConfiguration, TextureView}, | ||
}; | ||
|
||
use crate::game::elements::{ | ||
camera::Camera, damaged_helmet::DamagedHelmet, debug_world_environment::DebugWorldEnvironment, | ||
lights::Lights, pbr_spheres::PBRSpheres, ping_pong::PingPongElement, | ||
}; | ||
|
||
pub struct MyApp<RendererImpl: Renderer + Send> { | ||
renderer: Option<RendererImpl>, | ||
world: World, | ||
timer: Timer, | ||
cache_settings_pipelines: CacheSettings, | ||
cache_settings_materials: CacheSettings, | ||
cache_timer_pipelines: Instant, | ||
cache_timer_materials: Instant, | ||
} | ||
|
||
impl<RenderImpl: Renderer + Send> MyApp<RenderImpl> { | ||
pub fn new( | ||
cache_settings_pipelines: CacheSettings, | ||
cache_settings_materials: CacheSettings, | ||
) -> Self { | ||
Self { | ||
renderer: None, | ||
world: World::new(), | ||
timer: Timer::new(), | ||
cache_settings_pipelines, | ||
cache_settings_materials, | ||
cache_timer_pipelines: Instant::now(), | ||
cache_timer_materials: Instant::now(), | ||
} | ||
} | ||
|
||
fn on_startup(&mut self) { | ||
// Debug | ||
self.world | ||
.process_world_change(WorldChange::SpawnElement(Box::new( | ||
DebugWorldEnvironment::new(), | ||
))); | ||
|
||
// Camera & Lights | ||
self.world | ||
.process_world_change(WorldChange::SpawnElement(Box::new(Camera::new()))); | ||
self.world | ||
.process_world_change(WorldChange::SpawnElement(Box::new(Lights {}))); | ||
|
||
// Ping Pong | ||
self.world | ||
.process_world_change(WorldChange::SpawnElement(Box::new(PingPongElement::new( | ||
true, | ||
)))); | ||
self.world | ||
.process_world_change(WorldChange::SpawnElement(Box::new(PingPongElement::new( | ||
false, | ||
)))); | ||
|
||
// Models | ||
self.world | ||
.process_world_change(WorldChange::SpawnElement(Box::new(PBRSpheres {}))); | ||
self.world | ||
.process_world_change(WorldChange::SpawnElement(Box::new(DamagedHelmet {}))); | ||
} | ||
|
||
fn cache_cleanup(&mut self) { | ||
self.cache_cleanup_pipelines(); | ||
self.cache_cleanup_materials(); | ||
} | ||
|
||
fn cache_cleanup_pipelines(&mut self) { | ||
if self.cache_timer_pipelines.elapsed() < self.cache_settings_pipelines.cleanup_interval { | ||
return; | ||
} | ||
|
||
// Cache access | ||
let cache = Pipeline::prepare_cache_access(None); | ||
|
||
// Run cleanup | ||
let change = cache.cleanup(self.cache_settings_pipelines.retain_period); | ||
info!("Pipeline {}", change); | ||
|
||
// Print out duration | ||
debug!( | ||
"Pipeline Cache Cleanup took {}ms!", | ||
self.cache_timer_pipelines.elapsed().as_millis() | ||
); | ||
|
||
self.cache_timer_pipelines = Instant::now(); | ||
} | ||
|
||
fn cache_cleanup_materials(&mut self) { | ||
if self.cache_timer_materials.elapsed() < self.cache_settings_materials.cleanup_interval { | ||
return; | ||
} | ||
|
||
// Cache access | ||
let cache = Material::prepare_cache_access(); | ||
|
||
// Run cleanup | ||
let change = cache.cleanup(self.cache_settings_materials.retain_period); | ||
info!("Material {}", change); | ||
|
||
// Print out duration | ||
debug!( | ||
"Material Cache Cleanup took {}ms!", | ||
self.cache_timer_materials.elapsed().as_millis() | ||
); | ||
|
||
self.cache_timer_materials = Instant::now(); | ||
} | ||
} | ||
|
||
impl<RenderImpl: Renderer + Send> App for MyApp<RenderImpl> { | ||
async fn on_resume(&mut self, config: &SurfaceConfiguration, device: &Device, queue: &Queue) { | ||
self.renderer = Some(RenderImpl::new( | ||
config.format, | ||
Vector2::new(config.width, config.height), | ||
device, | ||
queue, | ||
)); | ||
|
||
if self.world.models().is_empty() { | ||
self.on_startup(); | ||
} | ||
} | ||
|
||
async fn on_suspend(&mut self) { | ||
self.renderer = None; | ||
} | ||
|
||
async fn on_resize(&mut self, new_size: Vector2<u32>, device: &Device, queue: &Queue) | ||
where | ||
Self: Sized, | ||
{ | ||
if let Some(renderer) = &mut self.renderer { | ||
renderer.change_resolution(new_size, device, queue); | ||
} else { | ||
warn!("Received resize event, but Renderer doesn't exist (yet?)"); | ||
} | ||
} | ||
|
||
async fn on_update(&mut self, input_state: &InputState) -> Option<Vec<AppChange>> | ||
where | ||
Self: Sized, | ||
{ | ||
let delta_time = self.timer.cycle_delta_time(); | ||
let app_changes = self.world.update(delta_time, input_state).await; // TODO: ? | ||
|
||
// TODO: Needed? | ||
if let Some(renderer) = &mut self.renderer { | ||
renderer.update(delta_time); | ||
} | ||
|
||
(!app_changes.is_empty()).then_some(app_changes) | ||
} | ||
|
||
async fn on_render(&mut self, target_view: &TextureView, device: &Device, queue: &Queue) | ||
where | ||
Self: Sized, | ||
{ | ||
self.world.prepare_render(device, queue); | ||
|
||
if let Some(renderer) = &mut self.renderer { | ||
renderer.render(target_view, device, queue, &self.world); | ||
} | ||
|
||
if let Some((delta_time, fps)) = self.timer.tick() { | ||
debug!("FPS: {fps}"); | ||
debug!("Tick Delta: {} ms", delta_time); | ||
|
||
self.cache_cleanup(); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,18 +1,17 @@ | ||
use orbital::{ | ||
game::{GameRuntime, GameSettings}, | ||
logging, | ||
renderer::StandardRenderer, | ||
winit::{error::EventLoopError, event_loop::EventLoop}, | ||
app::{AppRuntime, AppSettings}, game::CacheSettings, logging, renderer::StandardRenderer, winit::{error::EventLoopError, event_loop::EventLoop} | ||
}; | ||
|
||
use crate::game::ExampleGame; | ||
use crate::app::MyApp; | ||
|
||
pub fn entrypoint(event_loop_result: Result<EventLoop<()>, EventLoopError>) { | ||
logging::init(); | ||
|
||
let event_loop = event_loop_result.expect("Event Loop failure"); | ||
let settings = GameSettings::default(); | ||
|
||
GameRuntime::<ExampleGame, StandardRenderer>::liftoff(event_loop, settings) | ||
.expect("Runtime failure"); | ||
let app_settings = AppSettings::default(); | ||
|
||
let app = MyApp::<StandardRenderer>::new(CacheSettings::default(), CacheSettings::default()); | ||
|
||
AppRuntime::liftoff(event_loop, app_settings, app).expect("Runtime failure"); | ||
} |
Oops, something went wrong.