From 9ddfaf3ee73cef3e7bd122f4d11893f77647c2c3 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Tue, 14 Nov 2023 14:41:48 +0100 Subject: Rename `cubes` to `scene` in `custom_shader` example --- examples/custom_shader/src/scene.rs | 99 +++++++++++++++++++++++++++++++++++++ 1 file changed, 99 insertions(+) create mode 100644 examples/custom_shader/src/scene.rs (limited to 'examples/custom_shader/src/scene.rs') diff --git a/examples/custom_shader/src/scene.rs b/examples/custom_shader/src/scene.rs new file mode 100644 index 00000000..ab923093 --- /dev/null +++ b/examples/custom_shader/src/scene.rs @@ -0,0 +1,99 @@ +use crate::camera::Camera; +use crate::primitive; +use crate::primitive::cube::Cube; +use glam::Vec3; +use iced::widget::shader; +use iced::{mouse, Color, Rectangle}; +use rand::Rng; +use std::cmp::Ordering; +use std::iter; +use std::time::Duration; + +pub const MAX: u32 = 500; + +#[derive(Clone)] +pub struct Scene { + pub size: f32, + pub cubes: Vec, + pub camera: Camera, + pub show_depth_buffer: bool, + pub light_color: Color, +} + +impl Scene { + pub fn new() -> Self { + let mut scene = Self { + size: 0.2, + cubes: vec![], + camera: Camera::default(), + show_depth_buffer: false, + light_color: Color::WHITE, + }; + + scene.change_amount(MAX); + + scene + } + + pub fn update(&mut self, time: Duration) { + for cube in self.cubes.iter_mut() { + cube.update(self.size, time.as_secs_f32()); + } + } + + pub fn change_amount(&mut self, amount: u32) { + let curr_cubes = self.cubes.len() as u32; + + match amount.cmp(&curr_cubes) { + Ordering::Greater => { + // spawn + let cubes_2_spawn = (amount - curr_cubes) as usize; + + let mut cubes = 0; + self.cubes.extend(iter::from_fn(|| { + if cubes < cubes_2_spawn { + cubes += 1; + Some(Cube::new(self.size, rnd_origin())) + } else { + None + } + })); + } + Ordering::Less => { + // chop + let cubes_2_cut = curr_cubes - amount; + let new_len = self.cubes.len() - cubes_2_cut as usize; + self.cubes.truncate(new_len); + } + Ordering::Equal => {} + } + } +} + +impl shader::Program for Scene { + type State = (); + type Primitive = primitive::Primitive; + + fn draw( + &self, + _state: &Self::State, + _cursor: mouse::Cursor, + bounds: Rectangle, + ) -> Self::Primitive { + primitive::Primitive::new( + &self.cubes, + &self.camera, + bounds, + self.show_depth_buffer, + self.light_color, + ) + } +} + +fn rnd_origin() -> Vec3 { + Vec3::new( + rand::thread_rng().gen_range(-4.0..4.0), + rand::thread_rng().gen_range(-4.0..4.0), + rand::thread_rng().gen_range(-4.0..2.0), + ) +} -- cgit From 811aa673e9e832ebe38bf56a087f32fdc7aba59c Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Tue, 14 Nov 2023 15:48:01 +0100 Subject: Improve module hierarchy of `custom_shader` example --- examples/custom_shader/src/scene.rs | 103 +++++++++++++++++++++++++++++++++--- 1 file changed, 95 insertions(+), 8 deletions(-) (limited to 'examples/custom_shader/src/scene.rs') diff --git a/examples/custom_shader/src/scene.rs b/examples/custom_shader/src/scene.rs index ab923093..3b291ce2 100644 --- a/examples/custom_shader/src/scene.rs +++ b/examples/custom_shader/src/scene.rs @@ -1,13 +1,21 @@ -use crate::camera::Camera; -use crate::primitive; -use crate::primitive::cube::Cube; -use glam::Vec3; +mod camera; +mod pipeline; + +use camera::Camera; +use pipeline::Pipeline; + +use crate::wgpu; +use pipeline::cube::{self, Cube}; + +use iced::mouse; +use iced::time::Duration; use iced::widget::shader; -use iced::{mouse, Color, Rectangle}; +use iced::{Color, Rectangle, Size}; + +use glam::Vec3; use rand::Rng; use std::cmp::Ordering; use std::iter; -use std::time::Duration; pub const MAX: u32 = 500; @@ -72,7 +80,7 @@ impl Scene { impl shader::Program for Scene { type State = (); - type Primitive = primitive::Primitive; + type Primitive = Primitive; fn draw( &self, @@ -80,7 +88,7 @@ impl shader::Program for Scene { _cursor: mouse::Cursor, bounds: Rectangle, ) -> Self::Primitive { - primitive::Primitive::new( + Primitive::new( &self.cubes, &self.camera, bounds, @@ -90,6 +98,85 @@ impl shader::Program for Scene { } } +/// A collection of `Cube`s that can be rendered. +#[derive(Debug)] +pub struct Primitive { + cubes: Vec, + uniforms: pipeline::Uniforms, + show_depth_buffer: bool, +} + +impl Primitive { + pub fn new( + cubes: &[Cube], + camera: &Camera, + bounds: Rectangle, + show_depth_buffer: bool, + light_color: Color, + ) -> Self { + let uniforms = pipeline::Uniforms::new(camera, bounds, light_color); + + Self { + cubes: cubes + .iter() + .map(cube::Raw::from_cube) + .collect::>(), + uniforms, + show_depth_buffer, + } + } +} + +impl shader::Primitive for Primitive { + fn prepare( + &self, + format: wgpu::TextureFormat, + device: &wgpu::Device, + queue: &wgpu::Queue, + target_size: Size, + _scale_factor: f32, + _transform: shader::Transformation, + storage: &mut shader::Storage, + ) { + if !storage.has::() { + storage.store(Pipeline::new(device, queue, format, target_size)); + } + + let pipeline = storage.get_mut::().unwrap(); + + //upload data to GPU + pipeline.update( + device, + queue, + target_size, + &self.uniforms, + self.cubes.len(), + &self.cubes, + ); + } + + fn render( + &self, + storage: &shader::Storage, + bounds: Rectangle, + target: &wgpu::TextureView, + _target_size: Size, + encoder: &mut wgpu::CommandEncoder, + ) { + //at this point our pipeline should always be initialized + let pipeline = storage.get::().unwrap(); + + //render primitive + pipeline.render( + target, + encoder, + bounds, + self.cubes.len() as u32, + self.show_depth_buffer, + ); + } +} + fn rnd_origin() -> Vec3 { Vec3::new( rand::thread_rng().gen_range(-4.0..4.0), -- cgit From ab7dae554cac801aeed5d9aa4d3850d50be86263 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Tue, 28 Nov 2023 23:13:38 +0100 Subject: Provide actual bounds to `Shader` primitives ... and allow for proper translation and scissoring. --- examples/custom_shader/src/scene.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'examples/custom_shader/src/scene.rs') diff --git a/examples/custom_shader/src/scene.rs b/examples/custom_shader/src/scene.rs index 3b291ce2..a35efdd9 100644 --- a/examples/custom_shader/src/scene.rs +++ b/examples/custom_shader/src/scene.rs @@ -133,9 +133,9 @@ impl shader::Primitive for Primitive { format: wgpu::TextureFormat, device: &wgpu::Device, queue: &wgpu::Queue, + _bounds: Rectangle, target_size: Size, _scale_factor: f32, - _transform: shader::Transformation, storage: &mut shader::Storage, ) { if !storage.has::() { @@ -158,9 +158,9 @@ impl shader::Primitive for Primitive { fn render( &self, storage: &shader::Storage, - bounds: Rectangle, target: &wgpu::TextureView, _target_size: Size, + viewport: Rectangle, encoder: &mut wgpu::CommandEncoder, ) { //at this point our pipeline should always be initialized @@ -170,7 +170,7 @@ impl shader::Primitive for Primitive { pipeline.render( target, encoder, - bounds, + viewport, self.cubes.len() as u32, self.show_depth_buffer, ); -- cgit