parse line width function and call tile destructor from main thread

This commit is contained in:
Konstantin Käfer
2014-01-29 12:25:50 +01:00
parent 04e16cf2ca
commit d5cae14770
9 changed files with 70 additions and 24 deletions

View File

@@ -67,6 +67,7 @@ private:
int32_t max_zoom;
std::forward_list<Tile::Ptr> tiles;
std::forward_list<Tile::Ptr> historic_tiles;
};
}

View File

@@ -36,6 +36,9 @@ bool null(float z, const std::vector<bool>&);
float constant(float z, const std::vector<float>& values);
bool constant(float z, const std::vector<bool>& values);
float stops(float z, const std::vector<float>& values);
bool stops(float z, const std::vector<bool>& values);
}

View File

@@ -25,7 +25,7 @@ void DebugFontBuffer::addText(const char *text, double left, double baseline, do
if (text[i] < 32 || text[i] > 127) {
continue;
}
glyph &glyph = simplex[(int)text[i]];
glyph& glyph = simplex[(int)text[i]];
if (!glyph.width) {
continue;
}

View File

@@ -1,6 +1,5 @@
#include <llmr/geometry/fill_buffer.hpp>
#include <llmr/platform/gl.hpp>
// #include <cmath>
using namespace llmr;
@@ -51,18 +50,15 @@ void FillBuffer::addElements(uint16_t a, uint16_t b, uint16_t c) {
void FillBuffer::bind() {
if (vertex_buffer == 0) {
glGenBuffers(1, &vertex_buffer);
glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer);
} else {
glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer);
}
if (element_buffer == 0) {
glGenBuffers(1, &element_buffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, element_buffer);
} else {
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, element_buffer);
}
glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, element_buffer);
if (dirty) {
glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(uint16_t), vertices.data(), GL_STATIC_DRAW);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, elements.size() * sizeof(uint16_t), elements.data(), GL_STATIC_DRAW);

View File

@@ -1,6 +1,5 @@
#include <llmr/geometry/line_buffer.hpp>
#include <llmr/platform/gl.hpp>
// #include <cmath>
using namespace llmr;

View File

@@ -132,6 +132,7 @@ Tile::Ptr Map::addTile(const Tile::ID& id) {
// std::cerr << "init " << id.z << "/" << id.x << "/" << id.y << std::endl;
// std::cerr << "add " << tile->toString() << std::endl;
tiles.push_front(tile);
historic_tiles.push_front(tile);
}
return tile;
@@ -273,6 +274,16 @@ void Map::updateTiles() {
tiles.sort([](const Tile::Ptr& a, const Tile::Ptr& b) {
return a->id.z > b->id.z;
});
// Remove all tiles that are only in the list of historic tiles. We do this
// to make sure that the destructor (triggered by shared_ptr count falling
// to 0) is triggered from the main thread.
// TODO: Find a better solution by forcing the destructor to run in the
// main thread, e.g. with a custom deleter on shared_ptr construction?
historic_tiles.remove_if([](const Tile::Ptr& tile) {
return tile.unique();
});
}
bool Map::render() {

View File

@@ -84,6 +84,7 @@ void Painter::setupShaders() {
void Painter::teardown() {
glDeleteBuffers(1, &tile_stencil_buffer);
glDeleteBuffers(1, &tile_border_buffer);
}
void Painter::changeMatrix(const Tile::Ptr& tile) {
@@ -152,17 +153,6 @@ void Painter::render(const Tile::Ptr& tile) {
drawClippingMask();
// switchShader(outlineShader);
// glUniformMatrix4fv(outlineShader->u_matrix, 1, GL_FALSE, matrix);
// // draw lines:
// tile->lineVertex.bind();
// glVertexAttribPointer(outlineShader->a_pos, 2, GL_SHORT, GL_FALSE, 0, BUFFER_OFFSET(0));
// glUniform4f(outlineShader->u_color, 0.0f, 0.0f, 0.0f, 1.0f);
// glUniform2f(outlineShader->u_world, transform.fb_width, transform.fb_height);
// glLineWidth(2.0f);
// glDrawArrays(GL_LINE_STRIP, 0, tile->lineVertex.length());
renderLayers(tile, style.layers);
if (settings.debug) {
@@ -374,7 +364,7 @@ void Painter::renderLine(LineBucket& bucket, const std::string& layer_name) {
// color[3] = Infinity;
// glUniform4fv(lineShader->u_color, color);
// } else {
glUniform4fv(lineShader->u_color, 1, properties.color.data());
glUniform4fv(lineShader->u_color, 1, properties.color.data());
// }

View File

@@ -2,6 +2,7 @@
#include <cassert>
#include <cmath>
using namespace llmr;
@@ -22,4 +23,48 @@ float functions::constant(float z, const std::vector<float>& values) {
bool functions::constant(float z, const std::vector<bool>& values) {
assert(values.size() == 1);
return values.front();
}
}
float functions::stops(float z, const std::vector<float>& stops) {
// We need an even number of stop values.
if (stops.size() % 2 != 0) return 0;
// Accounts for us rendering tiles at 512x512, so our zoom levels are shifted by 1.
z += 1;
bool smaller = false;
float smaller_z, smaller_val;
bool larger = false;
float larger_z, larger_val;
for (uint32_t i = 0; i < stops.size(); i += 2) {
float stop_z = stops[i];
float stop_val = stops[i + 1];
if (stop_z <= z && (!smaller || smaller_z < stop_z)) { smaller = true; smaller_z = stop_z; smaller_val = stop_val; }
if (stop_z >= z && (!larger || larger_z > stop_z)) { larger = true; larger_z = stop_z; larger_val = stop_val; }
}
if (smaller && larger) {
// Exponential interpolation between the values
if (larger_z == smaller_z) return smaller_val;
float val = smaller_val * pow(larger_val / smaller_val, (z - smaller_z) / (larger_z - smaller_z));
return val;
} else if (larger || smaller) {
// Do not draw a line.
return -std::numeric_limits<float>::infinity();
// Exponential extrapolation of the smaller or larger value
//var edge = larger || smaller;
//return Math.pow(2, z) * (edge.val / Math.pow(2, edge.z));
} else {
// No stop defined.
return 1;
}
}
bool functions::stops(float z, const std::vector<bool>& values) {
// TODO
return false;
}

View File

@@ -173,6 +173,7 @@ template <typename T> FunctionProperty<T> Style::parseProperty(pbf data) {
switch((Property)data.varint()) {
case Property::Null: property.function = &functions::null; break;
case Property::Constant: property.function = &functions::constant; break;
case Property::Stops: property.function = &functions::stops; break;
default: property.function = &functions::null; break;
}
} else if (data.tag == 2) { // value
@@ -222,11 +223,11 @@ void Style::cascade(float z) {
const std::string& layer_name = line_pair.first;
const llmr::LineClass& layer = line_pair.second;
// TODO: This should be restricted to fill styles that have actual
// TODO: This should be restricted to line styles that have actual
// values so as to not override with default values.
llmr::LineProperties& stroke = computed.lines[layer_name];
stroke.hidden = layer.hidden(z);
stroke.width = 2; //layer.width(z);
stroke.width = layer.width(z);
stroke.offset = layer.offset(z);
stroke.color = layer.color;
stroke.opacity = layer.opacity(z);