summaryrefslogtreecommitdiff
path: root/src/renderer.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/renderer.rs')
-rw-r--r--src/renderer.rs84
1 files changed, 13 insertions, 71 deletions
diff --git a/src/renderer.rs b/src/renderer.rs
index e48f3e4..20edf34 100644
--- a/src/renderer.rs
+++ b/src/renderer.rs
@@ -1,10 +1,9 @@
-use std::{convert::TryInto, mem::size_of, num::NonZeroU32};
+use std::{convert::TryInto, num::NonZeroU32};
use crate::{
- instance::InstanceId,
texture::{TextureError, TextureId},
vertex::SQUARE,
- Camera, ImageFormat, Instance, RenderWindowConfig, Vertex, WgpuTextures,
+ Camera, ImageFormat, Instance, InstanceBuffer, RenderWindowConfig, Vertex, WgpuTextures,
};
use pollster::FutureExt;
use thiserror::Error;
@@ -52,9 +51,7 @@ pub struct Renderer {
render_pipeline: wgpu::RenderPipeline,
square_vertex_buffer: wgpu::Buffer,
square_vertices: u32,
- instance_buffer: wgpu::Buffer,
- instance_buffer_size: usize,
- instances: Vec<Instance>,
+ instances: InstanceBuffer,
camera: Camera,
textures: WgpuTextures,
window: Window,
@@ -121,21 +118,6 @@ impl Renderer {
})
}
- fn new_instance_buffer(
- device: &wgpu::Device,
- instances: &Vec<Instance>,
- ) -> (wgpu::Buffer, usize) {
- let instance_buffer_size = instances.capacity();
- let instance_buffer = device.create_buffer(&wgpu::BufferDescriptor {
- label: Some("Sprite Instance Buffer"),
- size: (instance_buffer_size * size_of::<Instance>()) as wgpu::BufferAddress,
- usage: wgpu::BufferUsages::VERTEX | wgpu::BufferUsages::COPY_DST,
- mapped_at_creation: false,
- });
-
- (instance_buffer, instance_buffer_size)
- }
-
/// Initializes the renderer
///
/// # Errors
@@ -215,9 +197,7 @@ impl Renderer {
});
// create the instance buffer
- let instances = Vec::with_capacity(config.instance_capacity);
- let (instance_buffer, instance_buffer_size) =
- Self::new_instance_buffer(&device, &instances);
+ let instances = InstanceBuffer::new(&device, config.instance_capacity);
// TODO make this configurable
let (textures, texture_layout) = WgpuTextures::new(
@@ -246,8 +226,6 @@ impl Renderer {
render_pipeline,
square_vertex_buffer,
square_vertices,
- instance_buffer,
- instance_buffer_size,
instances,
camera,
textures,
@@ -291,27 +269,14 @@ impl Renderer {
self.window.set_title(title);
}
- /// 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)
+ /// The reference buffer
+ pub const fn instances(&self) -> &InstanceBuffer {
+ &self.instances
}
- /// Get an immutable reference to an instance
- pub fn instance(&self, id: InstanceId) -> Option<&Instance> {
- self.instances.get(id.0)
- }
-
- /// 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();
+ /// The reference buffer
+ pub fn instances_mut(&mut self) -> &mut InstanceBuffer {
+ &mut self.instances
}
/// Get the camera information
@@ -358,24 +323,6 @@ impl Renderer {
self.textures.clear_textures();
}
- fn expand_instance_buffer(&mut self) {
- (self.instance_buffer, self.instance_buffer_size) =
- Self::new_instance_buffer(&self.device, &self.instances);
- }
-
- #[profiling::function]
- fn fill_instance_buffer(&mut self) {
- if self.instances.len() > self.instance_buffer_size {
- self.expand_instance_buffer();
- }
-
- self.queue.write_buffer(
- &self.instance_buffer,
- 0 as wgpu::BufferAddress,
- bytemuck::cast_slice(&self.instances),
- );
- }
-
/// Renders a new frame to the window
///
/// # Errors
@@ -399,13 +346,8 @@ impl Renderer {
label: Some("Render Encoder"),
});
- self.fill_instance_buffer();
- let num_instances = self
- .instances
- .len()
- .try_into()
- .expect("expected less than 3 billion instances");
-
+ let num_instances = self.instances.len();
+ self.instances.fill_buffer(&self.device, &self.queue);
self.camera.refresh(&self.queue);
self.textures.fill_textures(&self.queue);
@@ -428,7 +370,7 @@ impl Renderer {
render_pass.set_bind_group(0, self.camera.bind_group(), &[]);
render_pass.set_bind_group(1, self.textures.bind_group(), &[]);
render_pass.set_vertex_buffer(0, self.square_vertex_buffer.slice(..));
- render_pass.set_vertex_buffer(1, self.instance_buffer.slice(..));
+ render_pass.set_vertex_buffer(1, self.instances.buffer_slice());
render_pass.draw(0..self.square_vertices, 0..num_instances);
}
// the encoder can't finish building the command buffer until the