@@ -22,7 +22,7 @@ void RasterBucket::upload(gl::Context& context) {
22
22
if (!texture) {
23
23
texture = context.createTexture (*image);
24
24
}
25
- if (!vertices .empty ()) {
25
+ if (!segments .empty ()) {
26
26
vertexBuffer = context.createVertexBuffer (std::move (vertices));
27
27
indexBuffer = context.createIndexBuffer (std::move (indices));
28
28
}
@@ -45,6 +45,69 @@ void RasterBucket::setImage(std::shared_ptr<PremultipliedImage> image_) {
45
45
uploaded = false ;
46
46
}
47
47
48
+ void RasterBucket::setMask (TileMask&& mask_) {
49
+ if (mask == mask_) {
50
+ return ;
51
+ }
52
+
53
+ mask = std::move (mask_);
54
+ clear ();
55
+
56
+ if (mask == TileMask{ { 0 , 0 , 0 } }) {
57
+ // We want to render the full tile, and keeping the segments/vertices/indices empty means
58
+ // using the global shared buffers for covering the entire tile.
59
+ return ;
60
+ }
61
+
62
+ // Create a new segment so that we will upload (empty) buffers even when there is nothing to
63
+ // draw for this tile.
64
+ segments.emplace_back (0 , 0 );
65
+
66
+ constexpr const uint16_t vertexLength = 4 ;
67
+
68
+ // Create the vertex buffer for the specified tile mask.
69
+ for (const auto & id : mask) {
70
+ // Create a quad for every masked tile.
71
+ const int32_t vertexExtent = util::EXTENT >> id.z ;
72
+ const int32_t textureExtent = 32768 >> id.z ;
73
+
74
+ const Point <int16_t > tlVertex = { static_cast <int16_t >(id.x * vertexExtent),
75
+ static_cast <int16_t >(id.y * vertexExtent) };
76
+ const Point <int16_t > brVertex = { static_cast <int16_t >(tlVertex.x + vertexExtent),
77
+ static_cast <int16_t >(tlVertex.y + vertexExtent) };
78
+ const Point <uint16_t > tlTexture = { static_cast <uint16_t >(id.x * textureExtent),
79
+ static_cast <uint16_t >(id.y * textureExtent) };
80
+ const Point <uint16_t > brTexture = { static_cast <uint16_t >(tlTexture.x + textureExtent),
81
+ static_cast <uint16_t >(tlTexture.y + textureExtent) };
82
+
83
+ if (segments.back ().vertexLength + vertexLength > std::numeric_limits<uint16_t >::max ()) {
84
+ // Move to a new segments because the old one can't hold the geometry.
85
+ segments.emplace_back (vertices.vertexSize (), indices.indexSize ());
86
+ }
87
+
88
+ vertices.emplace_back (
89
+ RasterProgram::layoutVertex ({ tlVertex.x , tlVertex.y }, { tlTexture.x , tlTexture.y }));
90
+ vertices.emplace_back (
91
+ RasterProgram::layoutVertex ({ brVertex.x , tlVertex.y }, { brTexture.x , tlTexture.y }));
92
+ vertices.emplace_back (
93
+ RasterProgram::layoutVertex ({ tlVertex.x , brVertex.y }, { tlTexture.x , brTexture.y }));
94
+ vertices.emplace_back (
95
+ RasterProgram::layoutVertex ({ brVertex.x , brVertex.y }, { brTexture.x , brTexture.y }));
96
+
97
+ auto & segment = segments.back ();
98
+ assert (segment.vertexLength <= std::numeric_limits<uint16_t >::max ());
99
+ const uint16_t offset = segment.vertexLength ;
100
+
101
+ // 0, 1, 2
102
+ // 1, 2, 3
103
+ indices.emplace_back (offset, offset + 1 , offset + 2 );
104
+ indices.emplace_back (offset + 1 , offset + 2 , offset + 3 );
105
+
106
+ segment.vertexLength += vertexLength;
107
+ segment.indexLength += 6 ;
108
+ }
109
+ }
110
+
48
111
bool RasterBucket::hasData () const {
49
112
return !!image;
50
113
}
0 commit comments