-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathvertex.rs
More file actions
157 lines (137 loc) · 3.94 KB
/
vertex.rs
File metadata and controls
157 lines (137 loc) · 3.94 KB
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
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
//! Vertex attribute formats and a simple `Vertex` type.
//!
//! Pipelines declare per‑buffer `VertexAttribute`s that map engine vertex
//! data into shader inputs by `location`. This module hosts common color
//! formats and a convenience `Vertex`/`VertexBuilder` used in examples.
/// Canonical color/attribute formats used by engine pipelines.
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum ColorFormat {
Rgb32Sfloat,
Rgba8Srgb,
}
impl ColorFormat {
pub(crate) fn to_platform(
self,
) -> lambda_platform::wgpu::vertex::ColorFormat {
match self {
ColorFormat::Rgb32Sfloat => {
lambda_platform::wgpu::vertex::ColorFormat::Rgb32Sfloat
}
ColorFormat::Rgba8Srgb => {
lambda_platform::wgpu::vertex::ColorFormat::Rgba8Srgb
}
}
}
}
/// Step mode applied to a vertex buffer layout.
///
/// `PerVertex` advances attributes once per vertex; `PerInstance` advances
/// attributes once per instance. This mirrors the platform step mode without
/// exposing backend types.
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum VertexStepMode {
PerVertex,
PerInstance,
}
/// Layout for a single vertex buffer slot.
///
/// `stride` describes the size in bytes of one element in the buffer. The
/// `step_mode` field determines whether attributes sourced from this buffer
/// advance per vertex or per instance.
#[derive(Clone, Copy, Debug)]
pub struct VertexBufferLayout {
pub stride: u64,
pub step_mode: VertexStepMode,
}
/// A single vertex element (format + byte offset).
#[derive(Clone, Copy, Debug)]
///
/// Combine one or more elements to form a `VertexAttribute` bound at a shader
/// location. Offsets are in bytes from the start of the vertex and the element.
pub struct VertexElement {
pub format: ColorFormat,
pub offset: u32,
}
/// Vertex attribute bound to a shader `location` plus relative offsets.
#[derive(Clone, Copy, Debug)]
///
/// `location` MUST match the shader input. The final attribute byte offset is
/// `offset + element.offset`.
pub struct VertexAttribute {
pub location: u32,
pub offset: u32,
pub element: VertexElement,
}
/// Vertex data structure with position, normal, and color.
#[repr(C)]
#[derive(Clone, Copy, Debug)]
pub struct Vertex {
pub position: [f32; 3],
pub normal: [f32; 3],
pub color: [f32; 3],
}
unsafe impl crate::pod::PlainOldData for Vertex {}
/// Builder for constructing a `Vertex` instance incrementally.
#[derive(Clone, Copy, Debug)]
pub struct VertexBuilder {
pub position: [f32; 3],
pub normal: [f32; 3],
pub color: [f32; 3],
}
impl Default for VertexBuilder {
fn default() -> Self {
return Self::new();
}
}
impl VertexBuilder {
/// Creates a new vertex builder.
pub fn new() -> Self {
Self {
position: [0.0, 0.0, 0.0],
normal: [0.0, 0.0, 0.0],
color: [0.0, 0.0, 0.0],
}
}
/// Set the position of the vertex.
pub fn with_position(&mut self, position: [f32; 3]) -> &mut Self {
self.position = position;
self
}
/// Set the normal of the vertex.
pub fn with_normal(&mut self, normal: [f32; 3]) -> &mut Self {
self.normal = normal;
self
}
/// Set the color of the vertex.
pub fn with_color(&mut self, color: [f32; 3]) -> &mut Self {
self.color = color;
self
}
/// Build the vertex.
pub fn build(&self) -> Vertex {
Vertex {
position: self.position,
normal: self.normal,
color: self.color,
}
}
}
#[cfg(test)]
mod test {
use super::*;
#[test]
fn vertex_building() {
let mut vertex = VertexBuilder::new();
assert_eq!(vertex.position, [0.0, 0.0, 0.0]);
assert_eq!(vertex.normal, [0.0, 0.0, 0.0]);
assert_eq!(vertex.color, [0.0, 0.0, 0.0]);
let vertex = vertex
.with_position([1.0, 2.0, 3.0])
.with_normal([4.0, 5.0, 6.0])
.with_color([7.0, 8.0, 9.0])
.build();
assert_eq!(vertex.position, [1.0, 2.0, 3.0]);
assert_eq!(vertex.normal, [4.0, 5.0, 6.0]);
assert_eq!(vertex.color, [7.0, 8.0, 9.0]);
}
}