Browse Source

Fix seams between globe tiles

Johannes Hofmann 7 years ago
parent
commit
7034b667a9
4 changed files with 35 additions and 5 deletions
  1. 2
    1
      shader/globe_tile.frag
  2. 3
    0
      shader/globe_tile.vert
  3. 23
    2
      src/globe_tile_layer.rs
  4. 7
    2
      src/tile_atlas.rs

+ 2
- 1
shader/globe_tile.frag View File

2
 precision mediump float;
2
 precision mediump float;
3
 
3
 
4
 varying vec2 v_tex;
4
 varying vec2 v_tex;
5
+varying vec4 v_tex_minmax;
5
 uniform sampler2D tex_map;
6
 uniform sampler2D tex_map;
6
 
7
 
7
 void main() {
8
 void main() {
8
-    gl_FragColor = vec4(texture2D(tex_map, v_tex.xy).rgb, 1.0);
9
+    gl_FragColor = vec4(texture2D(tex_map, clamp(v_tex.xy, v_tex_minmax.xy, v_tex_minmax.zw)).rgb, 1.0);
9
 }
10
 }

+ 3
- 0
shader/globe_tile.vert View File

3
 
3
 
4
 attribute vec3 position;
4
 attribute vec3 position;
5
 attribute vec2 tex_coord;
5
 attribute vec2 tex_coord;
6
+attribute vec4 tex_minmax;
6
 
7
 
7
 varying vec2 v_tex;
8
 varying vec2 v_tex;
9
+varying vec4 v_tex_minmax;
8
 
10
 
9
 void main() {
11
 void main() {
10
     gl_Position = vec4(position.xy, 0.0, 1.0);
12
     gl_Position = vec4(position.xy, 0.0, 1.0);
11
     v_tex = tex_coord;
13
     v_tex = tex_coord;
14
+    v_tex_minmax = tex_minmax;
12
 }
15
 }

+ 23
- 2
src/globe_tile_layer.rs View File

38
         program.add_attribute(
38
         program.add_attribute(
39
             cx,
39
             cx,
40
             CStr::from_bytes_with_nul(b"position\0").unwrap(),
40
             CStr::from_bytes_with_nul(b"position\0").unwrap(),
41
-            &VertexAttribParams::new(3, 5, 0)
41
+            &VertexAttribParams::new(3, 9, 0)
42
         );
42
         );
43
         program.add_attribute(
43
         program.add_attribute(
44
             cx,
44
             cx,
45
             CStr::from_bytes_with_nul(b"tex_coord\0").unwrap(),
45
             CStr::from_bytes_with_nul(b"tex_coord\0").unwrap(),
46
-            &VertexAttribParams::new(2, 5, 3)
46
+            &VertexAttribParams::new(2, 9, 3)
47
+        );
48
+        program.add_attribute(
49
+            cx,
50
+            CStr::from_bytes_with_nul(b"tex_minmax\0").unwrap(),
51
+            &VertexAttribParams::new(4, 9, 5)
47
         );
52
         );
48
         check_gl_errors!(cx);
53
         check_gl_errors!(cx);
49
 
54
 
115
 
120
 
116
         let rot_mat = Transform::<Point3<f32>>::concat(&rot_mat_y, &rot_mat_x);
121
         let rot_mat = Transform::<Point3<f32>>::concat(&rot_mat_y, &rot_mat_x);
117
 
122
 
123
+        let (inset_x, inset_y) = tile_atlas.texture_margins();
124
+
118
         for tile_y in 0..16 {
125
         for tile_y in 0..16 {
119
             for tile_x in 0..16 {
126
             for tile_x in 0..16 {
120
                 let tc = TileCoord::new(4, tile_x, tile_y);
127
                 let tc = TileCoord::new(4, tile_x, tile_y);
121
                 let slot = tile_atlas.store(cx, tc, source, cache, true)
128
                 let slot = tile_atlas.store(cx, tc, source, cache, true)
122
                     .unwrap_or_else(TileAtlas::default_slot);
129
                     .unwrap_or_else(TileAtlas::default_slot);
123
                 let texrect = tile_atlas.slot_to_texture_rect(slot);
130
                 let texrect = tile_atlas.slot_to_texture_rect(slot);
131
+                let tex_minmax = texrect.inset(inset_x, inset_y);
132
+
133
+                let minmax = [
134
+                    tex_minmax.x1 as f32,
135
+                    tex_minmax.y1 as f32,
136
+                    tex_minmax.x2 as f32,
137
+                    tex_minmax.y2 as f32,
138
+                ];
124
 
139
 
125
                 for &(tc, sub_tile_a) in &tc.children() {
140
                 for &(tc, sub_tile_a) in &tc.children() {
126
                     for &(tc, sub_tile_b) in &tc.children() {
141
                     for &(tc, sub_tile_b) in &tc.children() {
157
                         let p4 = [p4.x as f32, p4.y as f32, p4.z as f32, texrect.x1 as f32, texrect.y2 as f32];
172
                         let p4 = [p4.x as f32, p4.y as f32, p4.z as f32, texrect.x1 as f32, texrect.y2 as f32];
158
 
173
 
159
                         vertex_data.extend(&p1);
174
                         vertex_data.extend(&p1);
175
+                        vertex_data.extend(&minmax);
160
                         vertex_data.extend(&p2);
176
                         vertex_data.extend(&p2);
177
+                        vertex_data.extend(&minmax);
161
                         vertex_data.extend(&p3);
178
                         vertex_data.extend(&p3);
179
+                        vertex_data.extend(&minmax);
162
                         vertex_data.extend(&p1);
180
                         vertex_data.extend(&p1);
181
+                        vertex_data.extend(&minmax);
163
                         vertex_data.extend(&p3);
182
                         vertex_data.extend(&p3);
183
+                        vertex_data.extend(&minmax);
164
                         vertex_data.extend(&p4);
184
                         vertex_data.extend(&p4);
185
+                        vertex_data.extend(&minmax);
165
                     }
186
                     }
166
                 }
187
                 }
167
             }
188
             }

+ 7
- 2
src/tile_atlas.rs View File

140
         slot
140
         slot
141
     }
141
     }
142
 
142
 
143
+    /// Return 0.5 pixels in texture coordinates for both dimensions.
144
+    pub fn texture_margins(&self) -> (f64, f64) {
145
+        (0.5 / f64::from(self.texture.width()),
146
+         0.5 / f64::from(self.texture.height()))
147
+    }
148
+
143
     /// Finds textures from the cache for a given slice of visible tiles. The texture atlas may not
149
     /// Finds textures from the cache for a given slice of visible tiles. The texture atlas may not
144
     /// be big enough to hold all textures at once; a possible remainder of untextured visible tiles is
150
     /// be big enough to hold all textures at once; a possible remainder of untextured visible tiles is
145
     /// returned as an `Option`.
151
     /// returned as an `Option`.
156
     {
162
     {
157
         let mut tvt = Vec::with_capacity(visible_tiles.len());
163
         let mut tvt = Vec::with_capacity(visible_tiles.len());
158
 
164
 
159
-        let inset_x = 0.5 / f64::from(self.texture.width());
160
-        let inset_y = 0.5 / f64::from(self.texture.height());
165
+        let (inset_x, inset_y) = self.texture_margins();
161
 
166
 
162
         let num_usable_slots = self.slots_lru.len();
167
         let num_usable_slots = self.slots_lru.len();
163
         // The number of actually used slots may be lower, because slots can be used multiple times
168
         // The number of actually used slots may be lower, because slots can be used multiple times