summaryrefslogtreecommitdiff
path: root/src/renderer.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/renderer.rs')
-rw-r--r--src/renderer.rs128
1 files changed, 16 insertions, 112 deletions
diff --git a/src/renderer.rs b/src/renderer.rs
index 516b1b1..2c26836 100644
--- a/src/renderer.rs
+++ b/src/renderer.rs
@@ -5,9 +5,8 @@ use crate::{
instance::InstanceId,
texture::{TextureError, TextureId},
vertex::SQUARE,
- Camera, ImageFormat, Instance, RenderWindowConfig, TextureAtlases, Vertex,
+ Camera, ImageFormat, Instance, RenderWindowConfig, Vertex, WgpuTextures,
};
-use image::{EncodableLayout, GenericImage};
use pollster::FutureExt;
use thiserror::Error;
use wgpu::{include_wgsl, util::DeviceExt};
@@ -60,11 +59,7 @@ pub struct Renderer {
camera: Camera,
camera_buffer: wgpu::Buffer,
camera_bind_group: wgpu::BindGroup,
- textures: TextureAtlases<'static>,
- texture_size: wgpu::Extent3d,
- diffuse_texture: wgpu::Texture,
- diffuse_bind_group: wgpu::BindGroup,
- image: image::RgbaImage,
+ textures: WgpuTextures,
window: Window,
}
@@ -248,70 +243,16 @@ impl Renderer {
Self::new_instance_buffer(&device, &instances);
// TODO make this configurable
- let textures = TextureAtlases::new(window.inner_size().width, window.inner_size().height);
- let texture_size = textures.extent_3d(); // textures.extent_3d();
- let diffuse_texture = device.create_texture(&wgpu::TextureDescriptor {
- label: Some("diffuse texture"),
- size: texture_size,
- mip_level_count: 1,
- sample_count: 1,
- dimension: wgpu::TextureDimension::D2,
- format: wgpu::TextureFormat::Rgba8UnormSrgb,
- usage: wgpu::TextureUsages::TEXTURE_BINDING | wgpu::TextureUsages::COPY_DST,
- });
- // TODO I don't think this refreshes anything
- let diffuse_texture_view =
- diffuse_texture.create_view(&wgpu::TextureViewDescriptor::default());
- // TODO make this configurable
- let diffuse_sampler = device.create_sampler(&wgpu::SamplerDescriptor::default());
- let texture_bind_group_layout =
- device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
- label: Some("Texture Bind Group Layout"),
- entries: &[
- wgpu::BindGroupLayoutEntry {
- binding: 0,
- visibility: wgpu::ShaderStages::FRAGMENT,
- ty: wgpu::BindingType::Texture {
- sample_type: wgpu::TextureSampleType::Float { filterable: true },
- view_dimension: wgpu::TextureViewDimension::D2,
- multisampled: false,
- },
- count: None,
- },
- wgpu::BindGroupLayoutEntry {
- binding: 1,
- visibility: wgpu::ShaderStages::FRAGMENT,
- ty: wgpu::BindingType::Sampler(wgpu::SamplerBindingType::Filtering),
- count: None,
- },
- ],
- });
- let diffuse_bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor {
- label: Some("Diffuse Bind Group"),
- layout: &texture_bind_group_layout,
- entries: &[
- wgpu::BindGroupEntry {
- binding: 0,
- resource: wgpu::BindingResource::TextureView(&diffuse_texture_view),
- },
- wgpu::BindGroupEntry {
- binding: 1,
- resource: wgpu::BindingResource::Sampler(&diffuse_sampler),
- },
- ],
- });
- // TODO make this all resizable
- let image = image::RgbaImage::from_vec(
- texture_size.width,
- texture_size.height,
- vec![0; 4 * texture_size.width as usize * texture_size.height as usize],
- )
- .unwrap();
+ let (textures, texture_layout) = WgpuTextures::new(
+ &device,
+ window.inner_size().width,
+ window.inner_size().height,
+ );
let render_pipeline_layout =
device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
label: Some("Sprite Render Pipeline Layout"),
- bind_group_layouts: &[&camera_bind_group_layout, &texture_bind_group_layout],
+ bind_group_layouts: &[&camera_bind_group_layout, &texture_layout],
push_constant_ranges: &[],
});
@@ -335,10 +276,6 @@ impl Renderer {
camera_buffer,
camera_bind_group,
textures,
- texture_size,
- diffuse_texture,
- diffuse_bind_group,
- image,
window,
})
}
@@ -418,36 +355,28 @@ impl Renderer {
///
/// This returns an error if the texture is not in the given format, or if
/// the texture is so large that it cannot fit in the texture atlas.
- pub fn texture_from_mem(
+ pub fn texture_from_memory(
&mut self,
texture: &[u8],
format: ImageFormat,
) -> Result<TextureId, TextureError> {
- self.textures.load_from_memory(texture, format)
+ self.textures.texture_from_memory(texture, format)
}
pub fn texture_width(&self, id: TextureId) -> Option<f32> {
- self.textures
- .texture_width(id)
- .map(|u| u as f32 / self.texture_size.width as f32)
+ self.textures.texture_width(id)
}
pub fn texture_height(&self, id: TextureId) -> Option<f32> {
- self.textures
- .texture_height(id)
- .map(|u| u as f32 / self.texture_size.height as f32)
+ self.textures.texture_height(id)
}
pub fn texture_x(&self, id: TextureId) -> Option<f32> {
- self.textures
- .texture_x(id)
- .map(|u| u as f32 / self.texture_size.width as f32)
+ self.textures.texture_x(id)
}
pub fn texture_y(&self, id: TextureId) -> Option<f32> {
- self.textures
- .texture_y(id)
- .map(|u| u as f32 / self.texture_size.height as f32)
+ self.textures.texture_y(id)
}
fn expand_instance_buffer(&mut self) {
@@ -475,31 +404,6 @@ impl Renderer {
);
}
- // TODO optimize this
- fn fill_textures(&mut self) {
- // put the packed texture into the base image
- let Ok(atlases) = self.textures.atlases() else { return };
- let Some(atlas) = atlases.first() else { return };
- self.image.copy_from(atlas, 0, 0).unwrap();
-
- // copy that to the gpu
- self.queue.write_texture(
- wgpu::ImageCopyTexture {
- texture: &self.diffuse_texture,
- mip_level: 0,
- origin: wgpu::Origin3d::ZERO,
- aspect: wgpu::TextureAspect::All,
- },
- self.image.as_bytes(),
- wgpu::ImageDataLayout {
- offset: 0,
- bytes_per_row: NonZeroU32::new(self.texture_size.width * 4),
- rows_per_image: NonZeroU32::new(self.texture_size.height),
- },
- self.texture_size,
- );
- }
-
/// Renders a new frame to the window
///
/// # Errors
@@ -530,7 +434,7 @@ impl Renderer {
.expect("expected less than 3 billion instances");
self.refresh_camera_buffer();
- self.fill_textures();
+ self.textures.fill_textures(&self.queue);
{
let mut render_pass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
@@ -548,7 +452,7 @@ impl Renderer {
render_pass.set_pipeline(&self.render_pipeline);
render_pass.set_bind_group(0, &self.camera_bind_group, &[]);
- render_pass.set_bind_group(1, &self.diffuse_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.draw(0..self.square_vertices, 0..num_instances);