summaryrefslogtreecommitdiffstats
path: root/examples/custom_shader/src/primitive.rs
diff options
context:
space:
mode:
Diffstat (limited to 'examples/custom_shader/src/primitive.rs')
-rw-r--r--examples/custom_shader/src/primitive.rs95
1 files changed, 95 insertions, 0 deletions
diff --git a/examples/custom_shader/src/primitive.rs b/examples/custom_shader/src/primitive.rs
new file mode 100644
index 00000000..2201218f
--- /dev/null
+++ b/examples/custom_shader/src/primitive.rs
@@ -0,0 +1,95 @@
+pub mod cube;
+pub mod vertex;
+
+mod buffer;
+mod uniforms;
+
+use crate::camera::Camera;
+use crate::pipeline::Pipeline;
+use crate::primitive::cube::Cube;
+use iced::advanced::graphics::Transformation;
+use iced::widget::shader;
+use iced::{Color, Rectangle, Size};
+
+pub use crate::primitive::vertex::Vertex;
+pub use buffer::Buffer;
+pub use uniforms::Uniforms;
+
+/// A collection of `Cube`s that can be rendered.
+#[derive(Debug)]
+pub struct Primitive {
+ cubes: Vec<cube::Raw>,
+ uniforms: 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 = 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: 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,
+ )
+ }
+}