forked from StudioInfinity/dyna3
Color points
In the process, find and correct a misunderstanding about vertex attributes. Here's my current understanding. Vertex attributes are program-independent. When you make a draw call, every enabled attribute has to have a vertex buffer object bound to it. A simple way to make sure this happens is to enable only the attributes used by the active program.
This commit is contained in:
parent
1945086586
commit
0fbb071506
5 changed files with 60 additions and 24 deletions
|
@ -138,6 +138,7 @@ fn load_pointed_assemb(assembly: &Assembly) {
|
||||||
Point::new(
|
Point::new(
|
||||||
format!("point_front"),
|
format!("point_front"),
|
||||||
format!("Front point"),
|
format!("Front point"),
|
||||||
|
[0.875_f32, 0.875_f32, 0.875_f32],
|
||||||
engine::point(0.0, 0.0, FRAC_1_SQRT_2)
|
engine::point(0.0, 0.0, FRAC_1_SQRT_2)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
@ -145,6 +146,7 @@ fn load_pointed_assemb(assembly: &Assembly) {
|
||||||
Point::new(
|
Point::new(
|
||||||
format!("point_back"),
|
format!("point_back"),
|
||||||
format!("Back point"),
|
format!("Back point"),
|
||||||
|
[0.875_f32, 0.875_f32, 0.875_f32],
|
||||||
engine::point(0.0, 0.0, -FRAC_1_SQRT_2)
|
engine::point(0.0, 0.0, -FRAC_1_SQRT_2)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
@ -166,6 +168,7 @@ fn load_pointed_assemb(assembly: &Assembly) {
|
||||||
Point::new(
|
Point::new(
|
||||||
format!("point{index_x}{index_y}"),
|
format!("point{index_x}{index_y}"),
|
||||||
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)
|
engine::point(x, y, 0.0)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
|
@ -202,6 +202,7 @@ impl ProblemPoser for Sphere {
|
||||||
pub struct Point {
|
pub struct Point {
|
||||||
pub id: String,
|
pub id: String,
|
||||||
pub label: String,
|
pub label: String,
|
||||||
|
pub color: ElementColor,
|
||||||
pub representation: Signal<DVector<f64>>,
|
pub representation: Signal<DVector<f64>>,
|
||||||
pub regulators: Signal<BTreeSet<RegulatorKey>>,
|
pub regulators: Signal<BTreeSet<RegulatorKey>>,
|
||||||
pub serial: u64,
|
pub serial: u64,
|
||||||
|
@ -214,11 +215,13 @@ impl Point {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
id: String,
|
id: String,
|
||||||
label: String,
|
label: String,
|
||||||
|
color: ElementColor,
|
||||||
representation: DVector<f64>
|
representation: DVector<f64>
|
||||||
) -> Point {
|
) -> Point {
|
||||||
Point {
|
Point {
|
||||||
id,
|
id,
|
||||||
label,
|
label,
|
||||||
|
color,
|
||||||
representation: create_signal(representation),
|
representation: create_signal(representation),
|
||||||
regulators: create_signal(BTreeSet::default()),
|
regulators: create_signal(BTreeSet::default()),
|
||||||
serial: Self::next_serial(),
|
serial: Self::next_serial(),
|
||||||
|
@ -236,6 +239,7 @@ impl Element for Point {
|
||||||
Point::new(
|
Point::new(
|
||||||
id,
|
id,
|
||||||
format!("Point {id_num}"),
|
format!("Point {id_num}"),
|
||||||
|
[0.875_f32, 0.875_f32, 0.875_f32],
|
||||||
point(0.0, 0.0, 0.0)
|
point(0.0, 0.0, 0.0)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,15 +48,22 @@ impl SceneSpheres {
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ScenePoints {
|
struct ScenePoints {
|
||||||
representations: Vec<DVector<f64>>
|
representations: Vec<DVector<f64>>,
|
||||||
|
colors: Vec<ElementColor>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ScenePoints {
|
impl ScenePoints {
|
||||||
fn new() -> ScenePoints {
|
fn new() -> ScenePoints {
|
||||||
ScenePoints {
|
ScenePoints {
|
||||||
representations: Vec::new()
|
representations: Vec::new(),
|
||||||
|
colors: Vec::new()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn push(&mut self, representation: DVector<f64>, color: ElementColor) {
|
||||||
|
self.representations.push(representation);
|
||||||
|
self.colors.push(color);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Scene {
|
pub struct Scene {
|
||||||
|
@ -135,7 +142,7 @@ impl DisplayItem for Sphere {
|
||||||
impl DisplayItem for Point {
|
impl DisplayItem for Point {
|
||||||
fn show(&self, scene: &mut Scene, _selected: bool) {
|
fn show(&self, scene: &mut Scene, _selected: bool) {
|
||||||
let representation = self.representation.get_clone_untracked();
|
let representation = self.representation.get_clone_untracked();
|
||||||
scene.points.representations.push(representation);
|
scene.points.push(representation, self.color);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* SCAFFOLDING */
|
/* SCAFFOLDING */
|
||||||
|
@ -211,18 +218,6 @@ fn get_uniform_array_locations<const N: usize>(
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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
|
// bind the given vertex buffer object to the given vertex attribute
|
||||||
fn bind_to_attribute(
|
fn bind_to_attribute(
|
||||||
context: &WebGl2RenderingContext,
|
context: &WebGl2RenderingContext,
|
||||||
|
@ -267,6 +262,16 @@ fn load_new_buffer(
|
||||||
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
|
// the direction in camera space that a mouse event is pointing along
|
||||||
fn event_dir(event: &MouseEvent) -> Vector3<f64> {
|
fn event_dir(event: &MouseEvent) -> Vector3<f64> {
|
||||||
let target: web_sys::Element = event.target().unwrap().unchecked_into();
|
let target: web_sys::Element = event.target().unwrap().unchecked_into();
|
||||||
|
@ -405,8 +410,8 @@ pub fn Display() -> View {
|
||||||
&JsValue::from("uniform vectors available")
|
&JsValue::from("uniform vectors available")
|
||||||
);
|
);
|
||||||
|
|
||||||
// find and enable the sphere program's sole vertex attribute
|
// find the sphere program's vertex attribute
|
||||||
let viewport_position_attr = find_and_enable_attribute(&ctx, &sphere_program, "position");
|
let viewport_position_attr = ctx.get_attrib_location(&sphere_program, "position") as u32;
|
||||||
|
|
||||||
// find the sphere program's uniforms
|
// find the sphere program's uniforms
|
||||||
const SPHERE_MAX: usize = 200;
|
const SPHERE_MAX: usize = 200;
|
||||||
|
@ -443,8 +448,9 @@ pub fn Display() -> View {
|
||||||
];
|
];
|
||||||
let viewport_position_buffer = load_new_buffer(&ctx, &viewport_positions);
|
let viewport_position_buffer = load_new_buffer(&ctx, &viewport_positions);
|
||||||
|
|
||||||
// find and enable the point program's sole vertex attribute
|
// find the point program's vertex attributes
|
||||||
let point_position_attr = find_and_enable_attribute(&ctx, &point_program, "position");
|
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
|
// set up a repainting routine
|
||||||
let (_, start_animation_loop, _) = create_raf(move || {
|
let (_, start_animation_loop, _) = create_raf(move || {
|
||||||
|
@ -539,6 +545,7 @@ pub fn Display() -> View {
|
||||||
|
|
||||||
if scene_changed.get() {
|
if scene_changed.get() {
|
||||||
const SPACE_DIM: usize = 3;
|
const SPACE_DIM: usize = 3;
|
||||||
|
const COLOR_SIZE: usize = 3;
|
||||||
|
|
||||||
/* INSTRUMENTS */
|
/* INSTRUMENTS */
|
||||||
// measure mean frame interval
|
// measure mean frame interval
|
||||||
|
@ -580,6 +587,9 @@ pub fn Display() -> View {
|
||||||
// use the sphere rendering program
|
// use the sphere rendering program
|
||||||
ctx.use_program(Some(&sphere_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
|
// write the spheres in world coordinates
|
||||||
let sphere_reps_world: Vec<_> = scene.spheres.representations.into_iter().map(
|
let sphere_reps_world: Vec<_> = scene.spheres.representations.into_iter().map(
|
||||||
|rep| (&asm_to_world * rep).cast::<f32>()
|
|rep| (&asm_to_world * rep).cast::<f32>()
|
||||||
|
@ -625,12 +635,19 @@ pub fn Display() -> View {
|
||||||
// draw the scene
|
// draw the scene
|
||||||
ctx.draw_arrays(WebGl2RenderingContext::TRIANGLES, 0, VERTEX_CNT as i32);
|
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 ---
|
// --- draw the points ---
|
||||||
|
|
||||||
if !scene.points.representations.is_empty() {
|
if !scene.points.representations.is_empty() {
|
||||||
// use the point rendering program
|
// use the point rendering program
|
||||||
ctx.use_program(Some(&point_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
|
// write the points in world coordinates
|
||||||
let asm_to_world_sp = asm_to_world.rows(0, SPACE_DIM);
|
let asm_to_world_sp = asm_to_world.rows(0, SPACE_DIM);
|
||||||
let point_positions = DMatrix::from_columns(
|
let point_positions = DMatrix::from_columns(
|
||||||
|
@ -639,13 +656,18 @@ pub fn Display() -> View {
|
||||||
).collect::<Vec<_>>().as_slice()
|
).collect::<Vec<_>>().as_slice()
|
||||||
).cast::<f32>();
|
).cast::<f32>();
|
||||||
|
|
||||||
// load the point positions into a new buffer and bind it to the
|
// load the point positions and colors into new buffers and
|
||||||
// position attribute in the vertex shader
|
// bind them to the corresponding attributes in the vertex
|
||||||
let point_position_buffer = load_new_buffer(&ctx, point_positions.as_slice());
|
// shader
|
||||||
bind_to_attribute(&ctx, point_position_attr, SPACE_DIM as i32, &point_position_buffer);
|
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
|
// draw the scene
|
||||||
ctx.draw_arrays(WebGl2RenderingContext::POINTS, 0, point_positions.ncols() as i32);
|
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 ---
|
// --- update the display state ---
|
||||||
|
|
|
@ -2,8 +2,10 @@
|
||||||
|
|
||||||
precision highp float;
|
precision highp float;
|
||||||
|
|
||||||
|
in vec3 point_color;
|
||||||
|
|
||||||
out vec4 outColor;
|
out vec4 outColor;
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
outColor = vec4(vec3(1.), 1.);
|
outColor = vec4(point_color, 1.);
|
||||||
}
|
}
|
|
@ -1,6 +1,9 @@
|
||||||
#version 300 es
|
#version 300 es
|
||||||
|
|
||||||
in vec4 position;
|
in vec4 position;
|
||||||
|
in vec3 color;
|
||||||
|
|
||||||
|
out vec3 point_color;
|
||||||
|
|
||||||
// camera
|
// camera
|
||||||
const float focal_slope = 0.3;
|
const float focal_slope = 0.3;
|
||||||
|
@ -9,4 +12,6 @@ void main() {
|
||||||
float depth = -focal_slope * position.z;
|
float depth = -focal_slope * position.z;
|
||||||
gl_Position = vec4(position.xy / depth, 0., 1.);
|
gl_Position = vec4(position.xy / depth, 0., 1.);
|
||||||
gl_PointSize = 5.;
|
gl_PointSize = 5.;
|
||||||
|
|
||||||
|
point_color = color;
|
||||||
}
|
}
|
Loading…
Add table
Add a link
Reference in a new issue