| @@ -0,0 +1,61 @@ | |||||
| #![allow(dead_code)] | |||||
| use std::mem::take; | |||||
| use std::time::Instant; | |||||
| pub struct FrameCounter { | |||||
| last_frame: Instant, | |||||
| time: f32, | |||||
| count: usize, | |||||
| fps: usize, | |||||
| delta: f32, | |||||
| } | |||||
| impl FrameCounter { | |||||
| #[inline] | |||||
| pub fn fps(&self) -> usize { | |||||
| self.fps | |||||
| } | |||||
| #[inline] | |||||
| pub fn delta(&self) -> f32 { | |||||
| self.delta | |||||
| } | |||||
| #[inline] | |||||
| pub fn next(&mut self) -> bool { | |||||
| let now = Instant::now(); | |||||
| self.delta = (now - self.last_frame).as_secs_f32(); | |||||
| self.last_frame = now; | |||||
| self.time += self.delta; | |||||
| self.count += 1; | |||||
| if self.time >= 2.0 { | |||||
| self.time = 0.0; | |||||
| self.fps = 0; | |||||
| self.count = 0; | |||||
| true | |||||
| } else if self.time >= 1.0 { | |||||
| self.time -= 1.0; | |||||
| self.fps = take(&mut self.count); | |||||
| true | |||||
| } else { | |||||
| false | |||||
| } | |||||
| } | |||||
| } | |||||
| impl Default for FrameCounter { | |||||
| fn default() -> Self { | |||||
| Self { | |||||
| last_frame: Instant::now(), | |||||
| time: 0.0, | |||||
| count: 0, | |||||
| fps: 0, | |||||
| delta: 0.0, | |||||
| } | |||||
| } | |||||
| } | |||||
| @@ -1,4 +1,5 @@ | |||||
| pub mod camera; | pub mod camera; | ||||
| pub mod events; | pub mod events; | ||||
| pub mod frame_counter; | |||||
| pub mod geometry; | pub mod geometry; | ||||
| pub mod window; | pub mod window; | ||||
| @@ -33,7 +33,7 @@ impl Window { | |||||
| .with_hardware_acceleration(Some(true)) | .with_hardware_acceleration(Some(true)) | ||||
| .with_pixel_format(24, 8) | .with_pixel_format(24, 8) | ||||
| .with_multisampling(*multisampling) | .with_multisampling(*multisampling) | ||||
| .with_vsync(true) | |||||
| .with_vsync(false) | |||||
| .with_gl(GlRequest::Specific(Api::OpenGl, (4, 5))) | .with_gl(GlRequest::Specific(Api::OpenGl, (4, 5))) | ||||
| .with_gl_profile(GlProfile::Core) | .with_gl_profile(GlProfile::Core) | ||||
| .build_windowed(window_builder, event_loop); | .build_windowed(window_builder, event_loop); | ||||
| @@ -2,24 +2,28 @@ use glc::{ | |||||
| misc::Bindable, | misc::Bindable, | ||||
| shader::{Program, Shader, Type}, | shader::{Program, Shader, Type}, | ||||
| }; | }; | ||||
| use log::error; | |||||
| use log::{error, info}; | |||||
| use shrev::{EventChannel, ReaderId}; | use shrev::{EventChannel, ReaderId}; | ||||
| use specs::{ReadExpect, System, World, WriteExpect}; | use specs::{ReadExpect, System, World, WriteExpect}; | ||||
| use crate::Error; | use crate::Error; | ||||
| use super::super::misc::{camera::Camera, events::WindowEvent, geometry::Geometry}; | |||||
| use super::super::misc::{ | |||||
| camera::Camera, events::WindowEvent, frame_counter::FrameCounter, geometry::Geometry, | |||||
| }; | |||||
| /* Global */ | /* Global */ | ||||
| pub struct Global { | pub struct Global { | ||||
| pub camera: Camera, | pub camera: Camera, | ||||
| pub frame_counter: FrameCounter, | |||||
| } | } | ||||
| impl Global { | impl Global { | ||||
| pub fn new() -> Result<Self, Error> { | pub fn new() -> Result<Self, Error> { | ||||
| Ok(Self { | Ok(Self { | ||||
| camera: Camera::new()?, | camera: Camera::new()?, | ||||
| frame_counter: FrameCounter::default(), | |||||
| }) | }) | ||||
| } | } | ||||
| } | } | ||||
| @@ -82,6 +86,10 @@ impl<'a> System<'a> for Init { | |||||
| } | } | ||||
| } | } | ||||
| if global.frame_counter.next() { | |||||
| info!("FPS: {}", global.frame_counter.fps()); | |||||
| } | |||||
| self.program.bind(); | self.program.bind(); | ||||
| geometry.render_quad(); | geometry.render_quad(); | ||||
| self.program.unbind(); | self.program.unbind(); | ||||
| @@ -40,10 +40,14 @@ impl Test { | |||||
| } | } | ||||
| impl<'a> System<'a> for Test { | impl<'a> System<'a> for Test { | ||||
| type SystemData = ReadExpect<'a, Geometry>; | |||||
| fn run(&mut self, geometry: Self::SystemData) { | |||||
| self.model = self.model * Matrix4f::rotate(Vector3f::new(0.0, 0.0, 1.0), Angle::Deg(0.01)); | |||||
| type SystemData = (ReadExpect<'a, Global>, ReadExpect<'a, Geometry>); | |||||
| fn run(&mut self, (global, geometry): Self::SystemData) { | |||||
| self.model = self.model | |||||
| * Matrix4f::rotate( | |||||
| Vector3f::new(0.0, 0.0, 1.0), | |||||
| Angle::Deg(10.0 * global.frame_counter.delta()), | |||||
| ); | |||||
| self.program.bind(); | self.program.bind(); | ||||
| self.program.uniform(1, Uniform::Matrix4f(&self.model)); | self.program.uniform(1, Uniform::Matrix4f(&self.model)); | ||||