use crate::{input::InputState, text::{create_text_object, update_text}, vulkan::{PERF_COUNTER_SIZE, VulkanRenderer, gameobject::{GameObject, GameObjectHandle, Updatable}}}; use super::{GameState, TestGame}; pub struct FpsCounter { pub game_object: GameObjectHandle } impl FpsCounter { pub fn new(game: &mut TestGame, renderer: &mut VulkanRenderer) -> Box { let text_mesh = create_text_object(&mut game.game_state.brush, renderer, "", 30.); Box::new(FpsCounter { game_object: game.add_game_object(renderer, text_mesh) }) } } impl Updatable for FpsCounter { fn update(&mut self, _delta_time: f32, _input: &InputState, game_state: &mut GameState, game_objects: &mut Vec, renderer: &mut VulkanRenderer) { let update_duration = renderer.game_data.update_perf_counters.iter().sum::() / PERF_COUNTER_SIZE as u128; let render_duration = renderer.game_data.render_perf_counters.iter().sum::() / PERF_COUNTER_SIZE as u128; let other_duration = renderer.game_data.other_perf_counters.iter().sum::() / PERF_COUNTER_SIZE as u128; let other_variance = renderer.game_data.other_perf_counters.iter().fold(0, |acc, b| acc + (*b as i128 - other_duration as i128) * (*b as i128 - other_duration as i128)) / PERF_COUNTER_SIZE as i128; let text = format!("Update: {:.0}ms\nRender: {:.0}ms\nTotal: {:.0}ms (±{:.1})\nDelta: {:.0}ms", update_duration as f64 / 1000., render_duration as f64 / 1000., other_duration as f64 / 1000., f64::sqrt(other_variance as f64) / 1000., _delta_time * 1000.); update_text(self.game_object, &text, 30., renderer, &mut game_state.brush, game_objects) } }