1use glam::*;
2use wgpu::util::DeviceExt;
3
4use crate::core::{self, BufferWrapper, FixedSizeBufferWrapper};
5
6#[derive(Debug, Clone)]
11pub struct BasicColorModifiersBuffer(wgpu::Buffer);
12
13impl BasicColorModifiersBuffer {
14 pub fn new(device: &wgpu::Device) -> Self {
16 let buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
17 label: Some("Basic Color Modifiers Buffer"),
18 contents: bytemuck::bytes_of(&BasicColorModifiersPod::default()),
19 usage: Self::DEFAULT_USAGES,
20 });
21
22 Self(buffer)
23 }
24
25 pub fn update(
27 &self,
28 queue: &wgpu::Queue,
29 rgb_or_hsv: BasicColorRgbOverrideOrHsvModifiersPod,
30 alpha: f32,
31 contrast: f32,
32 exposure: f32,
33 gamma: f32,
34 ) {
35 self.update_with_pod(
36 queue,
37 &BasicColorModifiersPod::new(rgb_or_hsv, alpha, contrast, exposure, gamma),
38 );
39 }
40
41 pub fn update_with_pod(&self, queue: &wgpu::Queue, pod: &BasicColorModifiersPod) {
43 queue.write_buffer(&self.0, 0, bytemuck::bytes_of(pod));
44 }
45}
46
47impl BufferWrapper for BasicColorModifiersBuffer {
48 fn buffer(&self) -> &wgpu::Buffer {
49 &self.0
50 }
51}
52
53impl From<BasicColorModifiersBuffer> for wgpu::Buffer {
54 fn from(wrapper: BasicColorModifiersBuffer) -> Self {
55 wrapper.0
56 }
57}
58
59impl TryFrom<wgpu::Buffer> for BasicColorModifiersBuffer {
60 type Error = core::FixedSizeBufferWrapperError;
61
62 fn try_from(buffer: wgpu::Buffer) -> Result<Self, Self::Error> {
63 Self::verify_buffer_size(&buffer).map(|()| Self(buffer))
64 }
65}
66
67impl FixedSizeBufferWrapper for BasicColorModifiersBuffer {
68 type Pod = BasicColorModifiersPod;
69}
70
71#[repr(transparent)]
77#[derive(Debug, Clone, Copy, PartialEq, bytemuck::Pod, bytemuck::Zeroable)]
78pub struct BasicColorRgbOverrideOrHsvModifiersPod(pub Vec3);
79
80impl BasicColorRgbOverrideOrHsvModifiersPod {
81 pub fn new_rgb_override(rgb: Vec3) -> Self {
83 Self(-rgb)
84 }
85
86 pub const fn new_hsv_modifiers(hsv: Vec3) -> Self {
88 Self(hsv)
89 }
90
91 pub fn is_rgb_override(&self) -> bool {
93 self.0.x.is_sign_negative() || self.0.y.is_sign_negative() || self.0.z.is_sign_negative()
94 }
95
96 pub fn is_hsv_modifiers(&self) -> bool {
98 !self.is_rgb_override()
99 }
100
101 pub fn get_vec3(&self) -> Vec3 {
103 if self.is_rgb_override() {
104 -self.0
105 } else {
106 self.0
107 }
108 }
109}
110
111#[repr(C)]
113#[derive(Debug, Clone, Copy, PartialEq, bytemuck::Pod, bytemuck::Zeroable)]
114pub struct BasicColorModifiersPod {
115 pub rgb_or_hsv: BasicColorRgbOverrideOrHsvModifiersPod,
116 pub alpha: f32,
117 pub contrast: f32,
118 pub exposure: f32,
119 pub gamma: f32,
120 pub _padding: u32,
121}
122
123impl BasicColorModifiersPod {
124 pub fn new(
126 rgb_or_hsv: BasicColorRgbOverrideOrHsvModifiersPod,
127 alpha: f32,
128 contrast: f32,
129 exposure: f32,
130 gamma: f32,
131 ) -> Self {
132 Self {
133 rgb_or_hsv,
134 alpha,
135 contrast,
136 exposure,
137 gamma,
138 _padding: 0,
139 }
140 }
141}
142
143impl Default for BasicColorModifiersPod {
144 fn default() -> Self {
145 Self {
146 rgb_or_hsv: BasicColorRgbOverrideOrHsvModifiersPod::new_hsv_modifiers(Vec3::new(
147 0.0, 1.0, 1.0,
148 )),
149 alpha: 1.0,
150 contrast: 0.0,
151 exposure: 0.0,
152 gamma: 1.0,
153 _padding: 0,
154 }
155 }
156}
157
158#[derive(Debug, Clone)]
160pub struct TransformFlagsBuffer(wgpu::Buffer);
161
162impl TransformFlagsBuffer {
163 pub fn new(device: &wgpu::Device) -> Self {
165 let buffer = device.create_buffer(&wgpu::BufferDescriptor {
166 label: Some("Transform Flags Buffer"),
167 size: std::mem::size_of::<u32>() as wgpu::BufferAddress,
168 usage: Self::DEFAULT_USAGES,
169 mapped_at_creation: false,
170 });
171
172 Self(buffer)
173 }
174
175 pub fn update(&self, queue: &wgpu::Queue, flags: TransformFlags) {
177 queue.write_buffer(&self.0, 0, bytemuck::bytes_of(&flags.bits()));
178 }
179}
180
181impl BufferWrapper for TransformFlagsBuffer {
182 fn buffer(&self) -> &wgpu::Buffer {
183 &self.0
184 }
185}
186
187impl From<TransformFlagsBuffer> for wgpu::Buffer {
188 fn from(wrapper: TransformFlagsBuffer) -> Self {
189 wrapper.0
190 }
191}
192
193impl TryFrom<wgpu::Buffer> for TransformFlagsBuffer {
194 type Error = core::FixedSizeBufferWrapperError;
195
196 fn try_from(buffer: wgpu::Buffer) -> Result<Self, Self::Error> {
197 Self::verify_buffer_size(&buffer).map(|()| Self(buffer))
198 }
199}
200
201impl FixedSizeBufferWrapper for TransformFlagsBuffer {
202 type Pod = u32;
203}
204
205bitflags::bitflags! {
206 #[repr(transparent)]
208 #[derive(Debug, Default, Clone, Copy, PartialEq, Eq, bytemuck::Pod, bytemuck::Zeroable)]
209 pub struct TransformFlags: u32 {
210 const MODEL = 0b0001;
212 const GAUSSIAN = 0b0010;
214 }
215}
216
217#[derive(Debug, Clone)]
221pub struct RotScaleBuffer(wgpu::Buffer);
222
223impl RotScaleBuffer {
224 pub fn new(device: &wgpu::Device) -> Self {
226 let buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
227 label: Some("Scale Rot Buffer"),
228 contents: bytemuck::bytes_of(&RotScalePod::default()),
229 usage: Self::DEFAULT_USAGES,
230 });
231
232 Self(buffer)
233 }
234
235 pub fn update(&self, queue: &wgpu::Queue, rot: Quat, scale: Vec3) {
237 self.update_with_pod(queue, &RotScalePod::new(rot, scale));
238 }
239
240 pub fn update_with_pod(&self, queue: &wgpu::Queue, pod: &RotScalePod) {
242 queue.write_buffer(&self.0, 0, bytemuck::bytes_of(pod));
243 }
244}
245
246impl BufferWrapper for RotScaleBuffer {
247 fn buffer(&self) -> &wgpu::Buffer {
248 &self.0
249 }
250}
251
252impl From<RotScaleBuffer> for wgpu::Buffer {
253 fn from(wrapper: RotScaleBuffer) -> Self {
254 wrapper.0
255 }
256}
257
258impl TryFrom<wgpu::Buffer> for RotScaleBuffer {
259 type Error = core::FixedSizeBufferWrapperError;
260
261 fn try_from(buffer: wgpu::Buffer) -> Result<Self, Self::Error> {
262 Self::verify_buffer_size(&buffer).map(|()| Self(buffer))
263 }
264}
265
266impl FixedSizeBufferWrapper for RotScaleBuffer {
267 type Pod = RotScalePod;
268}
269
270#[repr(C)]
272#[derive(Debug, Clone, Copy, PartialEq, bytemuck::Pod, bytemuck::Zeroable)]
273pub struct RotScalePod {
274 pub rot: Quat,
275 pub scale: Vec3A,
276}
277
278impl RotScalePod {
279 pub const fn new(rot: Quat, scale: Vec3) -> Self {
281 Self {
282 rot,
283 scale: Vec3A::from_array(scale.to_array()),
284 }
285 }
286}
287
288impl Default for RotScalePod {
289 fn default() -> Self {
290 Self {
291 rot: Quat::IDENTITY,
292 scale: Vec3A::ONE,
293 }
294 }
295}