diff --git a/dunge/src/context.rs b/dunge/src/context.rs index 7b44dc5..0f93511 100644 --- a/dunge/src/context.rs +++ b/dunge/src/context.rs @@ -8,7 +8,7 @@ use { sl::IntoModule, state::State, texture::{self, CopyBuffer, CopyBufferView, Filter, Make, MapResult, Mapped, Sampler}, - uniform::{Uniform, Value}, + uniform::{IntoValue, Uniform, Value}, Vertex, }, std::{error, fmt, future::IntoFuture, sync::Arc}, @@ -37,10 +37,11 @@ impl Context { Binder::new(&self.0, shader) } - pub fn make_uniform(&self, val: U) -> Uniform + pub fn make_uniform(&self, val: U) -> Uniform where - U: Value, + U: IntoValue, { + let val = val.into_value(); Uniform::new(&self.0, val.value().as_ref()) } diff --git a/dunge/src/uniform.rs b/dunge/src/uniform.rs index f3592cc..cecdce3 100644 --- a/dunge/src/uniform.rs +++ b/dunge/src/uniform.rs @@ -36,13 +36,14 @@ impl Uniform { } } - pub fn update(&self, cx: &Context, val: U) + pub fn update(&self, cx: &Context, val: V) where + V: IntoValue, U: Value, { let queue = cx.state().queue(); - let data = val.value(); - queue.write_buffer(&self.buf, 0, data.as_ref()); + let val = val.into_value(); + queue.write_buffer(&self.buf, 0, val.value().as_ref()); } pub(crate) fn buffer(&self) -> &Buffer { @@ -57,6 +58,14 @@ pub trait Value: private::Sealed { fn value(self) -> Self::Data; } +pub struct Data([f32; N]); + +impl AsRef<[u8]> for Data { + fn as_ref(&self) -> &[u8] { + bytemuck::cast_slice(&self.0) + } +} + pub(crate) fn values_as_bytes(values: &[U]) -> &[u8] where U: Value, @@ -152,11 +161,67 @@ impl Value for [[f32; 4]; 4] { } } -pub struct Data([f32; N]); +pub trait IntoValue { + type Value: Value; + fn into_value(self) -> Self::Value; +} -impl AsRef<[u8]> for Data { - fn as_ref(&self) -> &[u8] { - bytemuck::cast_slice(&self.0) +impl IntoValue for U +where + U: Value, +{ + type Value = Self; + + fn into_value(self) -> Self { + self + } +} + +impl IntoValue for glam::Vec2 { + type Value = [f32; 2]; + + fn into_value(self) -> Self::Value { + self.to_array() + } +} + +impl IntoValue for glam::Vec3 { + type Value = [f32; 3]; + + fn into_value(self) -> Self::Value { + self.to_array() + } +} + +impl IntoValue for glam::Vec4 { + type Value = [f32; 4]; + + fn into_value(self) -> Self::Value { + self.to_array() + } +} + +impl IntoValue for glam::Mat2 { + type Value = [[f32; 2]; 2]; + + fn into_value(self) -> Self::Value { + self.to_cols_array_2d() + } +} + +impl IntoValue for glam::Mat3 { + type Value = [[f32; 3]; 3]; + + fn into_value(self) -> Self::Value { + self.to_cols_array_2d() + } +} + +impl IntoValue for glam::Mat4 { + type Value = [[f32; 4]; 4]; + + fn into_value(self) -> Self::Value { + self.to_cols_array_2d() } } diff --git a/examples/cube/src/main.rs b/examples/cube/src/main.rs index 3f40c5f..9baf159 100644 --- a/examples/cube/src/main.rs +++ b/examples/cube/src/main.rs @@ -53,8 +53,7 @@ async fn run() -> Result<(), Error> { let mut r = 0.; let uniform = { let mat = transform(r, window.size()); - // TODO: `IntoValue` trait - cx.make_uniform(mat.to_cols_array_2d()) + cx.make_uniform(mat) }; let bind = { @@ -128,7 +127,7 @@ async fn run() -> Result<(), Error> { r += ctrl.delta_time().as_secs_f32(); let mat = transform(r, ctrl.size()); - uniform.update(&cx, mat.to_cols_array_2d()); + uniform.update(&cx, mat); Then::Run };