j_webgl/structs/renderable/
cube_with_normals.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 CubeWithNormals {
12 inner: std::cell::RefCell<Option<Inner>>,
13}
14
15#[wasm_bindgen::prelude::wasm_bindgen]
16impl CubeWithNormals {
17 pub fn new() -> Result<CubeWithNormals> {
18 Ok(CubeWithNormals { inner: std::cell::RefCell::new(None), })
19 }
20}
21
22impl traits::Renderable for CubeWithNormals {
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::matrix_position_normal()?,
33 shaders::fragment::color_light()?,
34 )?;
35
36 let position_attribute_location = context.get_attrib_location(&program, "a_position");
37 let normal_attribute_location = context.get_attrib_location(&program, "a_normal");
38 let matrix_location = context.get_uniform_location(&program, "u_matrix");
39 let color_location = context.get_uniform_location(&program, "u_color");
40 let reverse_light_direction_location = context.get_uniform_location(&program, "u_reverseLightDirection");
41
42 let vertices: [f32; 24] = [
43 -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, ];
54
55 let indices: [usize; 36] = [
57 0, 1, 2, 2, 3, 0,
59 4, 6, 5, 6, 4, 7,
61 3, 2, 6, 6, 7, 3,
63 0, 4, 5, 5, 1, 0,
65 1, 5, 6, 6, 2, 1,
67 0, 3, 7, 7, 4, 0,
69 ];
70 let mut normals = Vec::<f32>::new();
71 for _ in 0..6 { normals.append(&mut vec![ 0.0, 0.0, 1.0, ]); } for _ in 0..6 { normals.append(&mut vec![ 0.0, 0.0, -1.0, ]); } for _ in 0..6 { normals.append(&mut vec![ 0.0, 1.0, 0.0, ]); } for _ in 0..6 { normals.append(&mut vec![ 0.0, -1.0, 0.0, ]); } for _ in 0..6 { normals.append(&mut vec![ 1.0, 0.0, 0.0, ]); } for _ in 0..6 { normals.append(&mut vec![-1.0, 0.0, 0.0, ]); } let array: Vec<f32> = indices.iter()
79 .fold(Vec::new(), |mut a, i| {
80 a.push(vertices[*i*3]);
81 a.push(vertices[*i*3+1]);
82 a.push(vertices[*i*3+2]);
83 a
84 });
85
86 let position_buffer = context.create_buffer().unwrap();
88 let vao = context.create_vertex_array().unwrap();
89 context.bind_vertex_array(Some(&vao));
90 context.enable_vertex_attrib_array(position_attribute_location as u32);
91 context.bind_buffer(web_sys::WebGl2RenderingContext::ARRAY_BUFFER, Some(&position_buffer));
92 unsafe {
93 let vertices_array = js_sys::Float32Array::view(array.as_slice());
94 context.buffer_data_with_array_buffer_view(
95 web_sys::WebGl2RenderingContext::ARRAY_BUFFER,
96 &vertices_array,
97 web_sys::WebGl2RenderingContext::STATIC_DRAW,
98 );
99 }
100 context.vertex_attrib_pointer_with_i32(position_attribute_location as u32,
101 3, web_sys::WebGl2RenderingContext::FLOAT,
103 false, 0, 0, );
107
108
109 let normal_buffer = context.create_buffer().unwrap();
111 context.enable_vertex_attrib_array(normal_attribute_location as u32);
112 context.bind_buffer(web_sys::WebGl2RenderingContext::ARRAY_BUFFER, Some(&normal_buffer));
113 unsafe {
114 let array = js_sys::Float32Array::view(normals.as_slice());
115 context.buffer_data_with_array_buffer_view(
116 web_sys::WebGl2RenderingContext::ARRAY_BUFFER,
117 &array,
118 web_sys::WebGl2RenderingContext::STATIC_DRAW,
119 );
120 }
121 context.vertex_attrib_pointer_with_i32(normal_attribute_location as u32,
122 3, web_sys::WebGl2RenderingContext::FLOAT,
124 false, 0, 0, );
128
129 context.use_program(Some(&program));
131 context.uniform4f(
132 color_location.as_ref(),
133 0.2, 1.0, 0.2, 1.0, );
138
139 context.uniform3f(
141 reverse_light_direction_location.as_ref(),
142 0.5, 0.7, 1.0,
143 );
144
145 *self.inner.borrow_mut() = Some(
146 Inner {
147 program,
148 vao,
149 matrix_location: matrix_location.unwrap(),
150 }
151 );
152 }
153
154 let binding = self.inner.borrow();
155 let inner = binding.as_ref().unwrap();
156
157 context.use_program(Some(&inner.program));
158 context.bind_vertex_array(Some(&inner.vao));
159 context.uniform_matrix4fv_with_f32_array(
160 Some(&inner.matrix_location),
161 false,
162 camera,
163 );
164 context.draw_arrays(
165 web_sys::WebGl2RenderingContext::TRIANGLES,
166 0, 12 * 3, );
169
170 Ok(())
171 }
172}