oxihuman_export/
webgl_export.rs1#![allow(dead_code)]
4
5#[derive(Clone, Copy, PartialEq, Debug)]
9pub enum WebGlBufferType {
10 ArrayBuffer,
11 ElementArrayBuffer,
12}
13
14pub struct WebGlBuffer {
16 pub buffer_type: WebGlBufferType,
17 pub data: Vec<u8>,
18 pub name: String,
19}
20
21pub struct WebGlExport {
23 pub buffers: Vec<WebGlBuffer>,
24 pub vertex_shader_src: String,
25 pub fragment_shader_src: String,
26}
27
28pub fn new_webgl_export() -> WebGlExport {
30 WebGlExport {
31 buffers: Vec::new(),
32 vertex_shader_src: "attribute vec3 aPos;\nvoid main(){gl_Position=vec4(aPos,1.0);}"
33 .to_string(),
34 fragment_shader_src: "void main(){gl_FragColor=vec4(1.0);}".to_string(),
35 }
36}
37
38pub fn add_webgl_f32_buffer(exp: &mut WebGlExport, name: &str, data: &[f32]) {
40 let bytes: Vec<u8> = data.iter().flat_map(|f| f.to_le_bytes()).collect();
41 exp.buffers.push(WebGlBuffer {
42 buffer_type: WebGlBufferType::ArrayBuffer,
43 data: bytes,
44 name: name.to_string(),
45 });
46}
47
48pub fn add_webgl_index_buffer(exp: &mut WebGlExport, name: &str, indices: &[u16]) {
50 let bytes: Vec<u8> = indices.iter().flat_map(|i| i.to_le_bytes()).collect();
51 exp.buffers.push(WebGlBuffer {
52 buffer_type: WebGlBufferType::ElementArrayBuffer,
53 data: bytes,
54 name: name.to_string(),
55 });
56}
57
58pub fn webgl_buffer_count(exp: &WebGlExport) -> usize {
60 exp.buffers.len()
61}
62
63pub fn webgl_total_bytes(exp: &WebGlExport) -> usize {
65 exp.buffers.iter().map(|b| b.data.len()).sum()
66}
67
68pub fn find_webgl_buffer<'a>(exp: &'a WebGlExport, name: &str) -> Option<&'a WebGlBuffer> {
70 exp.buffers.iter().find(|b| b.name == name)
71}
72
73pub fn validate_webgl_export(exp: &WebGlExport) -> bool {
75 !exp.vertex_shader_src.is_empty() && !exp.fragment_shader_src.is_empty()
76}
77
78#[cfg(test)]
79mod tests {
80 use super::*;
81
82 #[test]
83 fn new_export_has_no_buffers() {
84 let exp = new_webgl_export();
85 assert_eq!(webgl_buffer_count(&exp), 0 );
86 }
87
88 #[test]
89 fn add_f32_buffer_increments_count() {
90 let mut exp = new_webgl_export();
91 add_webgl_f32_buffer(&mut exp, "pos", &[0.0, 1.0, 2.0]);
92 assert_eq!(webgl_buffer_count(&exp), 1 );
93 }
94
95 #[test]
96 fn f32_buffer_correct_byte_size() {
97 let mut exp = new_webgl_export();
98 add_webgl_f32_buffer(&mut exp, "verts", &[0.0f32; 9]);
99 let b = find_webgl_buffer(&exp, "verts").expect("should succeed");
100 assert_eq!(b.data.len(), 36 );
101 }
102
103 #[test]
104 fn index_buffer_correct_byte_size() {
105 let mut exp = new_webgl_export();
106 add_webgl_index_buffer(&mut exp, "idx", &[0u16, 1, 2]);
107 let b = find_webgl_buffer(&exp, "idx").expect("should succeed");
108 assert_eq!(b.data.len(), 6 );
109 }
110
111 #[test]
112 fn total_bytes_sum() {
113 let mut exp = new_webgl_export();
114 add_webgl_f32_buffer(&mut exp, "a", &[0.0f32; 3]);
115 add_webgl_index_buffer(&mut exp, "b", &[0u16; 3]);
116 assert_eq!(webgl_total_bytes(&exp), 18 );
117 }
118
119 #[test]
120 fn find_buffer_by_name() {
121 let mut exp = new_webgl_export();
122 add_webgl_f32_buffer(&mut exp, "normals", &[0.0, 1.0, 0.0]);
123 assert!(find_webgl_buffer(&exp, "normals").is_some() );
124 }
125
126 #[test]
127 fn find_missing_buffer_none() {
128 let exp = new_webgl_export();
129 assert!(find_webgl_buffer(&exp, "x").is_none() );
130 }
131
132 #[test]
133 fn validate_new_export() {
134 let exp = new_webgl_export();
135 assert!(validate_webgl_export(&exp) );
136 }
137
138 #[test]
139 fn index_buffer_type_correct() {
140 let mut exp = new_webgl_export();
141 add_webgl_index_buffer(&mut exp, "i", &[0u16]);
142 let b = find_webgl_buffer(&exp, "i").expect("should succeed");
143 assert_eq!(
144 b.buffer_type,
145 WebGlBufferType::ElementArrayBuffer );
147 }
148}