j_webgl/structs/renderable/
cube.rs1use super::*;
2
3struct Inner {
4 program: web_sys::WebGlProgram,
5 vao: web_sys::WebGlVertexArrayObject,
6 matrix_location: web_sys::WebGlUniformLocation,
7}
8
9#[wasm_bindgen::prelude::wasm_bindgen]
10#[derive(Default)]
11pub struct Cube {
12 inner: std::cell::RefCell<Option<Inner>>,
13}
14
15#[wasm_bindgen::prelude::wasm_bindgen]
16impl Cube {
17 pub fn new() -> Result<Cube> {
18 Ok(Cube { inner: std::cell::RefCell::new(None), })
19 }
20}
21
22impl traits::Renderable for Cube {
23 fn render(
24 &self,
25 context: &web_sys::WebGl2RenderingContext,
26 camera: &[f32],
27 ) -> Result<()>
28 {
29 if self.inner.borrow().is_none() {
30 let program = utils::compile_program(
31 context,
32 shaders::vertex::position_matrix()?, shaders::fragment::color()?, )?;
35
36 let position_attribute_location = context
37 .get_attrib_location(&program, "a_position");
38 let matrix_location = context
39 .get_uniform_location(&program, "u_matrix");
40 let color_location = context.get_uniform_location(&program, "u_color");
41
42 let position_buffer = context.create_buffer().unwrap();
43
44 let vao = context.create_vertex_array().unwrap();
45 context.bind_vertex_array(Some(&vao));
46
47 context.enable_vertex_attrib_array(position_attribute_location as u32);
48 context.bind_buffer(web_sys::WebGl2RenderingContext::ARRAY_BUFFER, Some(&position_buffer));
49 let vertices: [f32; 24] = [
50 -0.5, -0.5, 0.5, 0.5, -0.5, 0.5, 0.5, 0.5, 0.5, -0.5, 0.5, 0.5, -0.5, -0.5, -0.5, 0.5, -0.5, -0.5, 0.5, 0.5, -0.5, -0.5, 0.5, -0.5, ];
61
62 let indices: [usize; 36] = [
64 0, 1, 2, 2, 3, 0,
66 4, 6, 5, 6, 4, 7,
68 3, 2, 6, 6, 7, 3,
70 0, 4, 5, 5, 1, 0,
72 1, 5, 6, 6, 2, 1,
74 0, 3, 7, 7, 4, 0,
76 ];
77 let array: Vec<f32> = indices.iter()
78 .fold(Vec::new(), |mut a, i| {
79 a.push(vertices[*i*3]);
80 a.push(vertices[*i*3+1]);
81 a.push(vertices[*i*3+2]);
82 a
83 });
84
85 unsafe {
86 let vertices_array = js_sys::Float32Array::view(array.as_slice());
87 context.buffer_data_with_array_buffer_view(
88 web_sys::WebGl2RenderingContext::ARRAY_BUFFER,
89 &vertices_array,
90 web_sys::WebGl2RenderingContext::STATIC_DRAW,
91 );
92 }
93
94 context.vertex_attrib_pointer_with_i32(position_attribute_location as u32,
95 3, web_sys::WebGl2RenderingContext::FLOAT,
97 false, 0, 0, );
101
102 context.use_program(Some(&program));
103 context.uniform4f(
104 color_location.as_ref(),
105 0.2, 1.0, 0.2, 1.0, );
110
111 *self.inner.borrow_mut() = Some(
112 Inner {
113 program,
114 vao,
115 matrix_location: matrix_location.unwrap(),
116 }
117 );
118 }
119
120 let binding = self.inner.borrow();
121 let inner = binding.as_ref().unwrap();
122
123 context.use_program(Some(&inner.program));
124 context.bind_vertex_array(Some(&inner.vao));
125 context.uniform_matrix4fv_with_f32_array(
126 Some(&inner.matrix_location),
127 false,
128 camera,
129 );
130 context.draw_arrays(
131 web_sys::WebGl2RenderingContext::TRIANGLES,
132 0, 12 * 3, );
135
136 Ok(())
137 }
138}