From 09df670b8e45a3ffe2853773e648b80b6b6d6254 Mon Sep 17 00:00:00 2001 From: Micha White Date: Thu, 20 Oct 2022 23:00:17 -0400 Subject: Added a bunnymark --- alligator_render/Cargo.toml | 3 + alligator_render/examples/black.rs | 2 +- alligator_render/examples/bmp.rs | 2 +- alligator_render/examples/bunnymark.rs | 126 +++++++++++++++++++++++++++++++++ alligator_render/examples/res/bunny.ff | Bin 0 -> 8208 bytes alligator_render/src/lib.rs | 4 +- alligator_render/src/renderer.rs | 2 +- alligator_render/src/texture.rs | 1 + 8 files changed, 136 insertions(+), 4 deletions(-) create mode 100644 alligator_render/examples/bunnymark.rs create mode 100644 alligator_render/examples/res/bunny.ff (limited to 'alligator_render') diff --git a/alligator_render/Cargo.toml b/alligator_render/Cargo.toml index 01c5738..e633fb9 100644 --- a/alligator_render/Cargo.toml +++ b/alligator_render/Cargo.toml @@ -31,3 +31,6 @@ name = "black" [[example]] name = "bmp" + +[[example]] +name = "bunnymark" diff --git a/alligator_render/examples/black.rs b/alligator_render/examples/black.rs index c66b080..622429f 100644 --- a/alligator_render/examples/black.rs +++ b/alligator_render/examples/black.rs @@ -17,5 +17,5 @@ fn main() { let renderer = Renderer::new(&config).unwrap(); println!("Startup time: {:?}", start.elapsed()); - renderer.run(&update); + renderer.run(Box::leak(Box::new(update))); } diff --git a/alligator_render/examples/bmp.rs b/alligator_render/examples/bmp.rs index af71863..23842a9 100644 --- a/alligator_render/examples/bmp.rs +++ b/alligator_render/examples/bmp.rs @@ -84,5 +84,5 @@ fn main() { ..Default::default() }); - renderer.run(&update); + renderer.run(Box::leak(Box::new(update))); } diff --git a/alligator_render/examples/bunnymark.rs b/alligator_render/examples/bunnymark.rs new file mode 100644 index 0000000..759d725 --- /dev/null +++ b/alligator_render/examples/bunnymark.rs @@ -0,0 +1,126 @@ +#![feature(once_cell)] +#![feature(let_else)] + +use std::{num::NonZeroU32, time::Instant}; + +use alligator_render::{ + ImageFormat, Instance, InstanceId, RenderWindowConfig, Renderer, TextureId, +}; + +#[derive(Debug)] +struct State { + texture_id: TextureId, + bunnies: Vec, + previous_timestamp: Option, + stopped: bool, +} + +impl State { + fn new(texture_id: TextureId) -> Self { + Self { + texture_id, + bunnies: Vec::with_capacity(10_000_000), + previous_timestamp: None, + stopped: false, + } + } + + #[profiling::function] + fn update(&mut self, renderer: &mut Renderer) { + let Some(instant) = self.previous_timestamp else { + self.previous_timestamp = Some(Instant::now()); + return; + }; + + let frame_time = instant.elapsed(); + let fps = 1.0 / frame_time.as_secs_f32(); + + renderer.set_title(&format!( + "BunnyMark - {} bunnies - {} FPS", + self.bunnies.len(), + fps.round() + )); + + if fps < 15.0 { + self.stopped = true; + } + + self.previous_timestamp = Some(Instant::now()); + + if self.stopped { + return; + } + + for bunny in self.bunnies.iter_mut() { + let instance = renderer + .instances_mut() + .get_instance_mut(bunny.instance_id) + .unwrap(); + + instance.position[0] += bunny.velocity_x; + instance.position[1] += bunny.velocity_y; + + if !(-1.5..1.5).contains(&instance.position[0]) { + instance.position[0] = instance.position[0].clamp(-1.0, 1.0); + bunny.velocity_x = -bunny.velocity_x; + } + + if !(-0.75..0.75).contains(&instance.position[1]) { + instance.position[1] = instance.position[1].clamp(-0.5, 0.5); + bunny.velocity_y *= -0.90; + } + + bunny.velocity_y -= 0.005; + } + + for _ in 0..=(fps as u64 * 50) { + let texture_x = renderer.textures().texture_x(self.texture_id).unwrap(); + let texture_y = renderer.textures().texture_x(self.texture_id).unwrap(); + let texture_height = renderer.textures().texture_height(self.texture_id).unwrap(); + let texture_width = renderer.textures().texture_width(self.texture_id).unwrap(); + let instance_id = renderer.instances_mut().push_instance(Instance { + texture_coordinates: [texture_x, texture_y], + texture_size: [texture_width, texture_height], + size: [0.1, 0.1], + position: [-1.5, 0.70], + ..Default::default() + }); + + let velocity_x = fps.fract() / 24.0; + let velocity_y = 0.0; + self.bunnies.push(Bunny { + instance_id, + velocity_x, + velocity_y, + }); + } + } +} + +#[derive(Debug, Clone, Copy)] +struct Bunny { + instance_id: InstanceId, + velocity_x: f32, + velocity_y: f32, +} + +fn main() { + // configure the render window + let config = RenderWindowConfig { + title: "BunnyMark", + instance_capacity: 10_000_000, + default_width: NonZeroU32::new(1280).unwrap(), + default_height: NonZeroU32::new(720).unwrap(), + vsync: false, + ..Default::default() + }; + + let bunny = include_bytes!("res/bunny.ff"); + let mut renderer = Renderer::new(&config).unwrap(); + let texture_id = renderer + .textures_mut() + .load_from_memory(bunny, ImageFormat::Farbfeld) + .unwrap(); + let state = Box::leak(Box::new(State::new(texture_id))); + renderer.run(Box::leak(Box::new(|r| state.update(r)))); +} diff --git a/alligator_render/examples/res/bunny.ff b/alligator_render/examples/res/bunny.ff new file mode 100644 index 0000000..64c5a69 Binary files /dev/null and b/alligator_render/examples/res/bunny.ff differ diff --git a/alligator_render/src/lib.rs b/alligator_render/src/lib.rs index f5403f2..debb68c 100644 --- a/alligator_render/src/lib.rs +++ b/alligator_render/src/lib.rs @@ -13,10 +13,12 @@ mod texture; mod vertex; pub(crate) use camera::Camera; -pub use config::RenderWindowConfig; +pub use config::*; pub use instance::Instance; pub(crate) use instance::InstanceBuffer; +pub use instance::InstanceId; pub use renderer::Renderer; pub use texture::ImageFormat; pub(crate) use texture::TextureAtlas; +pub use texture::TextureId; pub(crate) use vertex::Vertex; diff --git a/alligator_render/src/renderer.rs b/alligator_render/src/renderer.rs index afcb92b..ec3cac5 100644 --- a/alligator_render/src/renderer.rs +++ b/alligator_render/src/renderer.rs @@ -372,7 +372,7 @@ impl Renderer { } /// Run the renderer indefinitely - pub fn run(mut self, f: &'static dyn Fn(&mut Self)) -> ! { + pub fn run(mut self, f: &'static mut dyn FnMut(&mut Self)) -> ! { self.window.set_visible(true); let event_loop = self.event_loop(); event_loop.run(move |event, _, control_flow| match event { diff --git a/alligator_render/src/texture.rs b/alligator_render/src/texture.rs index e343508..0eacb5b 100644 --- a/alligator_render/src/texture.rs +++ b/alligator_render/src/texture.rs @@ -19,6 +19,7 @@ pub struct TextureId(usize); impl TextureId { #[allow(clippy::new_without_default)] + #[must_use] pub fn new() -> Self { Self(NEXT_TEXTURE_ID.fetch_add(1, Ordering::Relaxed)) } -- cgit v1.2.3