diff options
| -rw-r--r-- | Cargo.toml | 5 | ||||
| -rw-r--r-- | examples/square.rs | 19 | ||||
| -rw-r--r-- | src/config.rs | 5 | ||||
| -rw-r--r-- | src/instance.rs | 3 | ||||
| -rw-r--r-- | src/lib.rs | 4 | ||||
| -rw-r--r-- | src/renderer.rs | 22 |
6 files changed, 53 insertions, 5 deletions
@@ -14,4 +14,7 @@ pollster = "0.2" bytemuck = { version = "1.4", features = ["derive"] } [[example]] -name = "black"
\ No newline at end of file +name = "black" + +[[example]] +name = "square"
\ No newline at end of file diff --git a/examples/square.rs b/examples/square.rs new file mode 100644 index 0000000..f9b9223 --- /dev/null +++ b/examples/square.rs @@ -0,0 +1,19 @@ +#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")] + +use alligator_render::{Instance, RenderWindowConfig, Renderer}; +use winit::event_loop::EventLoop; + +fn main() { + // configure the render window + let config = RenderWindowConfig { + title: "Pokemon: Black and White (New Edition)".into(), + instance_capacity: 1, + ..Default::default() + }; + + let event_loop = EventLoop::new(); + let mut renderer = Renderer::new(&config, &event_loop).unwrap(); + renderer.push_instance(Instance::default()); + + renderer.run(event_loop); +} diff --git a/src/config.rs b/src/config.rs index f321a9b..e9f9ca4 100644 --- a/src/config.rs +++ b/src/config.rs @@ -66,6 +66,10 @@ pub struct RenderWindowConfig<'a> { /// If true, Fifo mode is used to present frames. If false, then Mailbox or /// Immediate will be used if available. Otherwise, Fifo will be used. pub vsync: bool, + /// The initial capacity of the instance buffer. The size will increase if + /// it's not large enough. Increasing this value may improve performance + /// towards the beginning, if a lot of instances are being created. + pub instance_capacity: usize } impl<'a> Default for RenderWindowConfig<'a> { @@ -77,6 +81,7 @@ impl<'a> Default for RenderWindowConfig<'a> { title: "Alligator Game".into(), low_power: true, vsync: true, + instance_capacity: 0, } } } diff --git a/src/instance.rs b/src/instance.rs index 6de0133..554d02d 100644 --- a/src/instance.rs +++ b/src/instance.rs @@ -2,6 +2,9 @@ use std::mem::size_of; use bytemuck::{Pod, Zeroable}; +#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] +pub struct InstanceId(pub(crate) usize); + #[repr(C)] #[derive(Copy, Clone, Debug, PartialEq, Pod, Zeroable)] pub struct Instance { @@ -5,11 +5,11 @@ #![allow(clippy::module_name_repetitions)] pub mod config; -mod instance; +pub mod instance; pub mod renderer; mod vertex; pub use config::RenderWindowConfig; -pub(crate) use instance::Instance; +pub use instance::Instance; pub use renderer::Renderer; pub(crate) use vertex::Vertex; diff --git a/src/renderer.rs b/src/renderer.rs index 75e6d1e..81e1a3f 100644 --- a/src/renderer.rs +++ b/src/renderer.rs @@ -1,6 +1,6 @@ use std::convert::TryInto; -use crate::{vertex::SQUARE, Instance, RenderWindowConfig, Vertex}; +use crate::{instance::InstanceId, vertex::SQUARE, Instance, RenderWindowConfig, Vertex}; use pollster::FutureExt; use thiserror::Error; use wgpu::{include_wgsl, util::DeviceExt}; @@ -172,7 +172,7 @@ impl Renderer { usage: wgpu::BufferUsages::VERTEX, }); - let instances = Vec::new(); + let instances = Vec::with_capacity(config.instance_capacity); Ok(Self { surface, @@ -199,6 +199,24 @@ impl Renderer { self.surface.configure(&self.device, &self.surface_config); } + /// Add an instance to the renderer, and returns an `InstanceId` to the + /// instance. This id becomes invalid if the instances are cleared. + pub fn push_instance(&mut self, instance: Instance) -> InstanceId { + let index = self.instances.len(); + self.instances.push(instance); + InstanceId(index) + } + + /// Get a mutable reference to an instance + pub fn instance_mut(&mut self, id: InstanceId) -> Option<&mut Instance> { + self.instances.get_mut(id.0) + } + + /// Clears the list of instances, making all instance ID's invalid + pub fn clear_instances(&mut self) { + self.instances.clear(); + } + /// Renders a new frame to the window /// /// # Errors |
