diff --git a/app-proto/src/add_remove.rs b/app-proto/src/add_remove.rs index c9b73de..ed05c16 100644 --- a/app-proto/src/add_remove.rs +++ b/app-proto/src/add_remove.rs @@ -138,6 +138,7 @@ fn load_pointed_assemb(assembly: &Assembly) { Point::new( format!("point_front"), format!("Front point"), + [0.875_f32, 0.875_f32, 0.875_f32], engine::point(0.0, 0.0, FRAC_1_SQRT_2) ) ); @@ -145,6 +146,7 @@ fn load_pointed_assemb(assembly: &Assembly) { Point::new( format!("point_back"), format!("Back point"), + [0.875_f32, 0.875_f32, 0.875_f32], engine::point(0.0, 0.0, -FRAC_1_SQRT_2) ) ); @@ -166,6 +168,7 @@ fn load_pointed_assemb(assembly: &Assembly) { Point::new( format!("point{index_x}{index_y}"), format!("Point {index_x}{index_y}"), + [0.4*(2.0 + x) as f32, 0.4*(2.0 + y) as f32, 0.4*(2.0 - x*y) as f32], engine::point(x, y, 0.0) ) ); diff --git a/app-proto/src/assembly.rs b/app-proto/src/assembly.rs index fae10f5..5cf1ba8 100644 --- a/app-proto/src/assembly.rs +++ b/app-proto/src/assembly.rs @@ -202,6 +202,7 @@ impl ProblemPoser for Sphere { pub struct Point { pub id: String, pub label: String, + pub color: ElementColor, pub representation: Signal>, pub regulators: Signal>, pub serial: u64, @@ -214,11 +215,13 @@ impl Point { pub fn new( id: String, label: String, + color: ElementColor, representation: DVector ) -> Point { Point { id, label, + color, representation: create_signal(representation), regulators: create_signal(BTreeSet::default()), serial: Self::next_serial(), @@ -236,6 +239,7 @@ impl Element for Point { Point::new( id, format!("Point {id_num}"), + [0.875_f32, 0.875_f32, 0.875_f32], point(0.0, 0.0, 0.0) ) } diff --git a/app-proto/src/display.rs b/app-proto/src/display.rs index 115f1df..154d495 100644 --- a/app-proto/src/display.rs +++ b/app-proto/src/display.rs @@ -48,15 +48,22 @@ impl SceneSpheres { } struct ScenePoints { - representations: Vec> + representations: Vec>, + colors: Vec, } impl ScenePoints { fn new() -> ScenePoints { ScenePoints { - representations: Vec::new() + representations: Vec::new(), + colors: Vec::new() } } + + fn push(&mut self, representation: DVector, color: ElementColor) { + self.representations.push(representation); + self.colors.push(color); + } } pub struct Scene { @@ -135,7 +142,7 @@ impl DisplayItem for Sphere { impl DisplayItem for Point { fn show(&self, scene: &mut Scene, _selected: bool) { let representation = self.representation.get_clone_untracked(); - scene.points.representations.push(representation); + scene.points.push(representation, self.color); } /* SCAFFOLDING */ @@ -211,18 +218,6 @@ fn get_uniform_array_locations( }) } -// find the vertex attribute called `attr_name` in the given program. enable it -// and return its index -fn find_and_enable_attribute( - context: &WebGl2RenderingContext, - program: &WebGlProgram, - attr_name: &str -) -> u32 { - let attr_index = context.get_attrib_location(program, attr_name) as u32; - context.enable_vertex_attrib_array(attr_index); - attr_index -} - // bind the given vertex buffer object to the given vertex attribute fn bind_to_attribute( context: &WebGl2RenderingContext, @@ -267,6 +262,16 @@ fn load_new_buffer( buffer } +fn bind_new_buffer_to_attribute( + context: &WebGl2RenderingContext, + attr_index: u32, + attr_size: i32, + data: &[f32] +) { + let buffer = load_new_buffer(context, data); + bind_to_attribute(context, attr_index, attr_size, &buffer); +} + // the direction in camera space that a mouse event is pointing along fn event_dir(event: &MouseEvent) -> Vector3 { let target: web_sys::Element = event.target().unwrap().unchecked_into(); @@ -405,8 +410,8 @@ pub fn Display() -> View { &JsValue::from("uniform vectors available") ); - // find and enable the sphere program's sole vertex attribute - let viewport_position_attr = find_and_enable_attribute(&ctx, &sphere_program, "position"); + // find the sphere program's vertex attribute + let viewport_position_attr = ctx.get_attrib_location(&sphere_program, "position") as u32; // find the sphere program's uniforms const SPHERE_MAX: usize = 200; @@ -443,8 +448,9 @@ pub fn Display() -> View { ]; let viewport_position_buffer = load_new_buffer(&ctx, &viewport_positions); - // find and enable the point program's sole vertex attribute - let point_position_attr = find_and_enable_attribute(&ctx, &point_program, "position"); + // find the point program's vertex attributes + let point_position_attr = ctx.get_attrib_location(&point_program, "position") as u32; + let point_color_attr = ctx.get_attrib_location(&point_program, "color") as u32; // set up a repainting routine let (_, start_animation_loop, _) = create_raf(move || { @@ -539,6 +545,7 @@ pub fn Display() -> View { if scene_changed.get() { const SPACE_DIM: usize = 3; + const COLOR_SIZE: usize = 3; /* INSTRUMENTS */ // measure mean frame interval @@ -580,6 +587,9 @@ pub fn Display() -> View { // use the sphere rendering program ctx.use_program(Some(&sphere_program)); + // enable the sphere program's vertex attribute + ctx.enable_vertex_attrib_array(viewport_position_attr); + // write the spheres in world coordinates let sphere_reps_world: Vec<_> = scene.spheres.representations.into_iter().map( |rep| (&asm_to_world * rep).cast::() @@ -625,12 +635,19 @@ pub fn Display() -> View { // draw the scene ctx.draw_arrays(WebGl2RenderingContext::TRIANGLES, 0, VERTEX_CNT as i32); + // disable the sphere program's vertex attribute + ctx.disable_vertex_attrib_array(viewport_position_attr); + // --- draw the points --- if !scene.points.representations.is_empty() { // use the point rendering program ctx.use_program(Some(&point_program)); + // enable the point program's vertex attributes + ctx.enable_vertex_attrib_array(point_position_attr); + ctx.enable_vertex_attrib_array(point_color_attr); + // write the points in world coordinates let asm_to_world_sp = asm_to_world.rows(0, SPACE_DIM); let point_positions = DMatrix::from_columns( @@ -639,13 +656,18 @@ pub fn Display() -> View { ).collect::>().as_slice() ).cast::(); - // load the point positions into a new buffer and bind it to the - // position attribute in the vertex shader - let point_position_buffer = load_new_buffer(&ctx, point_positions.as_slice()); - bind_to_attribute(&ctx, point_position_attr, SPACE_DIM as i32, &point_position_buffer); + // load the point positions and colors into new buffers and + // bind them to the corresponding attributes in the vertex + // shader + bind_new_buffer_to_attribute(&ctx, point_position_attr, SPACE_DIM as i32, point_positions.as_slice()); + bind_new_buffer_to_attribute(&ctx, point_color_attr, COLOR_SIZE as i32, scene.points.colors.concat().as_slice()); // draw the scene ctx.draw_arrays(WebGl2RenderingContext::POINTS, 0, point_positions.ncols() as i32); + + // disable the point program's vertex attributes + ctx.disable_vertex_attrib_array(point_position_attr); + ctx.disable_vertex_attrib_array(point_color_attr); } // --- update the display state --- diff --git a/app-proto/src/point.frag b/app-proto/src/point.frag index 984d1c9..2abba0e 100644 --- a/app-proto/src/point.frag +++ b/app-proto/src/point.frag @@ -2,8 +2,10 @@ precision highp float; +in vec3 point_color; + out vec4 outColor; void main() { - outColor = vec4(vec3(1.), 1.); + outColor = vec4(point_color, 1.); } \ No newline at end of file diff --git a/app-proto/src/point.vert b/app-proto/src/point.vert index 6b8c739..49d584b 100644 --- a/app-proto/src/point.vert +++ b/app-proto/src/point.vert @@ -1,6 +1,9 @@ #version 300 es in vec4 position; +in vec3 color; + +out vec3 point_color; // camera const float focal_slope = 0.3; @@ -9,4 +12,6 @@ void main() { float depth = -focal_slope * position.z; gl_Position = vec4(position.xy / depth, 0., 1.); gl_PointSize = 5.; + + point_color = color; } \ No newline at end of file