Browse Source

Extract code into marker_layer module

Johannes Hofmann 7 years ago
parent
commit
5f47684dc4
3 changed files with 171 additions and 125 deletions
  1. 1
    0
      src/main.rs
  2. 8
    125
      src/map_view_gl.rs
  3. 162
    0
      src/marker_layer.rs

+ 1
- 0
src/main.rs View File

@@ -23,6 +23,7 @@ pub mod context;
23 23
 pub mod coord;
24 24
 pub mod map_view;
25 25
 pub mod map_view_gl;
26
+pub mod marker_layer;
26 27
 pub mod program;
27 28
 pub mod search;
28 29
 pub mod texture;

+ 8
- 125
src/map_view_gl.rs View File

@@ -1,10 +1,9 @@
1 1
 use ::std::ffi::CStr;
2 2
 use buffer::{Buffer, DrawMode};
3
-use cgmath::{Matrix3, Point2, Transform, vec2, vec3};
4 3
 use context::Context;
5
-use coord::{MapCoord, ScreenCoord, ScreenRect, View};
6
-use image;
4
+use coord::{MapCoord, ScreenCoord, View};
7 5
 use map_view::MapView;
6
+use marker_layer::MarkerLayer;
8 7
 use program::Program;
9 8
 use texture::{Texture, TextureFormat};
10 9
 use tile_atlas::TileAtlas;
@@ -24,10 +23,7 @@ pub struct MapViewGl {
24 23
     tile_buffer: Buffer,
25 24
     tile_cache: TileCache,
26 25
     tile_atlas: TileAtlas,
27
-    marker_buffer: Buffer,
28
-    marker_program: Program,
29
-    marker_tex: Texture,
30
-    markers: Vec<MapCoord>,
26
+    marker_layer: MarkerLayer,
31 27
     last_draw_type: DrawType,
32 28
 }
33 29
 
@@ -104,38 +100,6 @@ impl MapViewGl {
104 100
         );
105 101
         check_gl_errors!(cx);
106 102
 
107
-
108
-        let marker_buffer = Buffer::new(cx, &[], 0);
109
-        cx.bind_buffer(marker_buffer.id());
110
-        check_gl_errors!(cx);
111
-
112
-        let mut marker_program = Program::new(
113
-            cx,
114
-            include_bytes!("../shader/marker.vert"),
115
-            include_bytes!("../shader/marker.frag"),
116
-        ).unwrap();
117
-        check_gl_errors!(cx);
118
-
119
-        let marker_tex = {
120
-            let img = image::load_from_memory(
121
-                include_bytes!("../img/marker.png"),
122
-            ).unwrap();
123
-            Texture::new(cx, &img).unwrap()
124
-        };
125
-
126
-        marker_program.add_texture(cx, &marker_tex, CStr::from_bytes_with_nul(b"tex\0").unwrap());
127
-
128
-        marker_program.add_attribute(
129
-            cx,
130
-            CStr::from_bytes_with_nul(b"position\0").unwrap(),
131
-            &VertexAttribParams::new(2, 4, 0)
132
-        );
133
-        marker_program.add_attribute(
134
-            cx,
135
-            CStr::from_bytes_with_nul(b"tex_coord\0").unwrap(),
136
-            &VertexAttribParams::new(2, 4, 2)
137
-        );
138
-
139 103
         MapViewGl {
140 104
             map_view,
141 105
             viewport_size: initial_size,
@@ -143,10 +107,7 @@ impl MapViewGl {
143 107
             tile_buffer,
144 108
             tile_cache: TileCache::new(move |_tile| update_func(), use_network),
145 109
             tile_atlas: TileAtlas::new(cx, atlas_tex, 256, use_async),
146
-            marker_buffer,
147
-            marker_program,
148
-            marker_tex,
149
-            markers: vec![],
110
+            marker_layer: MarkerLayer::new(cx),
150 111
             last_draw_type: DrawType::Null,
151 112
         }
152 113
     }
@@ -158,7 +119,7 @@ impl MapViewGl {
158 119
     }
159 120
 
160 121
     pub fn add_marker(&mut self, map_coord: MapCoord) {
161
-        self.markers.push(map_coord);
122
+        self.marker_layer.add_marker(map_coord);
162 123
     }
163 124
 
