ren/gl45/
attrib.rs

1pub mod prelude {
2    pub use super::{Attrib, AttribBindPoint, AttribBinding, AttribFormat, AttribKind};
3}
4
5use std::mem;
6
7pub type Attrib = AttribFormat;
8
9#[derive(PartialEq, Eq, Hash, Clone, Copy, Debug)]
10pub enum AttribKind {
11    Float1,
12    Float2,
13    Float3,
14    Float4,
15}
16
17impl AttribKind {
18    fn gl_size_type(self) -> (u8, u32) {
19        match self {
20            Self::Float1 => (1, gl::FLOAT),
21            Self::Float2 => (2, gl::FLOAT),
22            Self::Float3 => (3, gl::FLOAT),
23            Self::Float4 => (4, gl::FLOAT),
24        }
25    }
26}
27
28#[derive(PartialEq, Eq, Hash, Clone, Copy, Debug)]
29pub struct AttribFormat {
30    /// Attribute index.
31    pub index: u32,
32    pub kind: AttribKind,
33    /// Relative offset in bytes between vertex elements.
34    pub offset: u32,
35}
36
37impl AttribFormat {
38    #[inline]
39    pub const fn new(index: u32, kind: AttribKind) -> Self {
40        Self::with_offset(index, kind, 0)
41    }
42
43    #[inline]
44    pub const fn with_offset(index: u32, kind: AttribKind, offset: u32) -> Self {
45        Self {
46            index,
47            kind,
48            offset,
49        }
50    }
51
52    #[inline]
53    pub const fn typed_offset<T>(index: u32, kind: AttribKind) -> Self {
54        Self::with_offset(index, kind, mem::size_of::<T>() as u32)
55    }
56
57    #[inline]
58    pub unsafe fn apply(&self, vao: u32) {
59        let (size, type_) = self.kind.gl_size_type();
60        gl::VertexArrayAttribFormat(vao, self.index, size as i32, type_, gl::FALSE, self.offset);
61    }
62
63    #[inline]
64    pub unsafe fn enable(&self, vao: u32) {
65        gl::EnableVertexArrayAttrib(vao, self.index);
66    }
67
68    #[inline]
69    pub unsafe fn disable(&self, vao: u32) {
70        gl::DisableVertexArrayAttrib(vao, self.index);
71    }
72}
73
74#[derive(PartialEq, Eq, Hash, Clone, Copy, Debug)]
75pub struct AttribBinding {
76    pub attrib_index: u32,
77    pub buffer_binding_index: u32,
78}
79
80impl AttribBinding {
81    pub fn new(attrib_index: u32, buffer_binding_index: u32) -> Self {
82        Self {
83            attrib_index,
84            buffer_binding_index,
85        }
86    }
87
88    pub unsafe fn apply(&self, vao: u32) {
89        gl::VertexArrayAttribBinding(vao, self.attrib_index, self.buffer_binding_index);
90    }
91}
92
93#[derive(PartialEq, Eq, Hash, Clone, Copy, Debug)]
94pub struct AttribBindPoint {
95    /// Index of the buffer binding point.
96    pub binding_index: u32,
97    /// Offset in bytes of the first element.
98    pub offset: u32,
99    /// Distance in bytes between elements.
100    pub stride: u32,
101}
102
103impl AttribBindPoint {
104    #[inline]
105    pub const fn new(binding_index: u32, offset: u32, stride: u32) -> Self {
106        Self {
107            binding_index,
108            offset,
109            stride,
110        }
111    }
112
113    #[inline]
114    pub const fn typed_stride<T>(binding_index: u32, offset: u32) -> Self {
115        Self::new(binding_index, offset, mem::size_of::<T>() as u32)
116    }
117
118    #[inline]
119    pub unsafe fn apply(&self, vao: u32, buffer: u32) {
120        gl::VertexArrayVertexBuffer(
121            vao,
122            self.binding_index,
123            buffer,
124            self.offset as isize,
125            self.stride as i32,
126        );
127    }
128}