crevice_notan/
glsl.rs

1/*!
2Defines traits and types for generating GLSL code from Rust definitions.
3
4All GLSL primitives, like `int` or `vec3`, implement the [`Glsl`] trait. Structs
5should implement [`GlslStruct`], which can be derived.
6
7## Examples
8Given this struct:
9*/
10#![cfg_attr(
11    feature = "std",
12    doc = r##"
13```rust
14use mint::{ColumnMatrix4, Vector3};
15use crevice_notan::glsl::GlslStruct;
16
17#[derive(GlslStruct)]
18struct SpotLight {
19    transform: ColumnMatrix4<f32>,
20    color: Vector3<f32>,
21    intensity: f32,
22}
23
24println!("{}", SpotLight::glsl_definition());
25```
26"##
27)]
28/*!
29The output will be:
30```glsl
31struct SpotLight {
32    mat4 transform;
33    vec3 color;
34    float intensity;
35};
36```
37*/
38
39pub use crevice_notan_derive::GlslStruct;
40
41/// Trait for types that have a GLSL equivalent. Useful for generating GLSL code
42/// from Rust structs.
43#[allow(clippy::missing_safety_doc)]
44pub unsafe trait Glsl {
45    /// The name of this type in GLSL, like `vec2` or `mat4`.
46    const NAME: &'static str;
47}
48
49/// A field contained within a GLSL struct definition.
50pub struct GlslField {
51    /// The type of the field, like `vec2` or `mat3`.
52    pub ty: &'static str,
53
54    /// The field's name. This must be a valid GLSL identifier.
55    pub name: &'static str,
56}
57
58/// Trait for types that can be represented as a struct in GLSL.
59///
60/// This trait should not generally be implemented by hand, but can be derived.
61#[cfg(feature = "std")]
62#[allow(clippy::missing_safety_doc)]
63pub unsafe trait GlslStruct: Glsl {
64    /// The fields contained in this struct.
65    const FIELDS: &'static [GlslField];
66
67    /// Generates GLSL code that represents this struct and its fields.
68    fn glsl_definition() -> String {
69        let mut output = String::new();
70        output.push_str("struct ");
71        output.push_str(Self::NAME);
72        output.push_str(" {\n");
73
74        for field in Self::FIELDS {
75            output.push('\t');
76            output.push_str(field.ty);
77            output.push(' ');
78            output.push_str(field.name);
79            output.push_str(";\n");
80        }
81
82        output.push_str("};");
83        output
84    }
85}
86
87unsafe impl Glsl for f32 {
88    const NAME: &'static str = "float";
89}
90
91unsafe impl Glsl for f64 {
92    const NAME: &'static str = "double";
93}
94
95unsafe impl Glsl for i32 {
96    const NAME: &'static str = "int";
97}
98
99unsafe impl Glsl for u32 {
100    const NAME: &'static str = "uint";
101}