164 125
     pub fn viewport_in_map(&self) -> bool {
@@ -282,88 +243,10 @@ impl MapViewGl {
282 243
     fn draw_marker(&mut self, cx: &mut Context, snap_to_pixel: bool) {
283 244
         if self.last_draw_type != DrawType::Markers {
284 245
             self.last_draw_type = DrawType::Markers;
285
-            cx.set_active_texture_unit(self.marker_tex.unit());
286
-            self.marker_program.enable_vertex_attribs(cx);
287
-            self.marker_program.set_vertex_attribs(cx, &self.marker_buffer);
288
-        }
289
-
290
-        let mut vertex_data: Vec<f32> = vec![];
291
-
292
-        let marker_size = vec2::<f64>(40.0, 50.0);
293
-        let marker_offset = vec2::<f64>(-20.0, -50.0);
294
-
295
-        let scale_x = 2.0 / self.viewport_size.0 as f32;
296
-        let scale_y = -2.0 / self.viewport_size.1 as f32;
297
-
298
-        let tex_mat: Matrix3<f32> = Matrix3::from_cols(
299
-            vec3(marker_size.x as f32, 0.0, 0.0),
300
-            vec3(0.0, marker_size.y as f32, 0.0),
301
-            vec3(marker_offset.x as f32, marker_offset.y as f32, 1.0),
302
-        );
303
-
304
-        let screen_mat: Matrix3<f32> = Matrix3::from_cols(
305
-            vec3(scale_x, 0.0, 0.0),
306
-            vec3(0.0, scale_y, 0.0),
307
-            vec3(-1.0, 1.0, 1.0),
308
-        );
309
-
310
-        let t1 = Point2::new(0.0f32, 0.0);
311
-        let t2 = Point2::new(1.0f32, 0.0);
312
-        let t3 = Point2::new(1.0f32, 1.0);
313
-        let t4 = Point2::new(0.0f32, 1.0);
314
-
315
-        let visible_rect = ScreenRect {
316
-            x: -(marker_offset.x + marker_size.x),
317
-            y: -(marker_offset.y + marker_size.y),
318
-            width: f64::from(self.viewport_size.0) + marker_size.x,
319
-            height: f64::from(self.viewport_size.1) + marker_size.y,
320
-        };
321
-
322
-        for m in &self.markers {
323
-            let screen_pos = {
324
-                let mut sp = self.map_view.map_to_screen_coord(*m);
325
-                if snap_to_pixel {
326
-                    let topleft = self.map_view.map_to_screen_coord(MapCoord::new(0.0, 0.0));
327
-                    let mut snapped = topleft;
328
-                    snapped.snap_to_pixel();
329
-
330
-                    sp.x += snapped.x - topleft.x;
331
-                    sp.y += snapped.y - topleft.y;
332
-                }
333
-                sp
334
-            };
335
-
336
-            if !screen_pos.is_inside(&visible_rect) {
337
-                continue;
338
-            }
339
-            let trans_mat: Matrix3<f32> = Matrix3::from_cols(
340
-                vec3(0.0, 0.0, 0.0),
341
-                vec3(0.0, 0.0, 0.0),
342
-                vec3(screen_pos.x as f32, screen_pos.y as f32, 0.0),
343
-            );
344
-            let mat: Matrix3<f32> = screen_mat * (tex_mat + trans_mat);
345
-
346
-            let p1: Point2<f32> = mat.transform_point(t1);
347
-            let p2: Point2<f32> = mat.transform_point(t2);
348
-            let p3: Point2<f32> = mat.transform_point(t3);
349
-            let p4: Point2<f32> = mat.transform_point(t4);
350
-
351
-            vertex_data.extend::<&[f32; 2]>(p1.as_ref());
352
-            vertex_data.extend::<&[f32; 2]>(t1.as_ref());
353
-            vertex_data.extend::<&[f32; 2]>(p2.as_ref());
354
-            vertex_data.extend::<&[f32; 2]>(t2.as_ref());
355
-            vertex_data.extend::<&[f32; 2]>(p3.as_ref());
356
-            vertex_data.extend::<&[f32; 2]>(t3.as_ref());
357
-            vertex_data.extend::<&[f32; 2]>(p1.as_ref());
358
-            vertex_data.extend::<&[f32; 2]>(t1.as_ref());
359
-            vertex_data.extend::<&[f32; 2]>(p3.as_ref());
360
-            vertex_data.extend::<&[f32; 2]>(t3.as_ref());
361
-            vertex_data.extend::<&[f32; 2]>(p4.as_ref());
362
-            vertex_data.extend::<&[f32; 2]>(t4.as_ref());
246
+            self.marker_layer.prepare_draw(cx);
363 247
         }
364 248
 
365
-        self.marker_buffer.set_data(cx, &vertex_data, vertex_data.len() / 4);
366
-        self.marker_buffer.draw(cx, &self.marker_program, DrawMode::Triangles);
249
+        self.marker_layer.draw(cx, &self.map_view, self.viewport_size, snap_to_pixel);
367 250
     }
368 251
 
369 252
     /// Returns `Err` when tile cache is too small for this view.
@@ -375,7 +258,7 @@ impl MapViewGl {
375 258
 
376 259
         let ret = self.draw_tiles(cx, source, snap_to_pixel);
377 260
 
378
-        if !self.markers.is_empty() {
261
+        if !self.marker_layer.is_empty() {
379 262
             self.draw_marker(cx, snap_to_pixel);
380 263
         }
381 264
 

+ 162
- 0
src/marker_layer.rs View File

@@ -0,0 +1,162 @@
1
+use ::std::ffi::CStr;
2
+use buffer::{Buffer, DrawMode};
3
+use cgmath::{Matrix3, Point2, Transform, vec2, vec3};
4
+use context::Context;
5
+use coord::{MapCoord, ScreenRect};
6
+use image;
7
+use map_view::MapView;
8
+use program::Program;
9
+use texture::Texture;
10
+use vertex_attrib::VertexAttribParams;
11
+
12
+
13
+#[derive(Debug)]
14
+pub struct MarkerLayer {
15
+    buffer: Buffer,
16
+    program: Program,
17
+    texture: Texture,
18
+    positions: Vec<MapCoord>,
19
+}
20
+
21
+impl MarkerLayer {
22
+    pub fn new(cx: &mut Context) -> MarkerLayer {
23
+        let buffer = Buffer::new(cx, &[], 0);
24
+        cx.bind_buffer(buffer.id());
25
+        check_gl_errors!(cx);
26
+
27
+        let mut program = Program::new(
28
+            cx,
29
+            include_bytes!("../shader/marker.vert"),
30
+            include_bytes!("../shader/marker.frag"),
31
+        ).unwrap();
32
+        check_gl_errors!(cx);
33
+
34
+        let texture = {
35
+            let img = image::load_from_memory(
36
+                include_bytes!("../img/marker.png"),
37
+            ).unwrap();
38
+            Texture::new(cx, &img).unwrap()
39
+        };
40
+
41
+        program.add_texture(cx, &texture, CStr::from_bytes_with_nul(b"tex\0").unwrap());
42
+
43
+        program.add_attribute(
44
+            cx,
45
+            CStr::from_bytes_with_nul(b"position\0").unwrap(),
46
+            &VertexAttribParams::new(2, 4, 0)
47
+        );
48
+        program.add_attribute(
49
+            cx,
50
+            CStr::from_bytes_with_nul(b"tex_coord\0").unwrap(),
51
+            &VertexAttribParams::new(2, 4, 2)
52
+        );
53
+
54
+        MarkerLayer {
55
+            buffer,
56
+            program,
57
+            texture,
58
+            positions: vec![],
59
+        }
60
+    }
61
+
62
+    pub fn is_empty(&self) -> bool {
63
+        self.positions.is_empty()
64
+    }
65
+
66
+    pub fn add_marker(&mut self, map_coord: MapCoord) {
67
+        self.positions.push(map_coord);
68
+    }
69
+
70
+    // Has to be called once before one or multiple calls to `draw`.
71
+    pub fn prepare_draw(&mut self, cx: &mut Context) {
72
+        cx.set_active_texture_unit(self.texture.unit());
73
+        self.program.enable_vertex_attribs(cx);
74
+        self.program.set_vertex_attribs(cx, &self.buffer);
75
+    }
76
+
77
+    pub fn draw(
78
+        &mut self,
79
+        cx: &mut Context,
80
+        map_view: &MapView,
81
+        viewport_size: (u32, u32),
82
+        snap_to_pixel: bool
83
+    ) {
84
+        let mut vertex_data: Vec<f32> = vec![];
85
+
86
+        let marker_size = vec2::<f64>(40.0, 50.0);
87
+        let marker_offset = vec2::<f64>(-20.0, -50.0);
88
+
89
+        let scale_x = 2.0 / viewport_size.0 as f32;
90
+        let scale_y = -2.0 / viewport_size.1 as f32;
91
+
92
+        let tex_mat: Matrix3<f32> = Matrix3::from_cols(
93
+            vec3(marker_size.x as f32, 0.0, 0.0),
94
+            vec3(0.0, marker_size.y as f32, 0.0),
95
+            vec3(marker_offset.x as f32, marker_offset.y as f32, 1.0),
96
+        );
97
+
98
+        let screen_mat: Matrix3<f32> = Matrix3::from_cols(
99
+            vec3(scale_x, 0.0, 0.0),
100
+            vec3(0.0, scale_y, 0.0),
101
+            vec3(-1.0, 1.0, 1.0),
102
+        );
103
+
104
+        let t1 = Point2::new(0.0f32, 0.0);
105
+        let t2 = Point2::new(1.0f32, 0.0);
106
+        let t3 = Point2::new(1.0f32, 1.0);
107
+        let t4 = Point2::new(0.0f32, 1.0);
108
+
109
+        let visible_rect = ScreenRect {
110
+            x: -(marker_offset.x + marker_size.x),
111
+            y: -(marker_offset.y + marker_size.y),
112
+            width: f64::from(viewport_size.0) + marker_size.x,
113
+            height: f64::from(viewport_size.1) + marker_size.y,
114
+        };
115
+
116
+        for map_pos in &self.positions {
117
+            let screen_pos = {
118
+                let mut sp = map_view.map_to_screen_coord(*map_pos);
119
+                if snap_to_pixel {
120
+                    let topleft = map_view.map_to_screen_coord(MapCoord::new(0.0, 0.0));
121
+                    let mut snapped = topleft;
122
+                    snapped.snap_to_pixel();
123
+
124
+                    sp.x += snapped.x - topleft.x;
125
+                    sp.y += snapped.y - topleft.y;
126
+                }
127
+                sp
128
+            };
129
+
130
+            if !screen_pos.is_inside(&visible_rect) {
131
+                continue;
132
+            }
133
+            let trans_mat: Matrix3<f32> = Matrix3::from_cols(
134
+                vec3(0.0, 0.0, 0.0),
135
+                vec3(0.0, 0.0, 0.0),
136
+                vec3(screen_pos.x as f32, screen_pos.y as f32, 0.0),
137
+            );
138
+            let mat: Matrix3<f32> = screen_mat * (tex_mat + trans_mat);
139
+
140
+            let p1: Point2<f32> = mat.transform_point(t1);
141
+            let p2: Point2<f32> = mat.transform_point(t2);
142
+            let p3: Point2<f32> = mat.transform_point(t3);
143
+            let p4: Point2<f32> = mat.transform_point(t4);
144
+
145
+            vertex_data.extend::<&[f32; 2]>(p1.as_ref());
146
+            vertex_data.extend::<&[f32; 2]>(t1.as_ref());
147
+            vertex_data.extend::<&[f32; 2]>(p2.as_ref());
148
+            vertex_data.extend::<&[f32; 2]>(t2.as_ref());
149
+            vertex_data.extend::<&[f32; 2]>(p3.as_ref());
150
+            vertex_data.extend::<&[f32; 2]>(t3.as_ref());
151
+            vertex_data.extend::<&[f32; 2]>(p1.as_ref());
152
+            vertex_data.extend::<&[f32; 2]>(t1.as_ref());
153
+            vertex_data.extend::<&[f32; 2]>(p3.as_ref());
154
+            vertex_data.extend::<&[f32; 2]>(t3.as_ref());
155
+            vertex_data.extend::<&[f32; 2]>(p4.as_ref());
156
+            vertex_data.extend::<&[f32; 2]>(t4.as_ref());
157
+        }
158
+
159
+        self.buffer.set_data(cx, &vertex_data, vertex_data.len() / 4);
160
+        self.buffer.draw(cx, &self.program, DrawMode::Triangles);
161
+    }
162
+}