1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105
//! Defines traits and types for working with data adhering to GLSL's `std140` //! layout specification. mod dynamic_uniform; mod primitives; mod sizer; mod writer; use std::mem::size_of; use bytemuck::{bytes_of, Pod, Zeroable}; pub use self::dynamic_uniform::*; pub use self::primitives::*; pub use self::sizer::*; pub use self::writer::*; pub use crevice_derive::AsStd140; /// Trait implemented for all `std140` primitives. Generally should not be /// implemented outside this crate. pub unsafe trait Std140: Copy + Zeroable + Pod { /// The required alignment of the type. Must be a power of two. /// /// This is distinct from the value returned by `std::mem::align_of` because /// `AsStd140` structs do not use Rust's alignment. This enables them to /// control and zero their padding bytes, making converting them to and from /// slices safe. const ALIGNMENT: usize; /// Casts the type to a byte array. Implementors should not override this /// method. /// /// # Safety /// This is always safe due to the requirements of [`bytemuck::Pod`] being a /// prerequisite for this trait. fn as_bytes(&self) -> &[u8] { bytes_of(self) } } /** Trait implemented for all types that can be turned into `std140` values. This trait can often be `#[derive]`'d instead of manually implementing it. Any struct which contains only fields that also implement `AsStd140` can derive `AsStd140`. Types from the mint crate implement `AsStd140`, making them convenient for use in uniform types. Most Rust geometry crates, like cgmath, nalgebra, and ultraviolet support mint. ## Example ```glsl uniform CAMERA { mat4 view; mat4 projection; } camera; ``` ``` use cgmath::prelude::*; use cgmath::{Matrix4, Deg, perspective}; use crevice::std140::{AsStd140, Std140}; #[derive(AsStd140)] struct CameraUniform { view: mint::ColumnMatrix4<f32>, projection: mint::ColumnMatrix4<f32>, } let camera = CameraUniform { view: Matrix4::identity().into(), projection: perspective(Deg(60.0), 16.0/9.0, 0.01, 100.0).into(), }; # fn write_to_gpu_buffer(bytes: &[u8]) {} let camera_std140 = camera.as_std140(); write_to_gpu_buffer(camera_std140.as_bytes()); ``` */ pub trait AsStd140 { /// The `std140` version of this value. type Std140Type: Std140; /// Convert this value into the `std140` version of itself. fn as_std140(&self) -> Self::Std140Type; /// Returns the size of the `std140` version of this type. Useful for /// pre-sizing buffers. fn std140_size(&self) -> usize { size_of::<Self::Std140Type>() } } impl<T> AsStd140 for T where T: Std140, { type Std140Type = Self; fn as_std140(&self) -> Self { *self } }