add glyph atlas to map
This commit is contained in:
@@ -6,16 +6,12 @@
|
||||
#include <string>
|
||||
#include <set>
|
||||
#include <map>
|
||||
#include <mutex>
|
||||
#include <atomic>
|
||||
|
||||
namespace llmr {
|
||||
|
||||
class Glyph {
|
||||
public:
|
||||
uint32_t id = 0;
|
||||
std::string bitmap;
|
||||
uint16_t width = 0;
|
||||
uint16_t height = 0;
|
||||
};
|
||||
class VectorTileGlyph;
|
||||
|
||||
class GlyphAtlas {
|
||||
public:
|
||||
@@ -34,17 +30,18 @@ public:
|
||||
|
||||
|
||||
Rect<uint16_t> addGlyph(uint64_t tile_id, const std::string& face_name,
|
||||
const Glyph& glyph, uint8_t buffer);
|
||||
const VectorTileGlyph& glyph);
|
||||
void removeGlyphs(uint64_t tile_id);
|
||||
void bind();
|
||||
|
||||
private:
|
||||
std::mutex mtx;
|
||||
const uint16_t width = 0;
|
||||
const uint16_t height = 0;
|
||||
BinPack<uint16_t> bin;
|
||||
std::map<std::string, std::map<uint32_t, GlyphValue>> index;
|
||||
char *const data = NULL;
|
||||
bool dirty = true;
|
||||
char *const data = nullptr;
|
||||
std::atomic<bool> dirty;
|
||||
uint32_t texture = 0;
|
||||
};
|
||||
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
#include <llmr/map/tile_data.hpp>
|
||||
#include <llmr/map/transform.hpp>
|
||||
#include <llmr/style/style.hpp>
|
||||
#include <llmr/style/style.hpp>
|
||||
#include <llmr/geometry/glyph_atlas.hpp>
|
||||
#include <llmr/renderer/painter.hpp>
|
||||
#include <llmr/util/noncopyable.hpp>
|
||||
|
||||
@@ -76,6 +78,7 @@ private:
|
||||
Transform transform;
|
||||
Style style;
|
||||
Painter painter;
|
||||
GlyphAtlas glyphAtlas;
|
||||
|
||||
int32_t min_zoom;
|
||||
int32_t max_zoom;
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include <llmr/util/vec.hpp>
|
||||
#include <llmr/util/mat4.hpp>
|
||||
#include <llmr/util/noncopyable.hpp>
|
||||
#include <llmr/geometry/glyph_atlas.hpp>
|
||||
#include <llmr/geometry/debug_font_buffer.hpp>
|
||||
#include <llmr/geometry/vao.hpp>
|
||||
#include <llmr/platform/platform.hpp>
|
||||
@@ -25,6 +26,7 @@ class LayerDescription;
|
||||
class BucketDescription;
|
||||
class VectorTile;
|
||||
class VectorTileLayer;
|
||||
class VectorTileFace;
|
||||
class FillVertexBuffer;
|
||||
class LineVertexBuffer;
|
||||
class PointVertexBuffer;
|
||||
@@ -54,7 +56,7 @@ public:
|
||||
};
|
||||
|
||||
public:
|
||||
TileData(Tile::ID id, const Style& style);
|
||||
TileData(Tile::ID id, const Style& style, GlyphAtlas& glyphAtlas);
|
||||
~TileData();
|
||||
|
||||
// Start loading the tile.
|
||||
@@ -74,6 +76,9 @@ public:
|
||||
|
||||
const std::string toString() const;
|
||||
|
||||
private:
|
||||
void loadGlyphs(const std::map<std::string, const VectorTileFace>& faces);
|
||||
|
||||
public:
|
||||
const Tile::ID id;
|
||||
std::atomic<State> state;
|
||||
@@ -94,10 +99,12 @@ public:
|
||||
// Holds the buckets of this tile.
|
||||
// They contain the location offsets in the buffers stored above
|
||||
std::map<std::string, std::shared_ptr<Bucket>> buckets;
|
||||
|
||||
private:
|
||||
// Source data
|
||||
std::string data;
|
||||
const Style& style;
|
||||
GlyphAtlas& glyphAtlas;
|
||||
platform::Request *req = nullptr;
|
||||
};
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#include <llmr/geometry/glyph_atlas.hpp>
|
||||
#include <llmr/map/vector_tile.hpp>
|
||||
#include <llmr/platform/gl.hpp>
|
||||
|
||||
#include <cassert>
|
||||
@@ -11,7 +12,8 @@ GlyphAtlas::GlyphAtlas(uint16_t width, uint16_t height)
|
||||
: width(width),
|
||||
height(height),
|
||||
bin(width, height),
|
||||
data(new char[width *height]) {
|
||||
data(new char[width *height]),
|
||||
dirty(true) {
|
||||
}
|
||||
|
||||
GlyphAtlas::~GlyphAtlas() {
|
||||
@@ -19,7 +21,11 @@ GlyphAtlas::~GlyphAtlas() {
|
||||
}
|
||||
|
||||
Rect<uint16_t> GlyphAtlas::addGlyph(uint64_t tile_id, const std::string& face_name,
|
||||
const Glyph& glyph, uint8_t buffer) {
|
||||
const VectorTileGlyph& glyph) {
|
||||
std::lock_guard<std::mutex> lock(mtx);
|
||||
|
||||
// Use constant value for now.
|
||||
const uint8_t buffer = 3;
|
||||
|
||||
std::map<uint32_t, GlyphValue>& face = index[face_name];
|
||||
std::map<uint32_t, GlyphValue>::iterator it = face.find(glyph.id);
|
||||
@@ -77,6 +83,8 @@ Rect<uint16_t> GlyphAtlas::addGlyph(uint64_t tile_id, const std::string& face_na
|
||||
}
|
||||
|
||||
void GlyphAtlas::removeGlyphs(uint64_t tile_id) {
|
||||
std::lock_guard<std::mutex> lock(mtx);
|
||||
|
||||
for (auto& faces : index) {
|
||||
std::map<uint32_t, GlyphValue>& face = faces.second;
|
||||
for (auto it = face.begin(); it != face.end(); /* we advance in the body */) {
|
||||
@@ -124,6 +132,7 @@ void GlyphAtlas::bind() {
|
||||
}
|
||||
|
||||
if (dirty) {
|
||||
std::lock_guard<std::mutex> lock(mtx);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, width, height, 0, GL_ALPHA, GL_UNSIGNED_BYTE, data);
|
||||
dirty = false;
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@ Map::Map(Settings& settings)
|
||||
transform(),
|
||||
style(),
|
||||
painter(transform, settings, style),
|
||||
glyphAtlas(1024, 1024),
|
||||
min_zoom(0),
|
||||
max_zoom(14) {
|
||||
}
|
||||
@@ -278,7 +279,7 @@ TileData::State Map::addTile(const Tile::ID& id) {
|
||||
|
||||
if (!new_tile.data) {
|
||||
// If we don't find working tile data, we're just going to load it.
|
||||
new_tile.data = std::make_shared<TileData>(normalized_id, style);
|
||||
new_tile.data = std::make_shared<TileData>(normalized_id, style, glyphAtlas);
|
||||
new_tile.data->request();
|
||||
tile_data.push_front(new_tile.data);
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
|
||||
using namespace llmr;
|
||||
|
||||
TileData::TileData(Tile::ID id, const Style& style)
|
||||
TileData::TileData(Tile::ID id, const Style& style, GlyphAtlas& glyphAtlas)
|
||||
: id(id),
|
||||
state(State::initial),
|
||||
fillVertexBuffer(std::make_shared<FillVertexBuffer>()),
|
||||
@@ -29,7 +29,8 @@ TileData::TileData(Tile::ID id, const Style& style)
|
||||
triangleElementsBuffer(std::make_shared<TriangleElementsBuffer>()),
|
||||
lineElementsBuffer(std::make_shared<LineElementsBuffer>()),
|
||||
pointElementsBuffer(std::make_shared<PointElementsBuffer>()),
|
||||
style(style) {
|
||||
style(style),
|
||||
glyphAtlas(glyphAtlas) {
|
||||
|
||||
// Initialize tile debug coordinates
|
||||
char coord[32];
|
||||
@@ -87,6 +88,7 @@ bool TileData::parse() {
|
||||
try {
|
||||
double parse_time_start = platform::time();
|
||||
VectorTile tile(pbf((const uint8_t *)data.data(), data.size()));
|
||||
loadGlyphs(tile.faces);
|
||||
parseStyleLayers(tile, style.layers);
|
||||
// double parse_time = (platform::time() - parse_time_start) * 1000.0;
|
||||
if (state == State::obsolete) {
|
||||
@@ -109,6 +111,21 @@ bool TileData::parse() {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void TileData::loadGlyphs(const std::map<std::string, const VectorTileFace>& faces) {
|
||||
std::map<std::string, std::map<uint32_t, Rect<uint16_t>>> rects;
|
||||
for (const std::pair<std::string, const VectorTileFace> pair : faces) {
|
||||
const std::string& name = pair.first;
|
||||
const VectorTileFace& face = pair.second;
|
||||
|
||||
std::map<uint32_t, Rect<uint16_t>>& rect = rects[name];
|
||||
|
||||
for (const VectorTileGlyph& glyph : face.glyphs) {
|
||||
rect.emplace({ glyph.id, glyphAtlas.addGlyph((uint64_t)id, name, glyph) });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TileData::parseStyleLayers(const VectorTile& tile, const std::vector<LayerDescription>& layers) {
|
||||
for (const LayerDescription& layer_desc : layers) {
|
||||
// Cancel early when parsing.
|
||||
|
||||
Reference in New Issue
Block a user