awsm_web/webgl/
drawing.rs

1use super::{BeginMode, BufferMask, DataType, WebGlCommon, WebGlRenderer, DrawBuffer, Buffer};
2use crate::errors::Error;
3use web_sys::{WebGl2RenderingContext, WebGlRenderingContext};
4use crate::data::{TypedData};
5use js_sys::Array;
6
7pub trait PartialWebGlDrawing {
8    fn awsm_clear(&self, bits: &[BufferMask]);
9    fn awsm_scissor(&self, x: i32, y: i32, width: u32, height: u32);
10    fn awsm_draw_arrays(&self, mode: BeginMode, first: u32, count: u32);
11    fn awsm_draw_elements(&self, mode: BeginMode, count: u32, data_type: DataType, offset: u32);
12}
13
14pub trait PartialWebGl2Drawing {
15    fn awsm_clear_draw_buffer_vf32(&self, buffer:Buffer, draw_buffer_index: usize, values:&[f32]);
16    fn awsm_clear_draw_buffer_vi32(&self, buffer:Buffer, draw_buffer_index: usize, values:&[i32]);
17    fn awsm_clear_draw_buffer_vu32(&self, buffer:Buffer, draw_buffer_index: usize, values:&[u32]);
18    fn awsm_clear_draw_buffer_fi(&self, buffer:Buffer, draw_buffer_index: usize, depth:f32, stencil:i32);
19}
20macro_rules! impl_context {
21    ($($type:ty { $($defs:tt)* })+) => {
22        $(impl PartialWebGlDrawing for $type {
23
24            fn awsm_clear(&self, bits: &[BufferMask]) {
25                let mut combined = 0u32;
26                for bit in bits {
27                    combined = combined | *bit as u32;
28                }
29                self.clear(combined);
30            }
31
32            fn awsm_scissor(&self, x: i32, y: i32, width: u32, height: u32) {
33                self.scissor(x, y, width as i32, height as i32);
34            }
35            fn awsm_draw_arrays(&self, mode: BeginMode, first: u32, count: u32) {
36                self.draw_arrays(mode as u32, first as i32, count as i32);
37            }
38
39            fn awsm_draw_elements(&self, mode: BeginMode, count: u32, data_type:DataType, offset:u32) {
40                self.draw_elements_with_i32(mode as u32, count as i32, data_type as u32, offset as i32);
41            }
42
43            $($defs)*
44        })+
45    };
46}
47
48impl_context! {
49    WebGlRenderingContext{}
50    WebGl2RenderingContext{}
51}
52
53impl PartialWebGl2Drawing for WebGl2RenderingContext {
54    fn awsm_clear_draw_buffer_vf32(&self, buffer:Buffer, draw_buffer_index: usize, values:&[f32]) {
55        self.clear_bufferfv_with_f32_array(buffer as u32, draw_buffer_index as i32, values);
56    }
57    fn awsm_clear_draw_buffer_vi32(&self, buffer:Buffer, draw_buffer_index: usize, values:&[i32]) {
58        self.clear_bufferiv_with_i32_array(buffer as u32, draw_buffer_index as i32, values);
59    }
60    fn awsm_clear_draw_buffer_vu32(&self, buffer:Buffer, draw_buffer_index: usize, values:&[u32]) {
61        self.clear_bufferuiv_with_u32_array(buffer as u32, draw_buffer_index as i32, values);
62    }
63    fn awsm_clear_draw_buffer_fi(&self, buffer:Buffer, draw_buffer_index: usize, depth:f32, stencil:i32) {
64        self.clear_bufferfi(buffer as u32, draw_buffer_index as i32, depth, stencil);
65    }
66}
67
68impl<T: WebGlCommon> WebGlRenderer<T> {
69    pub fn clear(&self, bits: &[BufferMask]) {
70        self.gl.awsm_clear(&bits);
71    }
72    pub fn scissor(&self, x: i32, y: i32, width: u32, height: u32) {
73        self.gl.awsm_scissor(x, y, width, height);
74    }
75
76    pub fn draw_arrays(&self, mode: BeginMode, first: u32, count: u32) {
77        self.gl.awsm_draw_arrays(mode, first, count);
78    }
79
80    pub fn draw_elements(&self, mode: BeginMode, count: u32, data_type: DataType, offset: u32) {
81        self.gl.awsm_draw_elements(mode, count, data_type, offset);
82    }
83}
84
85impl WebGlRenderer<WebGlRenderingContext> {
86    pub fn draw_buffers(&self, target_buffers: &[DrawBuffer]) -> Result<(), Error> {
87        let ext = self.get_extension_draw_buffers()?;
88        let target_buffers:&[u32] = unsafe { std::mem::transmute(target_buffers) };
89
90        let js_array:Array = TypedData::new(target_buffers).into();
91
92        ext.draw_buffers_webgl(&js_array);
93
94        Ok(())
95    }
96}
97
98impl WebGlRenderer<WebGl2RenderingContext> {
99    pub fn draw_buffers(&self, target_buffers: &[DrawBuffer]) -> Result<(), Error> {
100        let target_buffers:&[u32] = unsafe { std::mem::transmute(target_buffers) };
101
102        let js_array:Array = TypedData::new(target_buffers).into();
103
104        self.gl.draw_buffers(&js_array);
105
106        Ok(())
107    }
108
109    //The "reset" values are all according to spec
110
111    pub fn clear_draw_buffer_vf32_values(&self, buffer:Buffer, draw_buffer_index: usize, values:&[f32]) {
112        self.gl.awsm_clear_draw_buffer_vf32(buffer, draw_buffer_index, values);
113    }
114    pub fn reset_color_draw_buffer_vf32(&self, draw_buffer_index: usize) {
115        self.clear_draw_buffer_vf32_values(Buffer::Color, draw_buffer_index, &[0.0, 0.0, 0.0, 0.0]);
116    }
117
118    pub fn clear_draw_buffer_vi32_values(&self, buffer:Buffer, draw_buffer_index: usize, values:&[i32]) {
119        self.gl.awsm_clear_draw_buffer_vi32(buffer, draw_buffer_index, values);
120    }
121    pub fn reset_color_draw_buffer_vi32(&self, draw_buffer_index: usize) {
122        self.clear_draw_buffer_vi32_values(Buffer::Color, draw_buffer_index, &[0, 0, 0, 0]);
123    }
124
125    pub fn clear_draw_buffer_vu32_values(&self, buffer:Buffer, draw_buffer_index: usize, values:&[u32]) {
126        self.gl.awsm_clear_draw_buffer_vu32(buffer, draw_buffer_index, values);
127    }
128    pub fn reset_color_draw_buffer_vu32(&self, draw_buffer_index: usize) {
129        self.clear_draw_buffer_vu32_values(Buffer::Color, draw_buffer_index, &[0, 0, 0, 0]);
130    }
131
132    pub fn clear_draw_buffer_fi(&self, buffer:Buffer, draw_buffer_index: usize, depth:f32, stencil:i32) {
133        self.gl.awsm_clear_draw_buffer_fi(buffer, draw_buffer_index, depth, stencil);
134    }
135
136    pub fn clear_draw_buffer_depth_stencil_values(&self, depth:f32, stencil:i32) {
137        //spec says index must be 0 here
138        self.clear_draw_buffer_fi(Buffer::DepthStencil, 0, depth, stencil);
139    }
140    pub fn reset_depth_stencil_draw_buffer(&self) {
141        self.clear_draw_buffer_depth_stencil_values(1.0, 0)
142    }
143}