summaryrefslogtreecommitdiffstats
path: root/examples/custom_shader/src/scene.rs
diff options
context:
space:
mode:
Diffstat (limited to 'examples/custom_shader/src/scene.rs')
-rw-r--r--examples/custom_shader/src/scene.rs103
1 files changed, 95 insertions, 8 deletions
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<Message> shader::Program<Message> for Scene {
type State = ();
- type Primitive = primitive::Primitive;
+ type Primitive = Primitive;
fn draw(
&self,
@@ -80,7 +88,7 @@ impl<Message> shader::Program<Message> for Scene {
_cursor: mouse::Cursor,
bounds: Rectangle,
) -> Self::Primitive {
- primitive::Primitive::new(
+ Primitive::new(
&self.cubes,
&self.camera,
bounds,
@@ -90,6 +98,85 @@ impl<Message> shader::Program<Message> for Scene {
}
}
+/// A collection of `Cube`s that can be rendered.
+#[derive(Debug)]
+pub struct Primitive {
+ cubes: Vec<cube::Raw>,
+ 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::<Vec<cube::Raw>>(),
+ uniforms,
+ show_depth_buffer,
+ }
+ }
+}
+
+impl shader::Primitive for Primitive {
+ fn prepare(
+ &self,
+ format: wgpu::TextureFormat,
+ device: &wgpu::Device,
+ queue: &wgpu::Queue,
+ target_size: Size<u32>,
+ _scale_factor: f32,
+ _transform: shader::Transformation,
+ storage: &mut shader::Storage,
+ ) {
+ if !storage.has::<Pipeline>() {
+ storage.store(Pipeline::new(device, queue, format, target_size));
+ }
+
+ let pipeline = storage.get_mut::<Pipeline>().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<u32>,
+ target: &wgpu::TextureView,
+ _target_size: Size<u32>,
+ encoder: &mut wgpu::CommandEncoder,
+ ) {
+ //at this point our pipeline should always be initialized
+ let pipeline = storage.get::<Pipeline>().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),