awsm_web/webgl/
uniforms.rs

1use super::{WebGlCommon, Id, WebGlRenderer};
2use crate::errors::{Error, NativeError};
3use std::marker::PhantomData;
4use web_sys::{WebGl2RenderingContext, WebGlRenderingContext};
5use web_sys::{WebGlProgram, WebGlUniformLocation};
6use std::collections::hash_map::Entry;
7use std::convert::TryInto;
8use wasm_bindgen::prelude::*;
9
10pub enum UniformType {
11    Scalar1,
12    Scalar2,
13    Scalar3,
14    Scalar4,
15    Vector1,
16    Vector2,
17    Vector3,
18    Vector4,
19    Matrix2,
20    Matrix3,
21    Matrix4,
22    MatrixTransposed2,
23    MatrixTransposed3,
24    MatrixTransposed4,
25}
26
27pub trait PartialWebGlUniforms {
28    fn awsm_get_uniform_location(
29        &self,
30        program: &WebGlProgram,
31        name: &str,
32    ) -> Result<WebGlUniformLocation, Error>;
33    fn awsm_upload_uniform_fvec<T: AsRef<[f32]>>(
34        &self,
35        loc: &WebGlUniformLocation,
36        _type: UniformType,
37        data: &T,
38    ) -> Result<(), Error>;
39    fn awsm_upload_uniform_ivec<T: AsRef<[i32]>>(
40        &self,
41        loc: &WebGlUniformLocation,
42        _type: UniformType,
43        data: &T,
44    ) -> Result<(), Error>;
45
46    fn awsm_uniform1f(&self, loc: &WebGlUniformLocation, x: f32);
47    fn awsm_uniform2f(&self, loc: &WebGlUniformLocation, x: f32, y: f32);
48    fn awsm_uniform3f(&self, loc: &WebGlUniformLocation, x: f32, y: f32, z: f32);
49    fn awsm_uniform4f(&self, loc: &WebGlUniformLocation, x: f32, y: f32, z: f32, w: f32);
50
51    fn awsm_uniform1fv_with_f32_array(&self, loc: &WebGlUniformLocation, data: &[f32]);
52    fn awsm_uniform2fv_with_f32_array(&self, loc: &WebGlUniformLocation, data: &[f32]);
53    fn awsm_uniform3fv_with_f32_array(&self, loc: &WebGlUniformLocation, data: &[f32]);
54    fn awsm_uniform4fv_with_f32_array(&self, loc: &WebGlUniformLocation, data: &[f32]);
55
56    fn awsm_uniform1i(&self, loc: &WebGlUniformLocation, x: i32);
57    fn awsm_uniform2i(&self, loc: &WebGlUniformLocation, x: i32, y: i32);
58    fn awsm_uniform3i(&self, loc: &WebGlUniformLocation, x: i32, y: i32, z: i32);
59    fn awsm_uniform4i(&self, loc: &WebGlUniformLocation, x: i32, y: i32, z: i32, w: i32);
60
61    fn awsm_uniform1iv_with_i32_array(&self, loc: &WebGlUniformLocation, data: &[i32]);
62    fn awsm_uniform2iv_with_i32_array(&self, loc: &WebGlUniformLocation, data: &[i32]);
63    fn awsm_uniform3iv_with_i32_array(&self, loc: &WebGlUniformLocation, data: &[i32]);
64    fn awsm_uniform4iv_with_i32_array(&self, loc: &WebGlUniformLocation, data: &[i32]);
65
66    fn awsm_uniform_matrix2fv_with_f32_array(
67        &self,
68        loc: &WebGlUniformLocation,
69        transpose: bool,
70        data: &[f32],
71    );
72    fn awsm_uniform_matrix3fv_with_f32_array(
73        &self,
74        loc: &WebGlUniformLocation,
75        transpose: bool,
76        data: &[f32],
77    );
78    fn awsm_uniform_matrix4fv_with_f32_array(
79        &self,
80        loc: &WebGlUniformLocation,
81        transpose: bool,
82        data: &[f32],
83    );
84}
85
86pub trait PartialWebGl2Uniforms {
87    fn awsm_upload_uniform_uvec<T: AsRef<[u32]>>(
88        &self,
89        loc: &WebGlUniformLocation,
90        _type: UniformType,
91        data: &T,
92    ) -> Result<(), Error>;
93    fn awsm_uniform1ui(&self, loc: &WebGlUniformLocation, x: u32);
94    fn awsm_uniform2ui(&self, loc: &WebGlUniformLocation, x: u32, y: u32);
95    fn awsm_uniform3ui(&self, loc: &WebGlUniformLocation, x: u32, y: u32, z: u32);
96    fn awsm_uniform4ui(&self, loc: &WebGlUniformLocation, x: u32, y: u32, z: u32, w: u32);
97
98    fn awsm_uniform1uiv_with_u32_array(&self, loc: &WebGlUniformLocation, data: &[u32]);
99    fn awsm_uniform2uiv_with_u32_array(&self, loc: &WebGlUniformLocation, data: &[u32]);
100    fn awsm_uniform3uiv_with_u32_array(&self, loc: &WebGlUniformLocation, data: &[u32]);
101    fn awsm_uniform4uiv_with_u32_array(&self, loc: &WebGlUniformLocation, data: &[u32]);
102
103    fn awsm_get_uniform_indices(&self, program: &WebGlProgram, uniform_names: &[&str]) -> Option<Vec<u32>>;
104}
105
106macro_rules! impl_context {
107    ($($type:ty { $($defs:tt)* })+) => {
108        $(impl PartialWebGlUniforms for $type {
109
110            fn awsm_get_uniform_location(&self, program:&WebGlProgram, name:&str) -> Result<WebGlUniformLocation, Error> {
111                self.get_uniform_location(&program, &name)
112                    .ok_or(Error::from(NativeError::UniformLocation(Some(name.to_owned()))))
113            }
114
115            fn awsm_upload_uniform_fvec<T: AsRef<[f32]>> (&self, loc:&WebGlUniformLocation, _type:UniformType, data:&T) -> Result<(), Error> {
116                UniformSlice::new(data, _type).upload(self, &loc)
117            }
118
119            fn awsm_upload_uniform_ivec<T: AsRef<[i32]>> (&self, loc:&WebGlUniformLocation, _type:UniformType, data:&T) -> Result<(), Error> {
120                UniformSlice::new(data, _type).upload(self, &loc)
121            }
122
123
124            fn awsm_uniform1f(&self, loc: &WebGlUniformLocation, x: f32) {
125                self.uniform1f(Some(loc), x)
126            }
127            fn awsm_uniform2f(&self, loc: &WebGlUniformLocation, x: f32, y: f32) {
128                self.uniform2f(Some(loc), x, y)
129            }
130            fn awsm_uniform3f(&self, loc: &WebGlUniformLocation, x: f32, y: f32, z: f32) {
131                self.uniform3f(Some(loc), x, y, z)
132            }
133            fn awsm_uniform4f(&self, loc: &WebGlUniformLocation, x: f32, y: f32, z: f32, w: f32) {
134                self.uniform4f(Some(loc), x, y, z, w)
135            }
136
137            fn awsm_uniform1fv_with_f32_array(&self, loc: &WebGlUniformLocation, data: &[f32]) {
138                self.uniform1fv_with_f32_array(Some(loc), data)
139            }
140            fn awsm_uniform2fv_with_f32_array(&self, loc: &WebGlUniformLocation, data: &[f32]) {
141                self.uniform2fv_with_f32_array(Some(loc), data)
142            }
143            fn awsm_uniform3fv_with_f32_array(&self, loc: &WebGlUniformLocation, data: &[f32]) {
144                self.uniform3fv_with_f32_array(Some(loc), data)
145            }
146            fn awsm_uniform4fv_with_f32_array(&self, loc: &WebGlUniformLocation, data: &[f32]) {
147                self.uniform4fv_with_f32_array(Some(loc), data)
148            }
149
150
151            fn awsm_uniform1i(&self, loc: &WebGlUniformLocation, x: i32) {
152                self.uniform1i(Some(loc), x)
153            }
154            fn awsm_uniform2i(&self, loc: &WebGlUniformLocation, x: i32, y: i32) {
155                self.uniform2i(Some(loc), x, y)
156            }
157            fn awsm_uniform3i(&self, loc: &WebGlUniformLocation, x: i32, y: i32, z: i32) {
158                self.uniform3i(Some(loc), x, y, z)
159            }
160            fn awsm_uniform4i(&self, loc: &WebGlUniformLocation, x: i32, y: i32, z: i32, w: i32) {
161                self.uniform4i(Some(loc), x, y, z, w)
162            }
163
164            fn awsm_uniform1iv_with_i32_array(&self, loc: &WebGlUniformLocation, data: &[i32]) {
165                self.uniform1iv_with_i32_array(Some(loc), data)
166            }
167            fn awsm_uniform2iv_with_i32_array(&self, loc: &WebGlUniformLocation, data: &[i32]) {
168                self.uniform2iv_with_i32_array(Some(loc), data)
169            }
170            fn awsm_uniform3iv_with_i32_array(&self, loc: &WebGlUniformLocation, data: &[i32]) {
171                self.uniform3iv_with_i32_array(Some(loc), data)
172            }
173            fn awsm_uniform4iv_with_i32_array(&self, loc: &WebGlUniformLocation, data: &[i32]) {
174                self.uniform4iv_with_i32_array(Some(loc), data)
175            }
176
177
178            fn awsm_uniform_matrix2fv_with_f32_array(&self, loc: &WebGlUniformLocation, transpose: bool, data: &[f32]) {
179                self.uniform_matrix2fv_with_f32_array(Some(loc), transpose, data);
180            }
181            fn awsm_uniform_matrix3fv_with_f32_array(&self, loc: &WebGlUniformLocation, transpose: bool, data: &[f32]) {
182                self.uniform_matrix3fv_with_f32_array(Some(loc), transpose, data);
183            }
184            fn awsm_uniform_matrix4fv_with_f32_array(&self, loc: &WebGlUniformLocation, transpose: bool, data: &[f32]) {
185                self.uniform_matrix4fv_with_f32_array(Some(loc), transpose, data);
186            }
187            $($defs)*
188        })+
189    };
190}
191
192impl_context! {
193    WebGlRenderingContext{}
194    WebGl2RenderingContext{}
195}
196
197impl PartialWebGl2Uniforms for WebGl2RenderingContext {
198    fn awsm_upload_uniform_uvec<T: AsRef<[u32]>>(
199        &self,
200        loc: &WebGlUniformLocation,
201        _type: UniformType,
202        data: &T,
203    ) -> Result<(), Error> {
204        UniformSlice::new(data, _type).upload(self, &loc)
205    }
206
207    fn awsm_get_uniform_indices(&self, program: &WebGlProgram, uniform_names: &[&str]) -> Option<Vec<u32>> {
208        let len = uniform_names.len();
209
210        let arr = js_sys::Array::new_with_length(len.try_into().unwrap());
211        for i in 0..len {
212            arr.set(i.try_into().unwrap(), JsValue::from_str(uniform_names[i]));
213        }
214
215        self.get_uniform_indices(program, &arr)
216            .and_then(|arr| {
217                let mut values = Vec::with_capacity(len);
218                for i in 0..len {
219                    let value = arr.get(i.try_into().unwrap());
220                    if value == JsValue::UNDEFINED || value == JsValue::NULL {
221                        return None;
222                    } else {
223                        if let Some(value) = value.as_f64() {
224                            values.push(value as u32);
225                        } else {
226                            return None;
227                        }
228
229                    }
230                }
231
232                Some(values)
233            })
234    }
235
236    fn awsm_uniform1ui(&self, loc: &WebGlUniformLocation, x: u32) {
237        self.uniform1ui(Some(loc), x)
238    }
239    fn awsm_uniform2ui(&self, loc: &WebGlUniformLocation, x: u32, y: u32) {
240        self.uniform2ui(Some(loc), x, y)
241    }
242    fn awsm_uniform3ui(&self, loc: &WebGlUniformLocation, x: u32, y: u32, z: u32) {
243        self.uniform3ui(Some(loc), x, y, z)
244    }
245    fn awsm_uniform4ui(&self, loc: &WebGlUniformLocation, x: u32, y: u32, z: u32, w: u32) {
246        self.uniform4ui(Some(loc), x, y, z, w)
247    }
248
249    fn awsm_uniform1uiv_with_u32_array(&self, loc: &WebGlUniformLocation, data: &[u32]) {
250        self.uniform1uiv_with_u32_array(Some(loc), data)
251    }
252    fn awsm_uniform2uiv_with_u32_array(&self, loc: &WebGlUniformLocation, data: &[u32]) {
253        self.uniform2uiv_with_u32_array(Some(loc), data)
254    }
255    fn awsm_uniform3uiv_with_u32_array(&self, loc: &WebGlUniformLocation, data: &[u32]) {
256        self.uniform3uiv_with_u32_array(Some(loc), data)
257    }
258    fn awsm_uniform4uiv_with_u32_array(&self, loc: &WebGlUniformLocation, data: &[u32]) {
259        self.uniform4uiv_with_u32_array(Some(loc), data)
260    }
261}
262/*
263 * The slice-based uploads are written as traits on this a newtype wrapper
264 * in order to work with either f32 or i32 and still get simple checks
265 *
266 * There is no need to wrap the scalar versions because the only check
267 * for those is the length, which is known at compile-time
268 *
269 * Realistically, the renderer's convenience functions provide more value
270 * since they expand on this to also get the location by name and provide more wrappers
271 *
272 * Technique via https://users.rust-lang.org/t/different-impls-for-types-of-slices-and-arrays/29468
273 * Playground proof-of-concept: https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=19dc3ce889d1e7c8aedbd36ad45b8422
274 * TODO
275 * 1. followup with https://github.com/rustwasm/wasm-bindgen/pull/1539
276 * When the i32 slices don't need mut anymore - simplify below
277 *
278 *
279 */
280
281pub struct UniformSlice<T, U> {
282    values: T,
283    _type: UniformType,
284    phantom: PhantomData<U>,
285}
286
287impl<T: AsRef<[U]>, U> UniformSlice<T, U> {
288    pub fn new(values: T, _type: UniformType) -> Self {
289        Self {
290            values,
291            _type,
292            phantom: PhantomData,
293        }
294    }
295}
296
297pub trait UniformUploadImpl {
298    fn upload<T: PartialWebGlUniforms>(
299        &self,
300        gl: &T,
301        loc: &WebGlUniformLocation,
302    ) -> Result<(), Error>;
303}
304
305pub trait UniformUploadImpl2 {
306    fn upload<T: PartialWebGl2Uniforms>(
307        &self,
308        gl: &T,
309        loc: &WebGlUniformLocation,
310    ) -> Result<(), Error>;
311}
312
313fn is_length_enough(len: usize, _type: &UniformType) -> Result<(), Error> {
314    let min_length = match _type {
315        UniformType::Scalar1 | UniformType::Vector1 => 1,
316        UniformType::Scalar2 | UniformType::Vector2 => 2,
317        UniformType::Scalar3 | UniformType::Vector3 => 3,
318        UniformType::Scalar4
319        | UniformType::Vector4
320        | UniformType::Matrix2
321        | UniformType::MatrixTransposed2 => 4,
322        UniformType::Matrix3 | UniformType::MatrixTransposed3 => 9,
323        UniformType::Matrix4 | UniformType::MatrixTransposed4 => 16,
324    };
325
326    if len >= min_length {
327        Ok(())
328    } else {
329        Err(Error::from(NativeError::UniformSize))
330    }
331}
332
333impl<T: AsRef<[f32]>> UniformUploadImpl for UniformSlice<T, f32> {
334    fn upload<G: PartialWebGlUniforms>(
335        &self,
336        gl: &G,
337        loc: &WebGlUniformLocation,
338    ) -> Result<(), Error> {
339        let values = self.values.as_ref();
340        is_length_enough(values.len(), &self._type)?;
341
342        match self._type {
343            UniformType::Scalar1 => gl.awsm_uniform1f(loc, values[0]),
344            UniformType::Scalar2 => gl.awsm_uniform2f(loc, values[0], values[1]),
345            UniformType::Scalar3 => gl.awsm_uniform3f(loc, values[0], values[1], values[2]),
346            UniformType::Scalar4 => {
347                gl.awsm_uniform4f(loc, values[0], values[1], values[2], values[3])
348            }
349
350            UniformType::Vector1 => gl.awsm_uniform1fv_with_f32_array(loc, values),
351            UniformType::Vector2 => gl.awsm_uniform2fv_with_f32_array(loc, values),
352            UniformType::Vector3 => gl.awsm_uniform3fv_with_f32_array(loc, values),
353            UniformType::Vector4 => gl.awsm_uniform4fv_with_f32_array(loc, values),
354
355            UniformType::Matrix2 => gl.awsm_uniform_matrix2fv_with_f32_array(loc, false, values),
356            UniformType::Matrix3 => gl.awsm_uniform_matrix3fv_with_f32_array(loc, false, values),
357            UniformType::Matrix4 => gl.awsm_uniform_matrix4fv_with_f32_array(loc, false, values),
358
359            UniformType::MatrixTransposed2 => {
360                gl.awsm_uniform_matrix2fv_with_f32_array(loc, true, values)
361            }
362            UniformType::MatrixTransposed3 => {
363                gl.awsm_uniform_matrix3fv_with_f32_array(loc, true, values)
364            }
365            UniformType::MatrixTransposed4 => {
366                gl.awsm_uniform_matrix4fv_with_f32_array(loc, true, values)
367            }
368        };
369
370        Ok(())
371    }
372}
373
374impl<T: AsRef<[i32]>> UniformUploadImpl for UniformSlice<T, i32> {
375    fn upload<G: PartialWebGlUniforms>(
376        &self,
377        gl: &G,
378        loc: &WebGlUniformLocation,
379    ) -> Result<(), Error> {
380        let values = self.values.as_ref();
381        is_length_enough(values.len(), &self._type)?;
382
383        match self._type {
384            UniformType::Scalar1 => gl.awsm_uniform1i(loc, values[0]),
385            UniformType::Scalar2 => gl.awsm_uniform2i(loc, values[0], values[1]),
386            UniformType::Scalar3 => gl.awsm_uniform3i(loc, values[0], values[1], values[2]),
387            UniformType::Scalar4 => {
388                gl.awsm_uniform4i(loc, values[0], values[1], values[2], values[3])
389            }
390
391            UniformType::Vector1 => gl.awsm_uniform1iv_with_i32_array(loc, values),
392            UniformType::Vector2 => gl.awsm_uniform2iv_with_i32_array(loc, values),
393            UniformType::Vector3 => gl.awsm_uniform3iv_with_i32_array(loc, values),
394            UniformType::Vector4 => gl.awsm_uniform4iv_with_i32_array(loc, values),
395
396            _ => return Err(Error::from(NativeError::UniformMatrixMustBeFloat)),
397        };
398
399        Ok(())
400    }
401}
402
403impl<T: AsRef<[u32]>> UniformUploadImpl2 for UniformSlice<T, u32> {
404    fn upload<G: PartialWebGl2Uniforms>(
405        &self,
406        gl: &G,
407        loc: &WebGlUniformLocation,
408    ) -> Result<(), Error> {
409        let values = self.values.as_ref();
410        is_length_enough(values.len(), &self._type)?;
411
412        match self._type {
413            UniformType::Scalar1 => gl.awsm_uniform1ui(loc, values[0]),
414            UniformType::Scalar2 => gl.awsm_uniform2ui(loc, values[0], values[1]),
415            UniformType::Scalar3 => gl.awsm_uniform3ui(loc, values[0], values[1], values[2]),
416            UniformType::Scalar4 => {
417                gl.awsm_uniform4ui(loc, values[0], values[1], values[2], values[3])
418            }
419
420            UniformType::Vector1 => gl.awsm_uniform1uiv_with_u32_array(loc, values),
421            UniformType::Vector2 => gl.awsm_uniform2uiv_with_u32_array(loc, values),
422            UniformType::Vector3 => gl.awsm_uniform3uiv_with_u32_array(loc, values),
423            UniformType::Vector4 => gl.awsm_uniform4uiv_with_u32_array(loc, values),
424
425            _ => return Err(Error::from(NativeError::UniformMatrixMustBeFloat)),
426        };
427
428        Ok(())
429    }
430}
431
432//Renderer wrapper
433impl<G: WebGlCommon> WebGlRenderer<G> {
434
435    pub fn cache_uniform_name(&mut self, program_id: Id, name:&str) -> Result<(WebGlUniformLocation, bool), Error> {
436        let program_info = self
437            .program_lookup
438            .get_mut(program_id)
439            .ok_or(Error::from(NativeError::MissingShaderProgram))?;
440
441
442        let entry = program_info.uniform_lookup.entry(name.to_string());
443
444        match entry {
445            Entry::Occupied(entry) => {
446                //#[cfg(feature = "debug_log")]
447                //log::info!("skipping uniform cache for [{}] (already exists)", &name);
448                Ok((entry.get().clone(), false))
449            }
450            Entry::Vacant(entry) => {
451                #[cfg(feature = "debug_log")]
452                log::info!("caching uniform for [{}]", &name);
453                
454                let loc = self
455                    .gl
456                    .awsm_get_uniform_location(&program_info.program, &name)?;
457                entry.insert(loc.clone());
458                Ok((loc, true))
459            }
460        }
461    }
462
463    pub fn get_uniform_location_name(&mut self, name: &str) -> Result<WebGlUniformLocation, Error> {
464        let program_id = self
465            .current_program_id
466            .ok_or(Error::from(NativeError::MissingShaderProgram))?;
467
468        self.cache_uniform_name(program_id, name)
469            .map(|(loc, _cached)| loc)
470    }
471
472    //this covers all the slice-based versions due to the impl above
473
474    //Just some convenience helpers
475    pub fn upload_uniform_fvec_loc<T: AsRef<[f32]>>(
476        &self,
477        loc: &WebGlUniformLocation,
478        _type: UniformType,
479        data: &T,
480    ) -> Result<(), Error> {
481        self.gl.awsm_upload_uniform_fvec(&loc, _type, data)
482    }
483
484    pub fn upload_uniform_fvec_name<T: AsRef<[f32]>>(
485        &mut self,
486        target_name: &str,
487        _type: UniformType,
488        data: &T,
489    ) -> Result<(), Error> {
490        let loc = self.get_uniform_location_name(&target_name)?;
491        self.upload_uniform_fvec_loc(&loc, _type, data)
492    }
493
494    pub fn upload_uniform_ivec_loc<T: AsRef<[i32]>>(
495        &self,
496        loc: &WebGlUniformLocation,
497        _type: UniformType,
498        data: &T,
499    ) -> Result<(), Error> {
500        self.gl.awsm_upload_uniform_ivec(&loc, _type, data)
501    }
502
503    pub fn upload_uniform_ivec_name<T: AsRef<[i32]>>(
504        &mut self,
505        target_name: &str,
506        _type: UniformType,
507        data: &T,
508    ) -> Result<(), Error> {
509        let loc = self.get_uniform_location_name(&target_name)?;
510        self.upload_uniform_ivec_loc(&loc, _type, data)
511    }
512
513    pub fn upload_uniform_mat_4_loc<T: AsRef<[f32]>>(
514        &mut self,
515        loc: &WebGlUniformLocation,
516        data: &T,
517    ) -> Result<(), Error> {
518        self.upload_uniform_fvec_loc(loc, UniformType::Matrix4, &data)
519    }
520
521    pub fn upload_uniform_mat_4_name<T: AsRef<[f32]>>(
522        &mut self,
523        target_name: &str,
524        data: &T,
525    ) -> Result<(), Error> {
526        self.upload_uniform_fvec_name(target_name, UniformType::Matrix4, &data)
527    }
528    
529    pub fn upload_uniform_mat_3_loc<T: AsRef<[f32]>>(
530        &mut self,
531        loc: &WebGlUniformLocation,
532        data: &T,
533    ) -> Result<(), Error> {
534        self.upload_uniform_fvec_loc(loc, UniformType::Matrix3, &data)
535    }
536
537    pub fn upload_uniform_mat_3_name<T: AsRef<[f32]>>(
538        &mut self,
539        target_name: &str,
540        data: &T,
541    ) -> Result<(), Error> {
542        self.upload_uniform_fvec_name(target_name, UniformType::Matrix3, data)
543    }
544
545
546    pub fn upload_uniform_mat_2_loc<T: AsRef<[f32]>>(
547        &mut self,
548        loc: &WebGlUniformLocation,
549        data: &T,
550    ) -> Result<(), Error> {
551        self.upload_uniform_fvec_loc(loc, UniformType::Matrix2, &data)
552    }
553
554    pub fn upload_uniform_mat_2_name<T: AsRef<[f32]>>(
555        &mut self,
556        target_name: &str,
557        data: &T,
558    ) -> Result<(), Error> {
559        self.upload_uniform_fvec_name(target_name, UniformType::Matrix2, data)
560    }
561
562    pub fn upload_uniform_mat_transposed_4_loc<T: AsRef<[f32]>>(
563        &mut self,
564        loc: &WebGlUniformLocation,
565        data: &T,
566    ) -> Result<(), Error> {
567        self.upload_uniform_fvec_loc(loc, UniformType::MatrixTransposed4, data)
568    }
569
570    pub fn upload_uniform_mat_transposed_4_name<T: AsRef<[f32]>>(
571        &mut self,
572        target_name: &str,
573        data: &T,
574    ) -> Result<(), Error> {
575        self.upload_uniform_fvec_name(target_name, UniformType::MatrixTransposed4, data)
576    }
577
578    pub fn upload_uniform_mat_transposed_3_loc<T: AsRef<[f32]>>(
579        &mut self,
580        loc: &WebGlUniformLocation,
581        data: &T,
582    ) -> Result<(), Error> {
583        self.upload_uniform_fvec_loc(loc, UniformType::MatrixTransposed3, data)
584    }
585
586    pub fn upload_uniform_mat_transposed_3_name<T: AsRef<[f32]>>(
587        &mut self,
588        target_name: &str,
589        data: &T,
590    ) -> Result<(), Error> {
591        self.upload_uniform_fvec_name(target_name, UniformType::MatrixTransposed3, data)
592    }
593
594
595    pub fn upload_uniform_mat_transposed_2_loc<T: AsRef<[f32]>>(
596        &mut self,
597        loc: &WebGlUniformLocation,
598        data: &T,
599    ) -> Result<(), Error> {
600        self.upload_uniform_fvec_loc(loc, UniformType::MatrixTransposed2, data)
601    }
602
603    pub fn upload_uniform_mat_transposed_2_name<T: AsRef<[f32]>>(
604        &mut self,
605        target_name: &str,
606        data: &T,
607    ) -> Result<(), Error> {
608        self.upload_uniform_fvec_name(target_name, UniformType::MatrixTransposed2, data)
609    }
610
611    pub fn upload_uniform_fvec_4_loc<T: AsRef<[f32]>>(
612        &mut self,
613        loc: &WebGlUniformLocation,
614        data: &T,
615    ) -> Result<(), Error> {
616        self.upload_uniform_fvec_loc(loc, UniformType::Vector4, data)
617    }
618
619    pub fn upload_uniform_fvec_4_name<T: AsRef<[f32]>>(
620        &mut self,
621        target_name: &str,
622        data: &T,
623    ) -> Result<(), Error> {
624        self.upload_uniform_fvec_name(target_name, UniformType::Vector4, data)
625    }
626    pub fn upload_uniform_fvec_3_loc<T: AsRef<[f32]>>(
627        &mut self,
628        loc: &WebGlUniformLocation,
629        data: &T,
630    ) -> Result<(), Error> {
631        self.upload_uniform_fvec_loc(loc, UniformType::Vector3, data)
632    }
633    pub fn upload_uniform_fvec_3_name<T: AsRef<[f32]>>(
634        &mut self,
635        target_name: &str,
636        data: &T,
637    ) -> Result<(), Error> {
638        self.upload_uniform_fvec_name(target_name, UniformType::Vector3, data)
639    }
640    pub fn upload_uniform_fvec_2_loc<T: AsRef<[f32]>>(
641        &mut self,
642        loc: &WebGlUniformLocation,
643        data: &T,
644    ) -> Result<(), Error> {
645        self.upload_uniform_fvec_loc(loc, UniformType::Vector2, data)
646    }
647    pub fn upload_uniform_fvec_2_name<T: AsRef<[f32]>>(
648        &mut self,
649        target_name: &str,
650        data: &T,
651    ) -> Result<(), Error> {
652        self.upload_uniform_fvec_name(target_name, UniformType::Vector2, data)
653    }
654    pub fn upload_uniform_fvec_1_loc<T: AsRef<[f32]>>(
655        &mut self,
656        loc: &WebGlUniformLocation,
657        data: &T,
658    ) -> Result<(), Error> {
659        self.upload_uniform_fvec_loc(loc, UniformType::Vector1, data)
660    }
661    pub fn upload_uniform_fvec_1_name<T: AsRef<[f32]>>(
662        &mut self,
663        target_name: &str,
664        data: &T,
665    ) -> Result<(), Error> {
666        self.upload_uniform_fvec_name(target_name, UniformType::Vector1, data)
667    }
668
669    pub fn upload_uniform_ivec_4_loc<T: AsRef<[i32]>>(
670        &mut self,
671        loc: &WebGlUniformLocation,
672        data: &T,
673    ) -> Result<(), Error> {
674        self.upload_uniform_ivec_loc(loc, UniformType::Vector4, data)
675    }
676    pub fn upload_uniform_ivec_4_name<T: AsRef<[i32]>>(
677        &mut self,
678        target_name: &str,
679        data: &T,
680    ) -> Result<(), Error> {
681        self.upload_uniform_ivec_name(target_name, UniformType::Vector4, data)
682    }
683    pub fn upload_uniform_ivec_3_loc<T: AsRef<[i32]>>(
684        &mut self,
685        loc: &WebGlUniformLocation,
686        data: &T,
687    ) -> Result<(), Error> {
688        self.upload_uniform_ivec_loc(loc, UniformType::Vector3, data)
689    }
690    pub fn upload_uniform_ivec_3_name<T: AsRef<[i32]>>(
691        &mut self,
692        target_name: &str,
693        data: &T,
694    ) -> Result<(), Error> {
695        self.upload_uniform_ivec_name(target_name, UniformType::Vector3, data)
696    }
697    pub fn upload_uniform_ivec_2_loc<T: AsRef<[i32]>>(
698        &mut self,
699        loc: &WebGlUniformLocation,
700        data: &T,
701    ) -> Result<(), Error> {
702        self.upload_uniform_ivec_loc(loc, UniformType::Vector2, data)
703    }
704    pub fn upload_uniform_ivec_2_name<T: AsRef<[i32]>>(
705        &mut self,
706        target_name: &str,
707        data: &T,
708    ) -> Result<(), Error> {
709        self.upload_uniform_ivec_name(target_name, UniformType::Vector2, data)
710    }
711    pub fn upload_uniform_ivec_1_loc<T: AsRef<[i32]>>(
712        &mut self,
713        loc: &WebGlUniformLocation,
714        data: &T,
715    ) -> Result<(), Error> {
716        self.upload_uniform_ivec_loc(loc, UniformType::Vector1, data)
717    }
718    pub fn upload_uniform_ivec_1_name<T: AsRef<[i32]>>(
719        &mut self,
720        target_name: &str,
721        data: &T,
722    ) -> Result<(), Error> {
723        self.upload_uniform_ivec_name(target_name, UniformType::Vector1, data)
724    }
725
726    pub fn upload_uniform_fvals_4_loc(
727        &mut self,
728        loc: &WebGlUniformLocation,
729        data: (f32, f32, f32, f32),
730    ) {
731        self.gl.awsm_uniform4f(&loc, data.0, data.1, data.2, data.3);
732    }
733
734    pub fn upload_uniform_fvals_4_name(
735        &mut self,
736        target_name: &str,
737        data: (f32, f32, f32, f32),
738    ) -> Result<(), Error> {
739        let loc = self.get_uniform_location_name(&target_name)?;
740        self.gl.awsm_uniform4f(&loc, data.0, data.1, data.2, data.3);
741        Ok(())
742    }
743    pub fn upload_uniform_fvals_3_loc(
744        &mut self,
745        loc: &WebGlUniformLocation,
746        data: (f32, f32, f32),
747    ) {
748        self.gl.awsm_uniform3f(&loc, data.0, data.1, data.2);
749    }
750    pub fn upload_uniform_fvals_3_name(
751        &mut self,
752        target_name: &str,
753        data: (f32, f32, f32),
754    ) -> Result<(), Error> {
755        let loc = self.get_uniform_location_name(&target_name)?;
756        self.gl.awsm_uniform3f(&loc, data.0, data.1, data.2);
757        Ok(())
758    }
759    pub fn upload_uniform_fvals_2_loc(
760        &mut self,
761        loc: &WebGlUniformLocation,
762        data: (f32, f32),
763    ) {
764        self.gl.awsm_uniform2f(&loc, data.0, data.1);
765    }
766    pub fn upload_uniform_fvals_2_name(&mut self, target_name: &str, data: (f32, f32)) -> Result<(), Error> {
767        let loc = self.get_uniform_location_name(&target_name)?;
768        self.gl.awsm_uniform2f(&loc, data.0, data.1);
769        Ok(())
770    }
771    pub fn upload_uniform_fval_loc(
772        &mut self,
773        loc: &WebGlUniformLocation,
774        data: f32
775    ) {
776        self.gl.awsm_uniform1f(&loc, data);
777    }
778    pub fn upload_uniform_fval_name(&mut self, target_name: &str, data: f32) -> Result<(), Error> {
779        let loc = self.get_uniform_location_name(&target_name)?;
780        self.gl.awsm_uniform1f(&loc, data);
781        Ok(())
782    }
783
784    pub fn upload_uniform_ivals_4_loc(
785        &mut self,
786        loc: &WebGlUniformLocation,
787        data: (i32, i32, i32, i32),
788    ) {
789        self.gl.awsm_uniform4i(&loc, data.0, data.1, data.2, data.3);
790    }
791
792    pub fn upload_uniform_ivals_4_name(
793        &mut self,
794        target_name: &str,
795        data: (i32, i32, i32, i32),
796    ) -> Result<(), Error> {
797        let loc = self.get_uniform_location_name(&target_name)?;
798        self.gl.awsm_uniform4i(&loc, data.0, data.1, data.2, data.3);
799        Ok(())
800    }
801    pub fn upload_uniform_ivals_3_loc(
802        &mut self,
803        loc: &WebGlUniformLocation,
804        data: (i32, i32, i32),
805    ) {
806        self.gl.awsm_uniform3i(&loc, data.0, data.1, data.2);
807    }
808    pub fn upload_uniform_ivals_3_name(
809        &mut self,
810        target_name: &str,
811        data: (i32, i32, i32),
812    ) -> Result<(), Error> {
813        let loc = self.get_uniform_location_name(&target_name)?;
814        self.gl.awsm_uniform3i(&loc, data.0, data.1, data.2);
815        Ok(())
816    }
817    pub fn upload_uniform_ivals_2_loc(
818        &mut self,
819        loc: &WebGlUniformLocation,
820        data: (i32, i32),
821    ) {
822        self.gl.awsm_uniform2i(&loc, data.0, data.1);
823    }
824    pub fn upload_uniform_ivals_2_name(&mut self, target_name: &str, data: (i32, i32)) -> Result<(), Error> {
825        let loc = self.get_uniform_location_name(&target_name)?;
826        self.gl.awsm_uniform2i(&loc, data.0, data.1);
827        Ok(())
828    }
829    pub fn upload_uniform_ival_loc(
830        &mut self,
831        loc: &WebGlUniformLocation,
832        data: i32,
833    ) {
834        self.gl.awsm_uniform1i(&loc, data);
835    }
836    pub fn upload_uniform_ival_name(&mut self, target_name: &str, data: i32) -> Result<(), Error> {
837        let loc = self.get_uniform_location_name(&target_name)?;
838        self.gl.awsm_uniform1i(&loc, data);
839        Ok(())
840    }
841}
842
843impl WebGlRenderer<WebGl2RenderingContext> {
844
845    pub fn get_uniform_index_name(&self, program_id:Id, name:&str) -> Result<u32, Error> {
846        let program_info = self
847            .program_lookup
848            .get(program_id)
849            .ok_or(Error::from(NativeError::MissingShaderProgram))?;
850
851        self.gl.awsm_get_uniform_indices(&program_info.program, &vec![name])
852            .ok_or(Error::from(NativeError::UniformIndex(Some(name.to_owned()))))
853            .map(|indices| {
854                indices[0]
855            })
856    }
857
858    pub fn upload_uniform_uvec_loc<T: AsRef<[u32]>>(
859        &mut self,
860        loc: &WebGlUniformLocation,
861        _type: UniformType,
862        data: &T,
863    ) -> Result<(), Error> {
864        self.gl.awsm_upload_uniform_uvec(&loc, _type, data)
865    }
866
867    pub fn upload_uniform_uvec_name<T: AsRef<[u32]>>(
868        &mut self,
869        target_name: &str,
870        _type: UniformType,
871        data: &T,
872    ) -> Result<(), Error> {
873        let loc = self.get_uniform_location_name(&target_name)?;
874        self.upload_uniform_uvec_loc(&loc, _type, data)
875    }
876
877    pub fn upload_uniform_uvec_4_loc<T: AsRef<[u32]>>(
878        &mut self,
879        loc: &WebGlUniformLocation,
880        data: &T,
881    ) -> Result<(), Error> {
882        self.upload_uniform_uvec_loc(loc, UniformType::Vector4, data)
883    }
884
885    pub fn upload_uniform_uvec_4_name<T: AsRef<[u32]>>(
886        &mut self,
887        target_name: &str,
888        data: &T,
889    ) -> Result<(), Error> {
890        self.upload_uniform_uvec_name(target_name, UniformType::Vector4, data)
891    }
892    pub fn upload_uniform_uvec_3_loc<T: AsRef<[u32]>>(
893        &mut self,
894        loc: &WebGlUniformLocation,
895        data: &T,
896    ) -> Result<(), Error> {
897        self.upload_uniform_uvec_loc(loc, UniformType::Vector3, data)
898    }
899    pub fn upload_uniform_uvec_3_name<T: AsRef<[u32]>>(
900        &mut self,
901        target_name: &str,
902        data: &T,
903    ) -> Result<(), Error> {
904        self.upload_uniform_uvec_name(target_name, UniformType::Vector3, data)
905    }
906    pub fn upload_uniform_uvec_2_loc<T: AsRef<[u32]>>(
907        &mut self,
908        loc: &WebGlUniformLocation,
909        data: &T,
910    ) -> Result<(), Error> {
911        self.upload_uniform_uvec_loc(loc, UniformType::Vector2, data)
912    }
913    pub fn upload_uniform_uvec_2_name<T: AsRef<[u32]>>(
914        &mut self,
915        target_name: &str,
916        data: &T,
917    ) -> Result<(), Error> {
918        self.upload_uniform_uvec_name(target_name, UniformType::Vector2, data)
919    }
920    pub fn upload_uniform_uvec_1_loc<T: AsRef<[u32]>>(
921        &mut self,
922        loc: &WebGlUniformLocation,
923        data: &T,
924    ) -> Result<(), Error> {
925        self.upload_uniform_uvec_loc(loc, UniformType::Vector1, data)
926    }
927    pub fn upload_uniform_uvec_1_name<T: AsRef<[u32]>>(
928        &mut self,
929        target_name: &str,
930        data: &T,
931    ) -> Result<(), Error> {
932        self.upload_uniform_uvec_name(target_name, UniformType::Vector1, data)
933    }
934
935    pub fn upload_uniform_uvals_4_loc(
936        &mut self,
937        loc: &WebGlUniformLocation,
938        data: (u32, u32, u32, u32),
939    ) {
940        self.gl.awsm_uniform4ui(&loc, data.0, data.1, data.2, data.3);
941    }
942
943    pub fn upload_uniform_uvals_4_name(
944        &mut self,
945        target_name: &str,
946        data: (u32, u32, u32, u32),
947    ) -> Result<(), Error> {
948        let loc = self.get_uniform_location_name(&target_name)?;
949        self.gl.awsm_uniform4ui(&loc, data.0, data.1, data.2, data.3);
950        Ok(())
951    }
952    pub fn upload_uniform_uvals_3_loc(
953        &mut self,
954        loc: &WebGlUniformLocation,
955        data: (u32, u32, u32),
956    ) {
957        self.gl.awsm_uniform3ui(&loc, data.0, data.1, data.2);
958    }
959    pub fn upload_uniform_uvals_3_name(
960        &mut self,
961        target_name: &str,
962        data: (u32, u32, u32),
963    ) -> Result<(), Error> {
964        let loc = self.get_uniform_location_name(&target_name)?;
965        self.gl.awsm_uniform3ui(&loc, data.0, data.1, data.2);
966        Ok(())
967    }
968    pub fn upload_uniform_uvals_2_loc(
969        &mut self,
970        loc: &WebGlUniformLocation,
971        data: (u32, u32),
972    ) {
973        self.gl.awsm_uniform2ui(&loc, data.0, data.1);
974    }
975    pub fn upload_uniform_uvals_2_name(&mut self, target_name: &str, data: (u32, u32)) -> Result<(), Error> {
976        let loc = self.get_uniform_location_name(&target_name)?;
977        self.gl.awsm_uniform2ui(&loc, data.0, data.1);
978        Ok(())
979    }
980    pub fn upload_uniform_uval_loc(
981        &mut self,
982        loc: &WebGlUniformLocation,
983        data: u32,
984    ) {
985        self.gl.awsm_uniform1ui(&loc, data);
986    }
987    pub fn upload_uniform_uval_name(&mut self, target_name: &str, data: u32) -> Result<(), Error> {
988        let loc = self.get_uniform_location_name(&target_name)?;
989        self.gl.awsm_uniform1ui(&loc, data);
990        Ok(())
991    }
992}