Sfoglia il codice sorgente

Fix seams between globe tiles

Johannes Hofmann 7 anni fa
parent
commit
7034b667a9
4 ha cambiato i file con 35 aggiunte e 5 eliminazioni
  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 Vedi File

@@ -2,8 +2,9 @@
2 2
 precision mediump float;
3 3
 
4 4
 varying vec2 v_tex;
5
+varying vec4 v_tex_minmax;
5 6
 uniform sampler2D tex_map;
6 7
 
7 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 Vedi File

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

+ 23
- 2
src/globe_tile_layer.rs Vedi File

@@ -38,12 +38,17 @@ impl GlobeTileLayer {
38 38
         program.add_attribute(
39 39
             cx,
40 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 43
         program.add_attribute(
44 44
             cx,
45 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 53
         check_gl_errors!(cx);
49 54
 
@@ -115,12 +120,22 @@ impl GlobeTileLayer {
115 120
 
116 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 125
         for tile_y in 0..16 {
119 126
             for tile_x in 0..16 {
120 127
                 let tc = TileCoord::new(4, tile_x, tile_y);
121 128
                 let slot = tile_atlas.store(cx, tc, source, cache, true)
122 129
                     .unwrap_or_else(TileAtlas::default_slot);
123 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 140
                 for &(tc, sub_tile_a) in &tc.children() {
126 141
                     for &(tc, sub_tile_b) in &tc.children() {
@@ -157,11 +172,17 @@ impl GlobeTileLayer {
157 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 174
                         vertex_data.extend(&p1);
175
+                        vertex_data.extend(&minmax);
160 176
                         vertex_data.extend(&p2);
177
+                        vertex_data.extend(&minmax);
161 178
                         vertex_data.extend(&p3);
179
+                        vertex_data.extend(&minmax);
162 180
                         vertex_data.extend(&p1);
181
+                        vertex_data.extend(&minmax);
163 182
                         vertex_data.extend(&p3);
183
+                        vertex_data.extend(&minmax);
164 184
                         vertex_data.extend(&p4);
185
+                        vertex_data.extend(&minmax);
165 186
                     }
166 187
                 }
167 188
             }

+ 7
- 2
src/tile_atlas.rs Vedi File

@@ -140,6 +140,12 @@ impl TileAtlas {
140 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 149
     /// Finds textures from the cache for a given slice of visible tiles. The texture atlas may not
144 150
     /// be big enough to hold all textures at once; a possible remainder of untextured visible tiles is
145 151
     /// returned as an `Option`.
@@ -156,8 +162,7 @@ impl TileAtlas {
156 162
     {
157 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 167
         let num_usable_slots = self.slots_lru.len();
163 168
         // The number of actually used slots may be lower, because slots can be used multiple times