viewercloud/
renderer.rs

1//! The pointcloud Renderer for persistant pointcloud.
2//! It uses OpenGL.shader for fast computation.
3use kiss3d::camera::Camera;
4use kiss3d::context::Context;
5use kiss3d::renderer::Renderer;
6use kiss3d::resource::{Effect, GPUVec, ShaderAttribute, ShaderUniform};
7use na::{Matrix4, Point3};
8use nalgebra as na;
9
10/// Structure which manages the display of persistant Pointcloud.
11pub struct PointCloudRenderer {
12    shader: Effect,
13    pos: ShaderAttribute<Point3<f32>>,
14    color: ShaderAttribute<Point3<f32>>,
15    proj: ShaderUniform<Matrix4<f32>>,
16    view: ShaderUniform<Matrix4<f32>>,
17    colored_points: GPUVec<Point3<f32>>,
18    point_size: f32,
19}
20
21impl PointCloudRenderer {
22    /// Creates a new points renderer.
23    pub fn new(point_size: f32, point_cloud_data: GPUVec<Point3<f32>>) -> PointCloudRenderer {
24        let mut shader = Effect::new_from_str(VERTEX_SHADER_SRC, FRAGMENT_SHADER_SRC);
25
26        shader.use_program();
27
28        PointCloudRenderer {
29            colored_points: point_cloud_data,
30            pos: shader.get_attrib::<Point3<f32>>("position").unwrap(),
31            color: shader.get_attrib::<Point3<f32>>("color").unwrap(),
32            proj: shader.get_uniform::<Matrix4<f32>>("proj").unwrap(),
33            view: shader.get_uniform::<Matrix4<f32>>("view").unwrap(),
34            shader,
35            point_size,
36        }
37    }
38    /// Compute the number of points in the PointCloud.
39    pub fn num_points(&self) -> usize {
40        self.colored_points.len() / 2
41    }
42}
43
44impl Renderer for PointCloudRenderer {
45    /// Actually draws the points.
46    fn render(&mut self, pass: usize, camera: &mut dyn Camera) {
47        if self.colored_points.len() == 0 {
48            return;
49        }
50
51        self.shader.use_program();
52        self.pos.enable();
53        self.color.enable();
54
55        camera.upload(pass, &mut self.proj, &mut self.view);
56
57        self.color.bind_sub_buffer(&mut self.colored_points, 1, 1);
58        self.pos.bind_sub_buffer(&mut self.colored_points, 1, 0);
59
60        let ctxt = Context::get();
61        ctxt.point_size(self.point_size);
62        ctxt.draw_arrays(Context::POINTS, 0, (self.colored_points.len() - 10) as i32);
63        self.pos.disable();
64        self.color.disable();
65    }
66}
67
68const VERTEX_SHADER_SRC: &str = "#version 100
69    attribute vec3 position;
70    attribute vec3 color;
71    varying   vec3 Color;
72    uniform   mat4 proj;
73    uniform   mat4 view;
74    void main() {
75        gl_Position = proj * view * vec4(position, 1.0);
76        Color = color;
77    }";
78
79const FRAGMENT_SHADER_SRC: &str = "#version 100
80#ifdef GL_FRAGMENT_PRECISION_HIGH
81   precision highp float;
82#else
83   precision mediump float;
84#endif
85    varying vec3 Color;
86    void main() {
87        gl_FragColor = vec4(Color, 1.0);
88    }";