add glyph atlas to map

This commit is contained in:
Konstantin Käfer
2014-03-12 16:20:52 +01:00
parent d9589573bc
commit be44b6b31f
6 changed files with 50 additions and 16 deletions

View File

@@ -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;
};

View File

@@ -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;

View File

@@ -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;
};

View File

@@ -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;
}

View File

@@ -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);
}

View File

@@ -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.