summaryrefslogtreecommitdiffstats
path: root/examples/custom_shader/src/primitive
diff options
context:
space:
mode:
authorLibravatar Bingus <shankern@protonmail.com>2023-09-14 13:58:36 -0700
committerLibravatar Héctor Ramón Jiménez <hector@hecrj.dev>2023-11-14 11:31:44 +0100
commit781ef1f94c4859aeeb852f801b72be095b8ff82b (patch)
tree63e2678eca11dd41c26a40633c04341fd795d733 /examples/custom_shader/src/primitive
parent817f72868746461891ca4e74473c555f3b5c5703 (diff)
downloadiced-781ef1f94c4859aeeb852f801b72be095b8ff82b.tar.gz
iced-781ef1f94c4859aeeb852f801b72be095b8ff82b.tar.bz2
iced-781ef1f94c4859aeeb852f801b72be095b8ff82b.zip
Added support for custom shader widget for iced_wgpu backend.
Diffstat (limited to 'examples/custom_shader/src/primitive')
-rw-r--r--examples/custom_shader/src/primitive/buffer.rs39
-rw-r--r--examples/custom_shader/src/primitive/cube.rs324
-rw-r--r--examples/custom_shader/src/primitive/uniforms.rs22
-rw-r--r--examples/custom_shader/src/primitive/vertex.rs29
4 files changed, 414 insertions, 0 deletions
diff --git a/examples/custom_shader/src/primitive/buffer.rs b/examples/custom_shader/src/primitive/buffer.rs
new file mode 100644
index 00000000..377ce1bb
--- /dev/null
+++ b/examples/custom_shader/src/primitive/buffer.rs
@@ -0,0 +1,39 @@
+// A custom buffer container for dynamic resizing.
+pub struct Buffer {
+ pub raw: wgpu::Buffer,
+ label: &'static str,
+ size: u64,
+ usage: wgpu::BufferUsages,
+}
+
+impl Buffer {
+ pub fn new(
+ device: &wgpu::Device,
+ label: &'static str,
+ size: u64,
+ usage: wgpu::BufferUsages,
+ ) -> Self {
+ Self {
+ raw: device.create_buffer(&wgpu::BufferDescriptor {
+ label: Some(label),
+ size,
+ usage,
+ mapped_at_creation: false,
+ }),
+ label,
+ size,
+ usage,
+ }
+ }
+
+ pub fn resize(&mut self, device: &wgpu::Device, new_size: u64) {
+ if new_size > self.size {
+ self.raw = device.create_buffer(&wgpu::BufferDescriptor {
+ label: Some(self.label),
+ size: new_size,
+ usage: self.usage,
+ mapped_at_creation: false,
+ });
+ }
+ }
+}
diff --git a/examples/custom_shader/src/primitive/cube.rs b/examples/custom_shader/src/primitive/cube.rs
new file mode 100644
index 00000000..c23f2132
--- /dev/null
+++ b/examples/custom_shader/src/primitive/cube.rs
@@ -0,0 +1,324 @@
+use crate::primitive::Vertex;
+use glam::{vec2, vec3, Vec3};
+use rand::{thread_rng, Rng};
+
+/// A single instance of a cube.
+#[derive(Debug, Clone)]
+pub struct Cube {
+ pub rotation: glam::Quat,
+ pub position: Vec3,
+ pub size: f32,
+ rotation_dir: f32,
+ rotation_axis: glam::Vec3,
+}
+
+impl Default for Cube {
+ fn default() -> Self {
+ Self {
+ rotation: glam::Quat::IDENTITY,
+ position: glam::Vec3::ZERO,
+ size: 0.1,
+ rotation_dir: 1.0,
+ rotation_axis: glam::Vec3::Y,
+ }
+ }
+}
+
+impl Cube {
+ pub fn new(size: f32, origin: Vec3) -> Self {
+ let rnd = thread_rng().gen_range(0.0..=1.0f32);
+
+ Self {
+ rotation: glam::Quat::IDENTITY,
+ position: origin + Vec3::new(0.1, 0.1, 0.1),
+ size,
+ rotation_dir: if rnd <= 0.5 { -1.0 } else { 1.0 },
+ rotation_axis: if rnd <= 0.33 {
+ glam::Vec3::Y
+ } else if rnd <= 0.66 {
+ glam::Vec3::X
+ } else {
+ glam::Vec3::Z
+ },
+ }
+ }
+
+ pub fn update(&mut self, size: f32, time: f32) {
+ self.rotation = glam::Quat::from_axis_angle(
+ self.rotation_axis,
+ time / 2.0 * self.rotation_dir,
+ );
+ self.size = size;
+ }
+}
+
+#[derive(Clone, Copy, bytemuck::Pod, bytemuck::Zeroable, Debug)]
+#[repr(C)]
+pub struct Raw {
+ transformation: glam::Mat4,
+ normal: glam::Mat3,
+ _padding: [f32; 3],
+}
+
+impl Raw {
+ const ATTRIBS: [wgpu::VertexAttribute; 7] = wgpu::vertex_attr_array![
+ //cube transformation matrix
+ 4 => Float32x4,
+ 5 => Float32x4,
+ 6 => Float32x4,
+ 7 => Float32x4,
+ //normal rotation matrix
+ 8 => Float32x3,
+ 9 => Float32x3,
+ 10 => Float32x3,
+ ];
+
+ pub fn desc<'a>() -> wgpu::VertexBufferLayout<'a> {
+ wgpu::VertexBufferLayout {
+ array_stride: std::mem::size_of::<Self>() as wgpu::BufferAddress,
+ step_mode: wgpu::VertexStepMode::Instance,
+ attributes: &Self::ATTRIBS,
+ }
+ }
+}
+
+impl Raw {
+ pub fn from_cube(cube: &Cube) -> Raw {
+ Raw {
+ transformation: glam::Mat4::from_scale_rotation_translation(
+ glam::vec3(cube.size, cube.size, cube.size),
+ cube.rotation,
+ cube.position,
+ ),
+ normal: glam::Mat3::from_quat(cube.rotation),
+ _padding: [0.0; 3],
+ }
+ }
+
+ pub fn vertices() -> [Vertex; 36] {
+ [
+ //face 1
+ Vertex {
+ pos: vec3(-0.5, -0.5, -0.5),
+ normal: vec3(0.0, 0.0, -1.0),
+ tangent: vec3(1.0, 0.0, 0.0),
+ uv: vec2(0.0, 1.0),
+ },
+ Vertex {
+ pos: vec3(0.5, -0.5, -0.5),
+ normal: vec3(0.0, 0.0, -1.0),
+ tangent: vec3(1.0, 0.0, 0.0),
+ uv: vec2(1.0, 1.0),
+ },
+ Vertex {
+ pos: vec3(0.5, 0.5, -0.5),
+ normal: vec3(0.0, 0.0, -1.0),
+ tangent: vec3(1.0, 0.0, 0.0),
+ uv: vec2(1.0, 0.0),
+ },
+ Vertex {
+ pos: vec3(0.5, 0.5, -0.5),
+ normal: vec3(0.0, 0.0, -1.0),
+ tangent: vec3(1.0, 0.0, 0.0),
+ uv: vec2(1.0, 0.0),
+ },
+ Vertex {
+ pos: vec3(-0.5, 0.5, -0.5),
+ normal: vec3(0.0, 0.0, -1.0),
+ tangent: vec3(1.0, 0.0, 0.0),
+ uv: vec2(0.0, 0.0),
+ },
+ Vertex {
+ pos: vec3(-0.5, -0.5, -0.5),
+ normal: vec3(0.0, 0.0, -1.0),
+ tangent: vec3(1.0, 0.0, 0.0),
+ uv: vec2(0.0, 1.0),
+ },
+ //face 2
+ Vertex {
+ pos: vec3(-0.5, -0.5, 0.5),
+ normal: vec3(0.0, 0.0, 1.0),
+ tangent: vec3(1.0, 0.0, 0.0),
+ uv: vec2(0.0, 1.0),
+ },
+ Vertex {
+ pos: vec3(0.5, -0.5, 0.5),
+ normal: vec3(0.0, 0.0, 1.0),
+ tangent: vec3(1.0, 0.0, 0.0),
+ uv: vec2(1.0, 1.0),
+ },
+ Vertex {
+ pos: vec3(0.5, 0.5, 0.5),
+ normal: vec3(0.0, 0.0, 1.0),
+ tangent: vec3(1.0, 0.0, 0.0),
+ uv: vec2(1.0, 0.0),
+ },
+ Vertex {
+ pos: vec3(0.5, 0.5, 0.5),
+ normal: vec3(0.0, 0.0, 1.0),
+ tangent: vec3(1.0, 0.0, 0.0),
+ uv: vec2(1.0, 0.0),
+ },
+ Vertex {
+ pos: vec3(-0.5, 0.5, 0.5),
+ normal: vec3(0.0, 0.0, 1.0),
+ tangent: vec3(1.0, 0.0, 0.0),
+ uv: vec2(0.0, 0.0),
+ },
+ Vertex {
+ pos: vec3(-0.5, -0.5, 0.5),
+ normal: vec3(0.0, 0.0, 1.0),
+ tangent: vec3(1.0, 0.0, 0.0),
+ uv: vec2(0.0, 1.0),
+ },
+ //face 3
+ Vertex {
+ pos: vec3(-0.5, 0.5, 0.5),
+ normal: vec3(-1.0, 0.0, 0.0),
+ tangent: vec3(0.0, 0.0, -1.0),
+ uv: vec2(0.0, 1.0),
+ },
+ Vertex {
+ pos: vec3(-0.5, 0.5, -0.5),
+ normal: vec3(-1.0, 0.0, 0.0),
+ tangent: vec3(0.0, 0.0, -1.0),
+ uv: vec2(1.0, 1.0),
+ },
+ Vertex {
+ pos: vec3(-0.5, -0.5, -0.5),
+ normal: vec3(-1.0, 0.0, 0.0),
+ tangent: vec3(0.0, 0.0, -1.0),
+ uv: vec2(1.0, 0.0),
+ },
+ Vertex {
+ pos: vec3(-0.5, -0.5, -0.5),
+ normal: vec3(-1.0, 0.0, 0.0),
+ tangent: vec3(0.0, 0.0, -1.0),
+ uv: vec2(1.0, 0.0),
+ },
+ Vertex {
+ pos: vec3(-0.5, -0.5, 0.5),
+ normal: vec3(-1.0, 0.0, 0.0),
+ tangent: vec3(0.0, 0.0, -1.0),
+ uv: vec2(0.0, 0.0),
+ },
+ Vertex {
+ pos: vec3(-0.5, 0.5, 0.5),
+ normal: vec3(-1.0, 0.0, 0.0),
+ tangent: vec3(0.0, 0.0, -1.0),
+ uv: vec2(0.0, 1.0),
+ },
+ //face 4
+ Vertex {
+ pos: vec3(0.5, 0.5, 0.5),
+ normal: vec3(1.0, 0.0, 0.0),
+ tangent: vec3(0.0, 0.0, -1.0),
+ uv: vec2(0.0, 1.0),
+ },
+ Vertex {
+ pos: vec3(0.5, 0.5, -0.5),
+ normal: vec3(1.0, 0.0, 0.0),
+ tangent: vec3(0.0, 0.0, -1.0),
+ uv: vec2(1.0, 1.0),
+ },
+ Vertex {
+ pos: vec3(0.5, -0.5, -0.5),
+ normal: vec3(1.0, 0.0, 0.0),
+ tangent: vec3(0.0, 0.0, -1.0),
+ uv: vec2(1.0, 0.0),
+ },
+ Vertex {
+ pos: vec3(0.5, -0.5, -0.5),
+ normal: vec3(1.0, 0.0, 0.0),
+ tangent: vec3(0.0, 0.0, -1.0),
+ uv: vec2(1.0, 0.0),
+ },
+ Vertex {
+ pos: vec3(0.5, -0.5, 0.5),
+ normal: vec3(1.0, 0.0, 0.0),
+ tangent: vec3(0.0, 0.0, -1.0),
+ uv: vec2(0.0, 0.0),
+ },
+ Vertex {
+ pos: vec3(0.5, 0.5, 0.5),
+ normal: vec3(1.0, 0.0, 0.0),
+ tangent: vec3(0.0, 0.0, -1.0),
+ uv: vec2(0.0, 1.0),
+ },
+ //face 5
+ Vertex {
+ pos: vec3(-0.5, -0.5, -0.5),
+ normal: vec3(0.0, -1.0, 0.0),
+ tangent: vec3(1.0, 0.0, 0.0),
+ uv: vec2(0.0, 1.0),
+ },
+ Vertex {
+ pos: vec3(0.5, -0.5, -0.5),
+ normal: vec3(0.0, -1.0, 0.0),
+ tangent: vec3(1.0, 0.0, 0.0),
+ uv: vec2(1.0, 1.0),
+ },
+ Vertex {
+ pos: vec3(0.5, -0.5, 0.5),
+ normal: vec3(0.0, -1.0, 0.0),
+ tangent: vec3(1.0, 0.0, 0.0),
+ uv: vec2(1.0, 0.0),
+ },
+ Vertex {
+ pos: vec3(0.5, -0.5, 0.5),
+ normal: vec3(0.0, -1.0, 0.0),
+ tangent: vec3(1.0, 0.0, 0.0),
+ uv: vec2(1.0, 0.0),
+ },
+ Vertex {
+ pos: vec3(-0.5, -0.5, 0.5),
+ normal: vec3(0.0, -1.0, 0.0),
+ tangent: vec3(1.0, 0.0, 0.0),
+ uv: vec2(0.0, 0.0),
+ },
+ Vertex {
+ pos: vec3(-0.5, -0.5, -0.5),
+ normal: vec3(0.0, -1.0, 0.0),
+ tangent: vec3(1.0, 0.0, 0.0),
+ uv: vec2(0.0, 1.0),
+ },
+ //face 6
+ Vertex {
+ pos: vec3(-0.5, 0.5, -0.5),
+ normal: vec3(0.0, 1.0, 0.0),
+ tangent: vec3(1.0, 0.0, 0.0),
+ uv: vec2(0.0, 1.0),
+ },
+ Vertex {
+ pos: vec3(0.5, 0.5, -0.5),
+ normal: vec3(0.0, 1.0, 0.0),
+ tangent: vec3(1.0, 0.0, 0.0),
+ uv: vec2(1.0, 1.0),
+ },
+ Vertex {
+ pos: vec3(0.5, 0.5, 0.5),
+ normal: vec3(0.0, 1.0, 0.0),
+ tangent: vec3(1.0, 0.0, 0.0),
+ uv: vec2(1.0, 0.0),
+ },
+ Vertex {
+ pos: vec3(0.5, 0.5, 0.5),
+ normal: vec3(0.0, 1.0, 0.0),
+ tangent: vec3(1.0, 0.0, 0.0),
+ uv: vec2(1.0, 0.0),
+ },
+ Vertex {
+ pos: vec3(-0.5, 0.5, 0.5),
+ normal: vec3(0.0, 1.0, 0.0),
+ tangent: vec3(1.0, 0.0, 0.0),
+ uv: vec2(0.0, 0.0),
+ },
+ Vertex {
+ pos: vec3(-0.5, 0.5, -0.5),
+ normal: vec3(0.0, 1.0, 0.0),
+ tangent: vec3(1.0, 0.0, 0.0),
+ uv: vec2(0.0, 1.0),
+ },
+ ]
+ }
+}
diff --git a/examples/custom_shader/src/primitive/uniforms.rs b/examples/custom_shader/src/primitive/uniforms.rs
new file mode 100644
index 00000000..4fcb413b
--- /dev/null
+++ b/examples/custom_shader/src/primitive/uniforms.rs
@@ -0,0 +1,22 @@
+use crate::camera::Camera;
+use iced::{Color, Rectangle};
+
+#[derive(Copy, Clone, Debug, bytemuck::Pod, bytemuck::Zeroable)]
+#[repr(C)]
+pub struct Uniforms {
+ camera_proj: glam::Mat4,
+ camera_pos: glam::Vec4,
+ light_color: glam::Vec4,
+}
+
+impl Uniforms {
+ pub fn new(camera: &Camera, bounds: Rectangle, light_color: Color) -> Self {
+ let camera_proj = camera.build_view_proj_matrix(bounds);
+
+ Self {
+ camera_proj,
+ camera_pos: camera.position(),
+ light_color: glam::Vec4::from(light_color.into_linear()),
+ }
+ }
+}
diff --git a/examples/custom_shader/src/primitive/vertex.rs b/examples/custom_shader/src/primitive/vertex.rs
new file mode 100644
index 00000000..6d17aa0f
--- /dev/null
+++ b/examples/custom_shader/src/primitive/vertex.rs
@@ -0,0 +1,29 @@
+#[derive(Debug, Copy, Clone, bytemuck::Pod, bytemuck::Zeroable)]
+#[repr(C)]
+pub struct Vertex {
+ pub pos: glam::Vec3,
+ pub normal: glam::Vec3,
+ pub tangent: glam::Vec3,
+ pub uv: glam::Vec2,
+}
+
+impl Vertex {
+ const ATTRIBS: [wgpu::VertexAttribute; 4] = wgpu::vertex_attr_array![
+ //position
+ 0 => Float32x3,
+ //normal
+ 1 => Float32x3,
+ //tangent
+ 2 => Float32x3,
+ //uv
+ 3 => Float32x2,
+ ];
+
+ pub fn desc<'a>() -> wgpu::VertexBufferLayout<'a> {
+ wgpu::VertexBufferLayout {
+ array_stride: std::mem::size_of::<Self>() as wgpu::BufferAddress,
+ step_mode: wgpu::VertexStepMode::Vertex,
+ attributes: &Self::ATTRIBS,
+ }
+ }
+}