use glam::*;
use wgpu::util::DeviceExt;
use crate::core::{self, BufferWrapper, FixedSizeBufferWrapper};
#[derive(Debug, Clone)]
pub struct BasicColorModifiersBuffer(wgpu::Buffer);
impl BasicColorModifiersBuffer {
pub fn new(device: &wgpu::Device) -> Self {
let buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
label: Some("Basic Color Modifiers Buffer"),
contents: bytemuck::bytes_of(&BasicColorModifiersPod::default()),
usage: Self::DEFAULT_USAGES,
});
Self(buffer)
}
pub fn update(
&self,
queue: &wgpu::Queue,
rgb_or_hsv: BasicColorRgbOverrideOrHsvModifiersPod,
alpha: f32,
contrast: f32,
exposure: f32,
gamma: f32,
) {
self.update_with_pod(
queue,
&BasicColorModifiersPod::new(rgb_or_hsv, alpha, contrast, exposure, gamma),
);
}
pub fn update_with_pod(&self, queue: &wgpu::Queue, pod: &BasicColorModifiersPod) {
queue.write_buffer(&self.0, 0, bytemuck::bytes_of(pod));
}
}
impl BufferWrapper for BasicColorModifiersBuffer {
fn buffer(&self) -> &wgpu::Buffer {
&self.0
}
}
impl From<BasicColorModifiersBuffer> for wgpu::Buffer {
fn from(wrapper: BasicColorModifiersBuffer) -> Self {
wrapper.0
}
}
impl TryFrom<wgpu::Buffer> for BasicColorModifiersBuffer {
type Error = core::FixedSizeBufferWrapperError;
fn try_from(buffer: wgpu::Buffer) -> Result<Self, Self::Error> {
Self::verify_buffer_size(&buffer).map(|()| Self(buffer))
}
}
impl FixedSizeBufferWrapper for BasicColorModifiersBuffer {
type Pod = BasicColorModifiersPod;
}
#[repr(transparent)]
#[derive(Debug, Clone, Copy, PartialEq, bytemuck::Pod, bytemuck::Zeroable)]
pub struct BasicColorRgbOverrideOrHsvModifiersPod(pub Vec3);
impl BasicColorRgbOverrideOrHsvModifiersPod {
pub fn new_rgb_override(rgb: Vec3) -> Self {
Self(-rgb)
}
pub const fn new_hsv_modifiers(hsv: Vec3) -> Self {
Self(hsv)
}
pub fn is_rgb_override(&self) -> bool {
self.0.x.is_sign_negative() || self.0.y.is_sign_negative() || self.0.z.is_sign_negative()
}
pub fn is_hsv_modifiers(&self) -> bool {
!self.is_rgb_override()
}
pub fn get_vec3(&self) -> Vec3 {
if self.is_rgb_override() {
-self.0
} else {
self.0
}
}
}
#[repr(C)]
#[derive(Debug, Clone, Copy, PartialEq, bytemuck::Pod, bytemuck::Zeroable)]
pub struct BasicColorModifiersPod {
pub rgb_or_hsv: BasicColorRgbOverrideOrHsvModifiersPod,
pub alpha: f32,
pub contrast: f32,
pub exposure: f32,
pub gamma: f32,
pub _padding: u32,
}
impl BasicColorModifiersPod {
pub fn new(
rgb_or_hsv: BasicColorRgbOverrideOrHsvModifiersPod,
alpha: f32,
contrast: f32,
exposure: f32,
gamma: f32,
) -> Self {
Self {
rgb_or_hsv,
alpha,
contrast,
exposure,
gamma,
_padding: 0,
}
}
}
impl Default for BasicColorModifiersPod {
fn default() -> Self {
Self {
rgb_or_hsv: BasicColorRgbOverrideOrHsvModifiersPod::new_hsv_modifiers(Vec3::new(
0.0, 1.0, 1.0,
)),
alpha: 1.0,
contrast: 0.0,
exposure: 0.0,
gamma: 1.0,
_padding: 0,
}
}
}
#[derive(Debug, Clone)]
pub struct TransformFlagsBuffer(wgpu::Buffer);
impl TransformFlagsBuffer {
pub fn new(device: &wgpu::Device) -> Self {
let buffer = device.create_buffer(&wgpu::BufferDescriptor {
label: Some("Transform Flags Buffer"),
size: std::mem::size_of::<u32>() as wgpu::BufferAddress,
usage: Self::DEFAULT_USAGES,
mapped_at_creation: false,
});
Self(buffer)
}
pub fn update(&self, queue: &wgpu::Queue, flags: TransformFlags) {
queue.write_buffer(&self.0, 0, bytemuck::bytes_of(&flags.bits()));
}
}
impl BufferWrapper for TransformFlagsBuffer {
fn buffer(&self) -> &wgpu::Buffer {
&self.0
}
}
impl From<TransformFlagsBuffer> for wgpu::Buffer {
fn from(wrapper: TransformFlagsBuffer) -> Self {
wrapper.0
}
}
impl TryFrom<wgpu::Buffer> for TransformFlagsBuffer {
type Error = core::FixedSizeBufferWrapperError;
fn try_from(buffer: wgpu::Buffer) -> Result<Self, Self::Error> {
Self::verify_buffer_size(&buffer).map(|()| Self(buffer))
}
}
impl FixedSizeBufferWrapper for TransformFlagsBuffer {
type Pod = u32;
}
bitflags::bitflags! {
#[repr(transparent)]
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, bytemuck::Pod, bytemuck::Zeroable)]
pub struct TransformFlags: u32 {
const MODEL = 0b0001;
const GAUSSIAN = 0b0010;
}
}
#[derive(Debug, Clone)]
pub struct RotScaleBuffer(wgpu::Buffer);
impl RotScaleBuffer {
pub fn new(device: &wgpu::Device) -> Self {
let buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
label: Some("Scale Rot Buffer"),
contents: bytemuck::bytes_of(&RotScalePod::default()),
usage: Self::DEFAULT_USAGES,
});
Self(buffer)
}
pub fn update(&self, queue: &wgpu::Queue, rot: Quat, scale: Vec3) {
self.update_with_pod(queue, &RotScalePod::new(rot, scale));
}
pub fn update_with_pod(&self, queue: &wgpu::Queue, pod: &RotScalePod) {
queue.write_buffer(&self.0, 0, bytemuck::bytes_of(pod));
}
}
impl BufferWrapper for RotScaleBuffer {
fn buffer(&self) -> &wgpu::Buffer {
&self.0
}
}
impl From<RotScaleBuffer> for wgpu::Buffer {
fn from(wrapper: RotScaleBuffer) -> Self {
wrapper.0
}
}
impl TryFrom<wgpu::Buffer> for RotScaleBuffer {
type Error = core::FixedSizeBufferWrapperError;
fn try_from(buffer: wgpu::Buffer) -> Result<Self, Self::Error> {
Self::verify_buffer_size(&buffer).map(|()| Self(buffer))
}
}
impl FixedSizeBufferWrapper for RotScaleBuffer {
type Pod = RotScalePod;
}
#[repr(C)]
#[derive(Debug, Clone, Copy, PartialEq, bytemuck::Pod, bytemuck::Zeroable)]
pub struct RotScalePod {
pub rot: Quat,
pub scale: Vec3A,
}
impl RotScalePod {
pub const fn new(rot: Quat, scale: Vec3) -> Self {
Self {
rot,
scale: Vec3A::from_array(scale.to_array()),
}
}
}
impl Default for RotScalePod {
fn default() -> Self {
Self {
rot: Quat::IDENTITY,
scale: Vec3A::ONE,
}
}
}