From 828d8ba26f24a733f5cf50f6e47c489ad9a17a03 Mon Sep 17 00:00:00 2001 From: "Justin R. Miller" Date: Fri, 14 Feb 2014 18:13:12 -0800 Subject: [PATCH 01/37] refs #60: first cut of POI rendering * add basic marker style to stylesheet * pass through marker style to PBF conversion * marker/point tile parsing, bucket, buffer, shaders, etc. * new sprite hosting for 1x/2x variants * sprite load accepts screen scale argument --- bin/convert-style.js | 38 +++++++++--- bin/style.js | 2 + include/llmr/geometry/point_buffer.hpp | 19 ++++++ include/llmr/map/map.hpp | 4 +- include/llmr/map/tile.hpp | 3 + include/llmr/platform/platform.hpp | 2 +- include/llmr/renderer/painter.hpp | 4 ++ include/llmr/renderer/point_bucket.hpp | 56 +++++++++++++++++ include/llmr/renderer/shader-point.hpp | 37 +++++++++++ include/llmr/shader/shaders.hpp | 1 + include/llmr/style/class_description.hpp | 1 + include/llmr/style/properties.hpp | 20 ++++-- include/llmr/style/sprite.hpp | 2 +- include/llmr/style/style.hpp | 2 + ios/MBXViewController.mm | 2 +- resources/style.pbf | Bin 1050 -> 1090 bytes src/geometry/point_buffer.cpp | 12 ++++ src/map/map.cpp | 13 ++-- src/map/tile.cpp | 21 +++++++ src/renderer/painter.cpp | 33 ++++++++++ src/renderer/point_bucket.cpp | 75 +++++++++++++++++++++++ src/renderer/shader-point.cpp | 66 ++++++++++++++++++++ src/shader/point.fragment.glsl | 25 ++++++++ src/shader/point.vertex.glsl | 10 +++ src/shader/shaders.cpp | 4 ++ src/style/resources.cpp | 7 ++- src/style/sprite.cpp | 8 ++- src/style/style.cpp | 46 +++++++++++++- 28 files changed, 483 insertions(+), 30 deletions(-) create mode 100644 include/llmr/geometry/point_buffer.hpp create mode 100644 include/llmr/renderer/point_bucket.hpp create mode 100644 include/llmr/renderer/shader-point.hpp create mode 100644 src/geometry/point_buffer.cpp create mode 100644 src/renderer/point_bucket.cpp create mode 100644 src/renderer/shader-point.cpp create mode 100644 src/shader/point.fragment.glsl create mode 100644 src/shader/point.vertex.glsl diff --git a/bin/convert-style.js b/bin/convert-style.js index 57aee0136..a79f46cf7 100755 --- a/bin/convert-style.js +++ b/bin/convert-style.js @@ -6,8 +6,6 @@ var style = require('./style.js'); var Protobuf = require('./protobuf.js'); var fs = require('fs'); -// var fs = require('fs'); - var pbf = new Protobuf(); // enum @@ -181,23 +179,47 @@ function createLineClass(layer, name) { return pbf; } +function createMarkerClass(layer, name) { + var pbf = new Protobuf(); + pbf.writeTaggedString(1 /* layer_name */, name); + + if ('color' in layer) { + var color = layer.color.match(/^#([0-9a-f]{6})$/i); + if (!color) { + console.warn('invalid color'); + } else { + pbf.writeTaggedUInt32(3 /* color */, parseInt(color[1] + 'ff', 16)); + } + } + + if ('size' in layer) { + pbf.writeMessage(4 /* size */, convertProperty(layer.size)); + } + + if ('opacity' in layer) { + pbf.writeMessage(6 /* opacity */, convertProperty(layer.opacity)); + } + + if ('image' in layer) { + pbf.writeTaggedString(8 /* image */, layer.image); + } + + return pbf; +} function createClass(klass) { var pbf = new Protobuf(); pbf.writeTaggedString(1 /* name */, klass.name); for (var name in klass.layers) { switch (klass.layers[name].type) { - case 'fill': pbf.writeMessage(2 /* fill */, createFillClass(klass.layers[name], name)); break; - case 'line': pbf.writeMessage(3 /* line */, createLineClass(klass.layers[name], name)); break; + case 'fill': pbf.writeMessage(2 /* fill */, createFillClass(klass.layers[name], name)); break; + case 'line': pbf.writeMessage(3 /* line */, createLineClass(klass.layers[name], name)); break; + case 'marker': pbf.writeMessage(4 /* marker */, createMarkerClass(klass.layers[name], name)); break; } } return pbf; } - - - - for (var name in style.buckets) { var bucket = style.buckets[name]; pbf.writeMessage(1 /* bucket */, createBucket(bucket, name)); diff --git a/bin/style.js b/bin/style.js index 1596e30a6..0383c3210 100644 --- a/bin/style.js +++ b/bin/style.js @@ -140,6 +140,8 @@ module.exports = { }, "alcohol": { "type": "marker", + "color": "#999999", + "size": 24, "image": "alcohol-shop" } } diff --git a/include/llmr/geometry/point_buffer.hpp b/include/llmr/geometry/point_buffer.hpp new file mode 100644 index 000000000..8c01a20ee --- /dev/null +++ b/include/llmr/geometry/point_buffer.hpp @@ -0,0 +1,19 @@ +#ifndef LLMR_GEOMETRY_POINT_BUFFER +#define LLMR_GEOMETRY_POINT_BUFFER + +#include "buffer.hpp" + +namespace llmr { + + class PointVertexBuffer : public Buffer< + 4 // 2 coordinates per vertex (== 4 bytes) + > { + public: + typedef int16_t vertex_type; + + void add(vertex_type x, vertex_type y); + }; + +} + +#endif diff --git a/include/llmr/map/map.hpp b/include/llmr/map/map.hpp index 84cb4d12e..ada84f05b 100644 --- a/include/llmr/map/map.hpp +++ b/include/llmr/map/map.hpp @@ -20,7 +20,7 @@ public: ~Map(); /* setup */ - void setup(); + void setup(float pixelRatio = 1); void loadStyle(const uint8_t *const data, uint32_t bytes); void loadSprite(const std::string& url); void loadSettings(); @@ -75,6 +75,8 @@ private: int32_t min_zoom; int32_t max_zoom; + float pixel_ratio; + std::forward_list> tiles; std::forward_list> historic_tiles; }; diff --git a/include/llmr/map/tile.hpp b/include/llmr/map/tile.hpp index 99286a953..dd107eb7b 100644 --- a/include/llmr/map/tile.hpp +++ b/include/llmr/map/tile.hpp @@ -23,6 +23,7 @@ class VectorTile; class VectorTileLayer; class FillVertexBuffer; class LineVertexBuffer; +class PointVertexBuffer; class TriangleElementsBuffer; class LineElementsBuffer; class PointElementsBuffer; @@ -59,6 +60,7 @@ public: std::shared_ptr createBucket(const VectorTile& tile, const BucketDescription& bucket_desc); std::shared_ptr createFillBucket(const VectorTileLayer& layer, const BucketDescription& bucket_desc); std::shared_ptr createLineBucket(const VectorTileLayer& layer, const BucketDescription& bucket_desc); + std::shared_ptr createPointBucket(const VectorTileLayer& layer, const BucketDescription& bucket_desc); void cancel(); @@ -77,6 +79,7 @@ public: std::shared_ptr fillVertexBuffer; std::shared_ptr lineVertexBuffer; + std::shared_ptr pointVertexBuffer; std::shared_ptr triangleElementsBuffer; std::shared_ptr lineElementsBuffer; diff --git a/include/llmr/platform/platform.hpp b/include/llmr/platform/platform.hpp index f56e738ff..bf40ae85f 100644 --- a/include/llmr/platform/platform.hpp +++ b/include/llmr/platform/platform.hpp @@ -6,7 +6,7 @@ #include #define kTileURL "http://a.gl-api-us-east-1.tilestream.net/v3/mapbox.mapbox-streets-v4/%d/%d/%d.gl.pbf" -#define kSpriteURL "http://mapbox-kkaefer.s3.amazonaws.com/static/sprite" +#define kSpriteURL "https://dl.dropboxusercontent.com/u/575564/sprite" namespace llmr { diff --git a/include/llmr/renderer/painter.hpp b/include/llmr/renderer/painter.hpp index 47d6a500c..165da3724 100644 --- a/include/llmr/renderer/painter.hpp +++ b/include/llmr/renderer/painter.hpp @@ -12,6 +12,7 @@ #include #include #include +#include namespace llmr { @@ -23,6 +24,7 @@ class Tile; class FillBucket; class LineBucket; +class PointBucket; class Painter : private util::noncopyable { public: @@ -36,6 +38,7 @@ public: void renderBackground(); void renderFill(FillBucket& bucket, const std::string& layer_name, const Tile::ID& id); void renderLine(LineBucket& bucket, const std::string& layer_name, const Tile::ID& id); + void renderPoint(PointBucket& bucket, const std::string& layer_name, const Tile::ID& id); private: void setupShaders(); @@ -63,6 +66,7 @@ private: std::unique_ptr lineShader; std::unique_ptr linejoinShader; std::unique_ptr patternShader; + std::unique_ptr pointShader; // Set up the stencil quad we're using to generate the stencil mask. VertexBuffer tileStencilBuffer = { diff --git a/include/llmr/renderer/point_bucket.hpp b/include/llmr/renderer/point_bucket.hpp new file mode 100644 index 000000000..4f9a3d353 --- /dev/null +++ b/include/llmr/renderer/point_bucket.hpp @@ -0,0 +1,56 @@ +#ifndef LLMR_RENDERER_POINTBUCKET +#define LLMR_RENDERER_POINTBUCKET + +#include +#include +#include +#include + +#include +#include + +#ifndef BUFFER_OFFSET +#define BUFFER_OFFSET(i) ((char *)nullptr + (i)) +#endif + +namespace llmr { + +class Style; +class PointVertexBuffer; +class BucketDescription; +class PointShader; +struct Coordinate; +struct pbf; + +class PointBucket : public Bucket { + typedef ElementGroup group_type; +public: + PointBucket(const std::shared_ptr& vertexBuffer, + const std::shared_ptr& elementsBuffer, + const BucketDescription& bucket_desc); + + virtual void render(Painter& painter, const std::string& layer_name, const Tile::ID& id); + + void addGeometry(pbf& data); + void addGeometry(Coordinate& point); + + bool hasPoints() const; + + void drawPoints(PointShader& shader); + +public: + const BucketGeometryDescription geometry; + +private: + std::shared_ptr vertexBuffer; + std::shared_ptr elementsBuffer; + + const uint32_t vertex_start; + const uint32_t elements_start; + + std::vector groups; +}; + +} + +#endif diff --git a/include/llmr/renderer/shader-point.hpp b/include/llmr/renderer/shader-point.hpp new file mode 100644 index 000000000..12605fb5a --- /dev/null +++ b/include/llmr/renderer/shader-point.hpp @@ -0,0 +1,37 @@ +#ifndef LLMR_RENDERER_SHADER_POINT +#define LLMR_RENDERER_SHADER_POINT + +#include "shader.hpp" + +namespace llmr { + +class PointShader : public Shader { +public: + PointShader(); + + void bind(char *offset); + + void setColor(const std::array& color); + void setPointTopLeft(const std::array& point_tl); + void setPointBottomRight(const std::array& point_br); + void setSize(float size); + +private: + int32_t a_pos = -1; + + std::array color = {}; + int32_t u_color = -1; + + std::array point_tl = {}; + int32_t u_point_tl = -1; + + std::array point_br = {}; + int32_t u_point_br = -1; + + float size = 0; + int32_t u_size = -1; +}; + +} + +#endif diff --git a/include/llmr/shader/shaders.hpp b/include/llmr/shader/shaders.hpp index c0f02337a..6312cc694 100644 --- a/include/llmr/shader/shaders.hpp +++ b/include/llmr/shader/shaders.hpp @@ -16,6 +16,7 @@ enum { OUTLINE_SHADER, PATTERN_SHADER, PLAIN_SHADER, + POINT_SHADER, SHADER_COUNT }; diff --git a/include/llmr/style/class_description.hpp b/include/llmr/style/class_description.hpp index ce5b172b2..eab7b46a9 100644 --- a/include/llmr/style/class_description.hpp +++ b/include/llmr/style/class_description.hpp @@ -12,6 +12,7 @@ class ClassDescription { public: std::map fill; std::map line; + std::map point; }; diff --git a/include/llmr/style/properties.hpp b/include/llmr/style/properties.hpp index 4d4ce6895..79b906cd5 100644 --- a/include/llmr/style/properties.hpp +++ b/include/llmr/style/properties.hpp @@ -60,8 +60,22 @@ struct FunctionProperty { inline T operator()(float z) const { return function(z, values); } }; +struct PointClass { + FunctionProperty hidden; + FunctionProperty size; + Color color = {{ 0, 0, 0, 1 }}; + FunctionProperty opacity = 1; + std::string image; +}; + +struct PointProperties { + bool hidden = false; + float size = 0; + Color color = {{ 0, 0, 0, 1 }}; + float opacity = 1.0; + std::string image; +}; -// LineClass is the information we parse from the stylesheet struct LineClass { FunctionProperty hidden; FunctionProperty width; @@ -70,7 +84,6 @@ struct LineClass { FunctionProperty opacity = 1; }; -// LineProperties is the one we resolve this to. struct LineProperties { bool hidden = false; float width = 0; @@ -79,9 +92,6 @@ struct LineProperties { float opacity = 1.0; }; - - - struct FillClass { FunctionProperty hidden; Winding winding = Winding::NonZero; diff --git a/include/llmr/style/sprite.hpp b/include/llmr/style/sprite.hpp index 0fcd15c05..b8b7b7a0b 100644 --- a/include/llmr/style/sprite.hpp +++ b/include/llmr/style/sprite.hpp @@ -34,7 +34,7 @@ public: class Sprite : public std::enable_shared_from_this { public: - void load(const std::string& base_url); + void load(const std::string& base_url, float pixelRatio = 1); void bind(bool linear = false); ImagePosition getPosition(const std::string& name, bool repeating = false); diff --git a/include/llmr/style/style.hpp b/include/llmr/style/style.hpp index 04b7e2216..d1212f9fe 100644 --- a/include/llmr/style/style.hpp +++ b/include/llmr/style/style.hpp @@ -36,6 +36,7 @@ private: static std::pair parseClass(pbf data); static std::pair parseFillClass(pbf data); static std::pair parseLineClass(pbf data); + static std::pair parsePointClass(pbf data); template static FunctionProperty parseProperty(pbf data); static Color parseColor(pbf& data); @@ -53,6 +54,7 @@ public: struct { std::map fills; std::map lines; + std::map points; } computed; }; diff --git a/ios/MBXViewController.mm b/ios/MBXViewController.mm index c5d6effa1..a687350af 100644 --- a/ios/MBXViewController.mm +++ b/ios/MBXViewController.mm @@ -49,7 +49,7 @@ class MBXMapView { settings.load(); - map.setup(); + map.setup([[UIScreen mainScreen] scale]); CGRect frame = [[UIScreen mainScreen] bounds]; map.resize(frame.size.width, frame.size.height, frame.size.width, frame.size.height); diff --git a/resources/style.pbf b/resources/style.pbf index 1b991386c7f4713760e9be6c3c5b330daf9acda1..46e117e52dcff7d78ee2fbec60fb4842abc611c5 100644 GIT binary patch delta 56 zcmbQmafoBX9ww$1=FR( HBfkIu{YVku delta 15 XcmX@aF^glv9ww$cOq=&H#V`T@Fkc0W diff --git a/src/geometry/point_buffer.cpp b/src/geometry/point_buffer.cpp new file mode 100644 index 000000000..00137eae3 --- /dev/null +++ b/src/geometry/point_buffer.cpp @@ -0,0 +1,12 @@ +#include +#include + +#include + +using namespace llmr; + +void PointVertexBuffer::add(vertex_type x, vertex_type y) { + vertex_type *vertices = static_cast(addElement()); + vertices[0] = x; + vertices[1] = y; +} diff --git a/src/map/map.cpp b/src/map/map.cpp index e837ecffb..35dcb471f 100644 --- a/src/map/map.cpp +++ b/src/map/map.cpp @@ -15,19 +15,20 @@ Map::Map(Settings& settings) painter(transform, settings, style), min_zoom(0), max_zoom(14) { - - // TODO: Extract that information from the stylesheet instead of hard coding - style.sprite = std::make_shared(); - style.sprite->load(kSpriteURL); } Map::~Map() { settings.sync(); } -void Map::setup() { +void Map::setup(float pixelRatio) { painter.setup(); + pixel_ratio = pixelRatio; + + style.sprite = std::make_shared(); + style.sprite->load(kSpriteURL, pixel_ratio); + style.load(resources::style, resources::style_size); // style.loadJSON((const char *)resources::style, resources::style_size); } @@ -54,7 +55,7 @@ void Map::resize(uint32_t width, uint32_t height, uint32_t fb_width, uint32_t fb transform.height = height; transform.fb_width = fb_width; transform.fb_height = fb_height; - transform.pixelRatio = (double)fb_width / (double)width; + transform.pixelRatio = pixel_ratio; update(); } diff --git a/src/map/tile.cpp b/src/map/tile.cpp index 902c2c03b..0d7258b24 100644 --- a/src/map/tile.cpp +++ b/src/map/tile.cpp @@ -4,9 +4,11 @@ #include #include #include +#include #include #include #include +#include #include #include #include @@ -45,6 +47,7 @@ Tile::Tile(ID id, const Style& style) state(initial), fillVertexBuffer(std::make_shared()), lineVertexBuffer(std::make_shared()), + pointVertexBuffer(std::make_shared()), triangleElementsBuffer(std::make_shared()), lineElementsBuffer(std::make_shared()), pointElementsBuffer(std::make_shared()), @@ -159,6 +162,8 @@ std::shared_ptr Tile::createBucket(const VectorTile& tile, const BucketD return createFillBucket(layer, bucket_desc); } else if (bucket_desc.type == BucketType::Line) { return createLineBucket(layer, bucket_desc); + } else if (bucket_desc.type == BucketType::Point) { + return createPointBucket(layer, bucket_desc); } else { // TODO: create other bucket types. } @@ -200,3 +205,19 @@ std::shared_ptr Tile::createLineBucket(const VectorTileLayer& layer, con return bucket; } + +std::shared_ptr Tile::createPointBucket(const VectorTileLayer& layer, const BucketDescription& bucket_desc) { + std::shared_ptr bucket = std::make_shared(pointVertexBuffer, pointElementsBuffer, bucket_desc); + + FilteredVectorTileLayer filtered_layer(layer, bucket_desc); + for (pbf feature : filtered_layer) { + while (feature.next(4)) { // geometry + pbf geometry_pbf = feature.message(); + if (geometry_pbf) { + bucket->addGeometry(geometry_pbf); + } + } + } + + return bucket; +} diff --git a/src/renderer/painter.cpp b/src/renderer/painter.cpp index 73f96a55f..a53496cb3 100644 --- a/src/renderer/painter.cpp +++ b/src/renderer/painter.cpp @@ -7,6 +7,7 @@ #include #include +#include #include #include @@ -29,6 +30,7 @@ Painter::Painter(Transform& transform, Settings& settings, Style& style) void Painter::setup() { setupShaders(); + assert(pointShader); assert(plainShader); assert(outlineShader); assert(lineShader); @@ -52,6 +54,7 @@ void Painter::setupShaders() { lineShader = std::make_unique(); linejoinShader = std::make_unique(); patternShader = std::make_unique(); + pointShader = std::make_unique(); } void Painter::useProgram(uint32_t program) { @@ -377,6 +380,36 @@ void Painter::renderLine(LineBucket& bucket, const std::string& layer_name, cons } } +void Painter::renderPoint(PointBucket& bucket, const std::string& layer_name, const Tile::ID& id) { + const PointProperties& properties = style.computed.points[layer_name]; + + // Abort early. + if (!bucket.hasPoints()) return; + if (properties.hidden) return; + + Color color = properties.color; + color[0] *= properties.opacity; + color[1] *= properties.opacity; + color[2] *= properties.opacity; + color[3] *= properties.opacity; + + std::string sized_image = properties.image; + sized_image.append("-"); + sized_image.append(std::to_string(static_cast(std::round(properties.size)))); + + ImagePosition imagePos = style.sprite->getPosition(sized_image, false); + + useProgram(pointShader->program); + pointShader->setMatrix(matrix); + pointShader->setColor(color); + pointShader->setSize(properties.size * transform.pixelRatio); + pointShader->setPointTopLeft({{ imagePos.tl.x, imagePos.tl.y }}); + pointShader->setPointBottomRight({{ imagePos.br.x, imagePos.br.y }}); + style.sprite->bind(true); + + bucket.drawPoints(*pointShader); +} + void Painter::renderDebug(const Tile::Ptr& tile) { // Blend to the front, not the back. glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); diff --git a/src/renderer/point_bucket.cpp b/src/renderer/point_bucket.cpp new file mode 100644 index 000000000..fcdcf96e9 --- /dev/null +++ b/src/renderer/point_bucket.cpp @@ -0,0 +1,75 @@ +#include +#include +#include +#include + +#include +#include +#include + +#include + +#include + +struct geometry_too_long_exception : std::exception {}; + +using namespace llmr; + +PointBucket::PointBucket(const std::shared_ptr& vertexBuffer, + const std::shared_ptr& elementsBuffer, + const BucketDescription& bucket_desc) + : geometry(bucket_desc.geometry), + vertexBuffer(vertexBuffer), + elementsBuffer(elementsBuffer), + vertex_start(vertexBuffer->index()), + elements_start(elementsBuffer->index()) +{ +} + +void PointBucket::addGeometry(pbf& geom) { + Coordinate point; + + Geometry geometry(geom); + int32_t x, y; + geometry.next(x, y); + point.x = x; + point.y = y; + addGeometry(point); +} + +typedef uint16_t PointElement; + +void PointBucket::addGeometry(Coordinate& point) { + vertexBuffer->add(point.x, point.y); + + { + if (!groups.size() || (groups.back().vertex_length + 1 > 65535)) { + groups.emplace_back(); + } + + group_type& group = groups.back(); + elementsBuffer->add(group.vertex_length + point); + + group.vertex_length++; + group.elements_length++; + } +} + +void PointBucket::render(Painter& painter, const std::string& layer_name, const Tile::ID& id) { + painter.renderPoint(*this, layer_name, id); +} + +bool PointBucket::hasPoints() const { + return !groups.empty(); +} + +void PointBucket::drawPoints(PointShader& shader) { + char *vertex_index = BUFFER_OFFSET(vertex_start * vertexBuffer->itemSize); + char *elements_index = BUFFER_OFFSET(elements_start * elementsBuffer->itemSize); + for (group_type& group : groups) { + group.array.bind(shader, *vertexBuffer, *elementsBuffer, vertex_index); + glDrawElements(GL_POINTS, group.elements_length, GL_UNSIGNED_SHORT, elements_index); + vertex_index += group.vertex_length * vertexBuffer->itemSize; + elements_index += group.elements_length * elementsBuffer->itemSize; + } +} diff --git a/src/renderer/shader-point.cpp b/src/renderer/shader-point.cpp new file mode 100644 index 000000000..250ac7d2f --- /dev/null +++ b/src/renderer/shader-point.cpp @@ -0,0 +1,66 @@ +#include +#include +#include + +#include + +using namespace llmr; + +PointShader::PointShader() + : Shader( + shaders[POINT_SHADER].vertex, + shaders[POINT_SHADER].fragment + ) { + if (!valid) { + fprintf(stderr, "invalid point shader\n"); + return; + } + + a_pos = glGetAttribLocation(program, "a_pos"); + + u_matrix = glGetUniformLocation(program, "u_matrix"); + u_color = glGetUniformLocation(program, "u_color"); + u_size = glGetUniformLocation(program, "u_size"); + u_point_tl = glGetUniformLocation(program, "u_tl"); + u_point_br = glGetUniformLocation(program, "u_br"); + + // fprintf(stderr, "PointShader:\n"); + // fprintf(stderr, " - u_matrix: %d\n", u_matrix); + // fprintf(stderr, " - u_color: %d\n", u_color); + // fprintf(stderr, " - u_size: %d\n", u_size); + // fprintf(stderr, " - u_point_tl: %d\n", u_point_tl); + // fprintf(stderr, " - u_point_br: %d\n", u_point_br); +} + +void PointShader::bind(char *offset) { + glEnableVertexAttribArray(a_pos); + glVertexAttribPointer(a_pos, 2, GL_SHORT, false, 8, offset); +} + +void PointShader::setColor(const std::array& new_color) { + if (color != new_color) { + glUniform4fv(u_color, 1, new_color.data()); + color = new_color; + } +} + +void PointShader::setSize(float new_size) { + if (size != new_size) { + glUniform1f(u_size, new_size); + size = new_size; + } +} + +void PointShader::setPointTopLeft(const std::array& new_point_tl) { + if (point_tl != new_point_tl) { + glUniform2fv(u_point_tl, 1, new_point_tl.data()); + point_tl = new_point_tl; + } +} + +void PointShader::setPointBottomRight(const std::array& new_point_br) { + if (point_br != new_point_br) { + glUniform2fv(u_point_br, 1, new_point_br.data()); + point_br = new_point_br; + } +} diff --git a/src/shader/point.fragment.glsl b/src/shader/point.fragment.glsl new file mode 100644 index 000000000..dcd45cc69 --- /dev/null +++ b/src/shader/point.fragment.glsl @@ -0,0 +1,25 @@ +#define root2 1.42 + +uniform sampler2D u_image; +uniform vec2 u_tl; +uniform vec2 u_br; +uniform vec4 u_color; + +uniform vec2 pos; +uniform float inbounds; +uniform vec4 color; + +void main() { + vec2 pos = (gl_PointCoord * 2.0 - 1.0) * root2 / 2.0 + 0.5; + + float inbounds = step(0.0, pos.x) * step(0.0, pos.y) * + (1.0 - step(1.0, pos.x)) * (1.0 - step(1.0, pos.y)); + + vec4 color = texture2D(u_image, mix(u_tl, u_br, pos)) * inbounds; + + if (u_color.a > 0.0) { + gl_FragColor = u_color * color.a; + } else { + gl_FragColor = vec4(color.rgb * color.a, color.a); + } +} diff --git a/src/shader/point.vertex.glsl b/src/shader/point.vertex.glsl new file mode 100644 index 000000000..e506745e0 --- /dev/null +++ b/src/shader/point.vertex.glsl @@ -0,0 +1,10 @@ +attribute vec2 a_pos; + +uniform mat4 u_matrix; +uniform float u_size; + +void main() { + float z = step(32767.0, a_pos.x) * 2.0; + gl_Position = u_matrix * vec4(a_pos, z, 1); + gl_PointSize = u_size; +} diff --git a/src/shader/shaders.cpp b/src/shader/shaders.cpp index 203f143ca..d56d88dc1 100644 --- a/src/shader/shaders.cpp +++ b/src/shader/shaders.cpp @@ -23,5 +23,9 @@ const shader_source llmr::shaders[SHADER_COUNT] = { { "attribute vec2 a_pos;\n\nuniform mat4 u_matrix;\n\nvoid main() {\n gl_Position = u_matrix * vec4(a_pos, 0, 1);\n}\n", "uniform vec4 u_color;\n\nvoid main() {\n gl_FragColor = u_color;\n}\n", + }, + { + "attribute vec2 a_pos;\n\nuniform mat4 u_matrix;\nuniform float u_size;\n\nvoid main() {\n float z = step(32767.0, a_pos.x) * 2.0;\n gl_Position = u_matrix * vec4(a_pos, z, 1);\n gl_PointSize = u_size;\n}\n", + "#define root2 1.42\n\nuniform sampler2D u_image;\nuniform vec2 u_tl;\nuniform vec2 u_br;\nuniform vec4 u_color;\n\nuniform vec2 pos;\nuniform float inbounds;\nuniform vec4 color;\n\nvoid main() {\n vec2 pos = (gl_PointCoord * 2.0 - 1.0) * root2 / 2.0 + 0.5;\n\n float inbounds = step(0.0, pos.x) * step(0.0, pos.y) *\n (1.0 - step(1.0, pos.x)) * (1.0 - step(1.0, pos.y));\n\n vec4 color = texture2D(u_image, mix(u_tl, u_br, pos)) * inbounds;\n\n if (u_color.a > 0.0) {\n gl_FragColor = u_color * color.a;\n } else {\n gl_FragColor = vec4(color.rgb * color.a, color.a);\n }\n}\n", } }; diff --git a/src/style/resources.cpp b/src/style/resources.cpp index 15b6aa040..bf0eb207e 100644 --- a/src/style/resources.cpp +++ b/src/style/resources.cpp @@ -47,7 +47,7 @@ const unsigned char resources::style[] = { 12, 114, 111, 97, 100, 95, 114, 101, 103, 117, 108, 97, 114, 18, 24, 10, 10, 114, 111, 97, 100, 95, 108, 97, 114, 103, 101, 18, 10, 114, 111, 97, 100, 95, 108, 97, 114, 103, 101, 18, 18, 10, 7, 97, 108, 99, 111, 104, - 111, 108, 18, 7, 97, 108, 99, 111, 104, 111, 108, 26, 220, 2, 10, 7, + 111, 108, 18, 7, 97, 108, 99, 111, 104, 111, 108, 26, 132, 3, 10, 7, 100, 101, 102, 97, 117, 108, 116, 18, 27, 10, 4, 112, 97, 114, 107, 34, 8, 8, 2, 18, 4, 0, 0, 128, 63, 45, 255, 159, 223, 200, 66, 4, 112, 97, 114, 107, 18, 31, 10, 4, 119, 111, 111, 100, 34, 8, 8, 2, @@ -69,6 +69,9 @@ const unsigned char resources::style[] = { 255, 102, 102, 102, 34, 52, 8, 3, 18, 48, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 48, 65, 0, 0, 0, 63, 0, 0, 80, 65, 0, 0, 128, 63, 0, 0, 128, 65, 0, 0, 128, 64, 0, 0, 160, 65, 0, 0, - 128, 66, 0, 0, 240, 65, 0, 0, 128, 66 + 128, 66, 0, 0, 240, 65, 0, 0, 128, 66, 34, 38, 10, 7, 97, 108, + 99, 111, 104, 111, 108, 29, 255, 153, 153, 153, 34, 8, 8, 2, 18, 4, + 0, 0, 192, 65, 66, 12, 97, 108, 99, 111, 104, 111, 108, 45, 115, 104, + 111, 112 }; const unsigned long resources::style_size = sizeof(resources::style); diff --git a/src/style/sprite.cpp b/src/style/sprite.cpp index ceef26739..e07cb89fd 100644 --- a/src/style/sprite.cpp +++ b/src/style/sprite.cpp @@ -29,7 +29,7 @@ Sprite::operator bool() const { return loaded; } -void Sprite::load(const std::string& base_url) { +void Sprite::load(const std::string& base_url, float pixelRatio) { std::shared_ptr sprite = shared_from_this(); auto complete = [sprite]() { @@ -41,7 +41,9 @@ void Sprite::load(const std::string& base_url) { } }; - platform::request_http(base_url + ".json", [sprite](const platform::Response & res) { + std::string suffix = (pixelRatio > 1 ? "@2x" : ""); + + platform::request_http(base_url + suffix + ".json", [sprite](const platform::Response & res) { if (res.code == 200) { sprite->parseJSON(res.body); } else { @@ -49,7 +51,7 @@ void Sprite::load(const std::string& base_url) { } }, complete); - platform::request_http(base_url + ".png", [sprite](const platform::Response & res) { + platform::request_http(base_url + suffix + ".png", [sprite](const platform::Response & res) { if (res.code == 200) { sprite->loadImage(res.body); } else { diff --git a/src/style/style.cpp b/src/style/style.cpp index 0e8e9f3b6..2aac0c384 100644 --- a/src/style/style.cpp +++ b/src/style/style.cpp @@ -12,6 +12,7 @@ Style::Style() { void Style::reset() { computed.fills.clear(); computed.lines.clear(); + computed.points.clear(); } void Style::load(const uint8_t *const data, uint32_t bytes) { @@ -89,10 +90,12 @@ std::pair Style::parseClass(pbf data) { while (data.next()) { if (data.tag == 1) { // name name = data.string(); - } else if (data.tag == 2) { // fill_style + } else if (data.tag == 2) { // fill style klass.fill.insert(parseFillClass(data.message())); - } else if (data.tag == 3) { // stroke_style + } else if (data.tag == 3) { // line style klass.line.insert(parseLineClass(data.message())); + } else if (data.tag == 4) { // point style + klass.point.insert(parsePointClass(data.message())); } else { data.skip(); } @@ -159,6 +162,30 @@ std::pair Style::parseLineClass(pbf data) { return { name, stroke }; } +std::pair Style::parsePointClass(pbf data) { + PointClass point; + std::string name; + + while (data.next()) { + if (data.tag == 1) { // name + name = data.string(); + } else if (data.tag == 2) { // hidden + point.hidden = parseProperty(data.message()); + } else if (data.tag == 3) { // color + point.color = parseColor(data); + } else if (data.tag == 4) { // size + point.size = parseProperty(data.message()); + } else if (data.tag == 6) { // opacity + point.opacity = parseProperty(data.message()); + } else if (data.tag == 8) { // image + point.image = data.string(); + } else { + data.skip(); + } + } + + return { name, point }; +} Color Style::parseColor(pbf& data) { uint32_t rgba = data.fixed(); @@ -240,6 +267,21 @@ void Style::cascade(float z) { stroke.color = layer.color; stroke.opacity = layer.opacity(z); } + + // Cascade point classes + for (const auto& point_pair : sheetClass.point) { + const std::string& layer_name = point_pair.first; + const llmr::PointClass& layer = point_pair.second; + + // TODO: This should be restricted to point styles that have actual + // values so as to not override with default values. + llmr::PointProperties& point = computed.points[layer_name]; + point.hidden = layer.hidden(z); + point.color = layer.color; + point.size = layer.size(z); + point.opacity = layer.opacity(z); + point.image = layer.image; + } } } From 9d89bc090989f972ee5487c58df859d5ab4c348d Mon Sep 17 00:00:00 2001 From: Ansis Brammanis Date: Mon, 17 Feb 2014 06:13:18 -0500 Subject: [PATCH 02/37] first attempt at linux wrapper --- Makefile | 5 + linux/llmr-app.gyp | 32 ++++++ linux/main.cpp | 263 +++++++++++++++++++++++++++++++++++++++++++ linux/settings.cpp | 52 +++++++++ linux/settings.hpp | 23 ++++ src/style/sprite.cpp | 1 + 6 files changed, 376 insertions(+) create mode 100644 linux/llmr-app.gyp create mode 100644 linux/main.cpp create mode 100644 linux/settings.cpp create mode 100644 linux/settings.hpp diff --git a/Makefile b/Makefile index 1d16f0c94..70ce2a4d4 100644 --- a/Makefile +++ b/Makefile @@ -15,6 +15,11 @@ app: config.gypi src macosx/llmr-app.gyp make -C build/macosx-make V=$(V) open build/macosx-make/out/Release/llmr.app +linux: config.gypi src linux/llmr-app.gyp + deps/run_gyp linux/llmr-app.gyp -Goutput_dir=./out/ --depth=. --generator-output=./build/linux-make -f make + make -C build/linux-make V=$(V) + ./build/linux-make/out/Release/llmr.app + # build just xcode project for libllmr xcode: config.gypi llmr.gyp deps/run_gyp llmr.gyp -Goutput_dir=./out/ --depth=. --generator-output=./ -f xcode diff --git a/linux/llmr-app.gyp b/linux/llmr-app.gyp new file mode 100644 index 000000000..40b8c76ec --- /dev/null +++ b/linux/llmr-app.gyp @@ -0,0 +1,32 @@ +{ + 'includes': [ + '../common.gypi', + '../config.gypi' + ], + 'targets': [ + { + "target_name": "linuxapp", + "product_name": "llmr", + "type": "executable", + "sources": [ + "./main.cpp", + "./settings.cpp", + "./settings.hpp" + ], + 'product_extension': 'app', + 'link_settings': { + 'libraries': [ + '<@(glfw3_libraries)', + '-lcurl' + ], + }, + 'cflags': [ + '<@(png_cflags)', + '<@(glfw3_cflags)' + ], + "dependencies": [ + "../llmr.gyp:llmr-osx" + ] + } + ] +} diff --git a/linux/main.cpp b/linux/main.cpp new file mode 100644 index 000000000..c51d27f82 --- /dev/null +++ b/linux/main.cpp @@ -0,0 +1,263 @@ +#include +#include +#include +#include +#include "settings.hpp" + +#include + +class MapView { +public: + MapView() : + dirty(true), + tracking(false), + rotating(false), + last_click(-1), + settings(), + map(settings) { + } + + void init() { + if (!glfwInit()) { + fprintf(stderr, "Failed to initialize glfw\n"); + exit(1); + } + + glfwWindowHint(GLFW_STENCIL_BITS, 8); + glfwWindowHint(GLFW_DEPTH_BITS, 16); + + window = glfwCreateWindow(1024, 768, "llmr", NULL, NULL); + if (!window) { + glfwTerminate(); + fprintf(stderr, "Failed to initialize window\n"); + exit(1); + } + + glfwSetWindowUserPointer(window, this); + glfwMakeContextCurrent(window); + + settings.load(); + map.setup(); + + resize(window, 0, 0); + + glfwSwapInterval(1); + + map.loadSettings(); + + glfwSetCursorPosCallback(window, mousemove); + glfwSetMouseButtonCallback(window, mouseclick); + glfwSetWindowSizeCallback(window, resize); + glfwSetFramebufferSizeCallback(window, resize); + glfwSetScrollCallback(window, scroll); + glfwSetCharCallback(window, character); + glfwSetKeyCallback(window, key); + + } + + static void character(GLFWwindow *window, unsigned int codepoint) { + + } + + + static void key(GLFWwindow *window, int key, int scancode, int action, int mods) { + MapView *mapView = (MapView *)glfwGetWindowUserPointer(window); + + if (action == GLFW_RELEASE) { + switch (key) { + case GLFW_KEY_ESCAPE: + glfwSetWindowShouldClose(window, true); + break; + case GLFW_KEY_TAB: + mapView->map.toggleDebug(); + break; + case GLFW_KEY_R: + if (!mods) mapView->map.resetPosition(); + break; + case GLFW_KEY_N: + if (!mods) mapView->map.resetNorth(); + break; + } + } + } + + + static void scroll(GLFWwindow *window, double xoffset, double yoffset) { + MapView *mapView = (MapView *)glfwGetWindowUserPointer(window); + double delta = yoffset * 40; + + bool is_wheel = delta != 0 && fmod(delta, 4.000244140625) == 0; + + double absdelta = delta < 0 ? -delta : delta; + double scale = 2.0 / (1.0 + exp(-absdelta / 100.0)); + + // Make the scroll wheel a bit slower. + if (!is_wheel) { + scale = (scale - 1.0) / 2.0 + 1.0; + } + + // Zooming out. + if (delta < 0 && scale != 0) { + scale = 1.0 / scale; + } + + mapView->map.scaleBy(scale, mapView->last_x, mapView->last_y); + } + + static void resize(GLFWwindow *window, int, int) { + MapView *mapView = (MapView *)glfwGetWindowUserPointer(window); + + int width, height; + glfwGetWindowSize(window, &width, &height); + int fb_width, fb_height; + glfwGetFramebufferSize(window, &fb_width, &fb_height); + + mapView->map.resize(width, height, fb_width, fb_height); + } + + static void mouseclick(GLFWwindow *window, int button, int action, int modifiers) { + MapView *mapView = (MapView *)glfwGetWindowUserPointer(window); + + if (button == GLFW_MOUSE_BUTTON_RIGHT || (button == GLFW_MOUSE_BUTTON_LEFT && modifiers & GLFW_MOD_CONTROL)) { + mapView->rotating = action == GLFW_PRESS; + if (mapView->rotating) { + mapView->start_x = mapView->last_x; + mapView->start_y = mapView->last_y; + } + } else if (button == GLFW_MOUSE_BUTTON_LEFT) { + mapView->tracking = action == GLFW_PRESS; + + if (action == GLFW_RELEASE) { + double now = glfwGetTime(); + if (now - mapView->last_click < 0.4) { + mapView->map.scaleBy(2.0, mapView->last_x, mapView->last_y); + } + mapView->last_click = now; + } + } + } + + static void mousemove(GLFWwindow *window, double x, double y) { + MapView *mapView = (MapView *)glfwGetWindowUserPointer(window); + if (mapView->tracking) { + mapView->map.moveBy(x - mapView->last_x, y - mapView->last_y); + } else if (mapView->rotating) { + mapView->map.rotateBy(mapView->start_x, mapView->start_y, mapView->last_x, mapView->last_y, x, y); + } + mapView->last_x = x; + mapView->last_y = y; + } + + int run() { + while (!glfwWindowShouldClose(window)) { + if (dirty) { + try { + dirty = render(); + } catch (std::exception& ex) { + fprintf(stderr, "exception: %s\n", ex.what()); + } + glfwSwapBuffers(window); + fps(); + } + + if (dirty) { + glfwPollEvents(); + } else { + glfwWaitEvents(); + } + } + + return 0; + } + + bool render() { + return map.render(); + } + + void fps() { + static int frames = 0; + static double time_elapsed = 0; + + frames++; + double current_time = glfwGetTime(); + + if (current_time - time_elapsed >= 1) { + fprintf(stderr, "FPS: %4.2f\n", frames / (current_time - time_elapsed)); + time_elapsed = current_time; + frames = 0; + } + } + + ~MapView() { + glfwTerminate(); + } + +public: + bool dirty; + double last_x, last_y; + bool tracking; + + double start_x, start_y; + bool rotating; + + double last_click; + + GLFWwindow *window; + llmr::Settings_MacOSX settings; + llmr::Map map; +}; + +MapView *mapView; + +namespace llmr { +namespace platform { + +void restart(void *) { + mapView->dirty = true; +} + + + +static size_t WriteCallback(void *contents, size_t size, size_t nmemb, void *userp) { + ((std::string*)userp)->append((char*)contents, size *nmemb); + return size * nmemb; +} + +void request_http(std::string url, std::function func, std::function cb) { + + Response res; + + CURL *curl; + CURLcode code; + curl = curl_easy_init(); + + if (curl) { + curl_easy_setopt(curl, CURLOPT_URL, url.c_str()); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback); + curl_easy_setopt(curl, CURLOPT_WRITEDATA, &res.body); + curl_easy_setopt(curl, CURLOPT_ACCEPT_ENCODING, "deflate"); + code = curl_easy_perform(curl); + curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &res.code); + curl_easy_cleanup(curl); + } + + func(res); + cb(); +} + + +double time() { + return glfwGetTime(); +} + +} +} + +int main() { + mapView = new MapView(); + mapView->init(); + int ret = mapView->run(); + mapView->settings.sync(); + delete mapView; + return ret; +} diff --git a/linux/settings.cpp b/linux/settings.cpp new file mode 100644 index 000000000..2aa4b8c8a --- /dev/null +++ b/linux/settings.cpp @@ -0,0 +1,52 @@ +#include "settings.hpp" + +using namespace llmr; + +Settings_MacOSX::Settings_MacOSX() +{ + /* + [[NSUserDefaults standardUserDefaults] registerDefaults:@{ @"longitude" : @(longitude), + @"latitude" : @(latitude), + @"scale" : @(scale), + @"angle" : @(angle), + @"debug" : @(debug) }]; + */ +} + +void Settings_MacOSX::load() +{ + /* + NSDictionary *settings = [[NSUserDefaults standardUserDefaults] dictionaryRepresentation]; + + longitude = [settings[@"longitude"] doubleValue]; + latitude = [settings[@"latitude"] doubleValue]; + scale = [settings[@"scale"] doubleValue]; + angle = [settings[@"angle"] doubleValue]; + debug = [settings[@"debug"] boolValue]; + */ +} + +void Settings_MacOSX::persist() +{ + /* + [[NSUserDefaults standardUserDefaults] setValuesForKeysWithDictionary:@{ @"longitude" : @(longitude), + @"latitude" : @(latitude), + @"scale" : @(scale), + @"angle" : @(angle), + @"debug" : @(debug) }]; + */ +} + +void Settings_MacOSX::sync() +{ + /* + [[NSUserDefaults standardUserDefaults] synchronize]; + */ +} + +void Settings_MacOSX::clear() +{ + /* + [NSUserDefaults resetStandardUserDefaults]; + */ +} diff --git a/linux/settings.hpp b/linux/settings.hpp new file mode 100644 index 000000000..dae645c74 --- /dev/null +++ b/linux/settings.hpp @@ -0,0 +1,23 @@ +#ifndef LLMR_MACOSX_SETTINGS +#define LLMR_MACOSX_SETTINGS + +#include + +namespace llmr { + +class Settings_MacOSX : public Settings { +public: + Settings_MacOSX(); + virtual void load(); + virtual void persist(); + virtual void sync(); + virtual void clear(); + double angle; + double longitude; + double latitude; + double scale; +}; + +} + +#endif diff --git a/src/style/sprite.cpp b/src/style/sprite.cpp index ceef26739..e2707f5b9 100644 --- a/src/style/sprite.cpp +++ b/src/style/sprite.cpp @@ -121,6 +121,7 @@ void warningHandler(png_structp png, png_const_charp error_msg) { } void Sprite::loadImage(const std::string& data) { + return; std::lock_guard lock(mtx); Buffer buffer(data); From 9fb05741d65912611782676c08ff9bf7cc104861 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Konstantin=20Ka=CC=88fer?= Date: Mon, 17 Feb 2014 17:55:47 +0100 Subject: [PATCH 03/37] make sure that mapView is initialized before referencing into it --- Makefile | 2 +- linux/main.cpp | 6 ++++-- src/style/sprite.cpp | 1 - 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/Makefile b/Makefile index 70ce2a4d4..0586f6017 100644 --- a/Makefile +++ b/Makefile @@ -68,4 +68,4 @@ distclean: test: all echo test -.PHONY: test +.PHONY: test linux diff --git a/linux/main.cpp b/linux/main.cpp index c51d27f82..1576a5be7 100644 --- a/linux/main.cpp +++ b/linux/main.cpp @@ -207,13 +207,15 @@ public: llmr::Map map; }; -MapView *mapView; +MapView *mapView = nullptr; namespace llmr { namespace platform { void restart(void *) { - mapView->dirty = true; + if (mapView) { + mapView->dirty = true; + } } diff --git a/src/style/sprite.cpp b/src/style/sprite.cpp index e2707f5b9..ceef26739 100644 --- a/src/style/sprite.cpp +++ b/src/style/sprite.cpp @@ -121,7 +121,6 @@ void warningHandler(png_structp png, png_const_charp error_msg) { } void Sprite::loadImage(const std::string& data) { - return; std::lock_guard lock(mtx); Buffer buffer(data); From c0997961aafe85abff28d3157202111456d9afc5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Konstantin=20Ka=CC=88fer?= Date: Mon, 17 Feb 2014 17:58:34 +0100 Subject: [PATCH 04/37] don't use std::string to hold the image --- include/llmr/style/sprite.hpp | 4 +++- src/style/sprite.cpp | 18 +++++++++++++----- 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/include/llmr/style/sprite.hpp b/include/llmr/style/sprite.hpp index 0fcd15c05..2f2c38cb3 100644 --- a/include/llmr/style/sprite.hpp +++ b/include/llmr/style/sprite.hpp @@ -34,6 +34,8 @@ public: class Sprite : public std::enable_shared_from_this { public: + ~Sprite(); + void load(const std::string& base_url); void bind(bool linear = false); @@ -52,7 +54,7 @@ private: uint32_t texture = 0; std::map pos; uint32_t width = 0, height = 0; - std::string img; + char *img = nullptr; }; } diff --git a/src/style/sprite.cpp b/src/style/sprite.cpp index ceef26739..f99fb0f88 100644 --- a/src/style/sprite.cpp +++ b/src/style/sprite.cpp @@ -23,6 +23,11 @@ ImagePosition::ImagePosition(const vec2& size, vec2 tl, vec2 lock(mtx); @@ -34,7 +39,7 @@ void Sprite::load(const std::string& base_url) { auto complete = [sprite]() { std::lock_guard lock(sprite->mtx); - if (sprite->img.size() && sprite->pos.size()) { + if (sprite->img && sprite->pos.size()) { sprite->loaded = true; platform::restart(NULL); fprintf(stderr, "sprite loaded\n"); @@ -176,8 +181,8 @@ void Sprite::loadImage(const std::string& data) { unsigned int rowbytes = png_get_rowbytes(png, info); assert(width * 4 == rowbytes); - img.resize(width * height * 4); - char *surface = const_cast(img.data()); + img = (char *)malloc(width * height * 4); + char *surface = img; assert(surface); png_bytep row_pointers[height]; @@ -192,7 +197,10 @@ void Sprite::loadImage(const std::string& data) { } catch (std::exception& e) { fprintf(stderr, "loading PNG failed: %s\n", e.what()); png_destroy_read_struct(&png, &info, nullptr); - img.clear(); + if (img) { + free(img); + img = nullptr; + } width = 0; height = 0; } @@ -237,7 +245,7 @@ void Sprite::bind(bool linear) { glBindTexture(GL_TEXTURE_2D, texture); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, img.data()); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, img); } else { glBindTexture(GL_TEXTURE_2D, texture); } From c4313c25aecf8a96d60a09be62e2e2e4aef27eed Mon Sep 17 00:00:00 2001 From: Ansis Brammanis Date: Tue, 18 Feb 2014 06:40:05 -0500 Subject: [PATCH 05/37] async http requests for linux wrapper --- linux/main.cpp | 35 ++++++++++++++++++++++++++++++++--- 1 file changed, 32 insertions(+), 3 deletions(-) diff --git a/linux/main.cpp b/linux/main.cpp index 1576a5be7..1e6c409a0 100644 --- a/linux/main.cpp +++ b/linux/main.cpp @@ -3,9 +3,18 @@ #include #include #include "settings.hpp" +#include +#include +#include #include +std::list> futures; +std::list>::iterator f_it; +std::list> callbacks; +std::list>::iterator c_it; +std::chrono::milliseconds zero (0); + class MapView { public: MapView() : @@ -150,6 +159,22 @@ public: int run() { while (!glfwWindowShouldClose(window)) { + + f_it = futures.begin(); + c_it = callbacks.begin(); + + while (f_it != futures.end()) { + if (f_it->wait_for(zero) == std::future_status::ready) { + std::function cb = *c_it; + futures.erase(f_it++); + callbacks.erase(c_it++); + cb(); + } else { + f_it++; + c_it++; + } + } + if (dirty) { try { dirty = render(); @@ -160,7 +185,7 @@ public: fps(); } - if (dirty) { + if (dirty || futures.size()) { glfwPollEvents(); } else { glfwWaitEvents(); @@ -225,7 +250,7 @@ static size_t WriteCallback(void *contents, size_t size, size_t nmemb, void *use return size * nmemb; } -void request_http(std::string url, std::function func, std::function cb) { +void request_http_async(std::string url, std::function func) { Response res; @@ -244,7 +269,11 @@ void request_http(std::string url, std::function func, std::fun } func(res); - cb(); +} + +void request_http(std::string url, std::function func, std::function cb) { + futures.emplace_back(std::async(std::launch::async, request_http_async, url, func)); + callbacks.push_back(cb); } From baa4981c3b1e7920cb4507592532a8d6863aee5e Mon Sep 17 00:00:00 2001 From: Ansis Brammanis Date: Tue, 18 Feb 2014 08:40:14 -0500 Subject: [PATCH 06/37] persist settings to /tmp/llmr-native.json --- linux/settings.cpp | 61 ++++++++++++++++++++++++---------------------- linux/settings.hpp | 4 --- 2 files changed, 32 insertions(+), 33 deletions(-) diff --git a/linux/settings.cpp b/linux/settings.cpp index 2aa4b8c8a..d058337f6 100644 --- a/linux/settings.cpp +++ b/linux/settings.cpp @@ -1,52 +1,55 @@ #include "settings.hpp" +#include "rapidjson/prettywriter.h" +#include "rapidjson/filestream.h" +#include "rapidjson/document.h" +#include using namespace llmr; Settings_MacOSX::Settings_MacOSX() { - /* - [[NSUserDefaults standardUserDefaults] registerDefaults:@{ @"longitude" : @(longitude), - @"latitude" : @(latitude), - @"scale" : @(scale), - @"angle" : @(angle), - @"debug" : @(debug) }]; - */ } void Settings_MacOSX::load() { - /* - NSDictionary *settings = [[NSUserDefaults standardUserDefaults] dictionaryRepresentation]; - - longitude = [settings[@"longitude"] doubleValue]; - latitude = [settings[@"latitude"] doubleValue]; - scale = [settings[@"scale"] doubleValue]; - angle = [settings[@"angle"] doubleValue]; - debug = [settings[@"debug"] boolValue]; - */ + FILE *settingsFile = fopen("/tmp/llmr-native.json", "r"); + if (settingsFile != NULL) { + rapidjson::FileStream is(settingsFile); + rapidjson::Document document; + document.ParseStream<0>(is); + if (document.IsArray()) { + latitude = document[rapidjson::SizeType(0)].GetDouble(); + latitude = document[1].GetDouble(); + scale = document[2].GetDouble(); + angle = document[3].GetDouble(); + debug = document[4].GetBool(); + } + } } void Settings_MacOSX::persist() { - /* - [[NSUserDefaults standardUserDefaults] setValuesForKeysWithDictionary:@{ @"longitude" : @(longitude), - @"latitude" : @(latitude), - @"scale" : @(scale), - @"angle" : @(angle), - @"debug" : @(debug) }]; - */ } void Settings_MacOSX::sync() { - /* - [[NSUserDefaults standardUserDefaults] synchronize]; - */ + + rapidjson::FileStream s(fopen("/tmp/llmr-native.json", "w")); + rapidjson::PrettyWriter writer(s); + writer.StartArray(); + writer.Double(longitude); + writer.Double(latitude); + writer.Double(scale); + writer.Double(angle); + writer.Bool(debug); + writer.EndArray(); } void Settings_MacOSX::clear() { - /* - [NSUserDefaults resetStandardUserDefaults]; - */ + longitude = 0; + latitude = 0; + scale = 0; + angle = 0; + debug = false; } diff --git a/linux/settings.hpp b/linux/settings.hpp index dae645c74..e507c6bd1 100644 --- a/linux/settings.hpp +++ b/linux/settings.hpp @@ -12,10 +12,6 @@ public: virtual void persist(); virtual void sync(); virtual void clear(); - double angle; - double longitude; - double latitude; - double scale; }; } From 420e534306bdd77d6cc7e4bce6a0ec5a4e16658a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Konstantin=20Ka=CC=88fer?= Date: Wed, 19 Feb 2014 14:43:57 +0100 Subject: [PATCH 07/37] fix stride to avoid bogus points at 0/0 --- src/renderer/shader-point.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/renderer/shader-point.cpp b/src/renderer/shader-point.cpp index 250ac7d2f..cbd1d576b 100644 --- a/src/renderer/shader-point.cpp +++ b/src/renderer/shader-point.cpp @@ -34,7 +34,7 @@ PointShader::PointShader() void PointShader::bind(char *offset) { glEnableVertexAttribArray(a_pos); - glVertexAttribPointer(a_pos, 2, GL_SHORT, false, 8, offset); + glVertexAttribPointer(a_pos, 2, GL_SHORT, false, 0, offset); } void PointShader::setColor(const std::array& new_color) { From 504b60b93e622c982a2103757754614bf67b851e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Konstantin=20Ka=CC=88fer?= Date: Wed, 19 Feb 2014 14:46:50 +0100 Subject: [PATCH 08/37] don't used element arrays --- include/llmr/renderer/point_bucket.hpp | 9 ++--- src/map/tile.cpp | 2 +- src/renderer/point_bucket.cpp | 47 +++++++------------------- 3 files changed, 15 insertions(+), 43 deletions(-) diff --git a/include/llmr/renderer/point_bucket.hpp b/include/llmr/renderer/point_bucket.hpp index 4f9a3d353..9c8de8f88 100644 --- a/include/llmr/renderer/point_bucket.hpp +++ b/include/llmr/renderer/point_bucket.hpp @@ -23,16 +23,13 @@ struct Coordinate; struct pbf; class PointBucket : public Bucket { - typedef ElementGroup group_type; public: PointBucket(const std::shared_ptr& vertexBuffer, - const std::shared_ptr& elementsBuffer, const BucketDescription& bucket_desc); virtual void render(Painter& painter, const std::string& layer_name, const Tile::ID& id); void addGeometry(pbf& data); - void addGeometry(Coordinate& point); bool hasPoints() const; @@ -43,12 +40,10 @@ public: private: std::shared_ptr vertexBuffer; - std::shared_ptr elementsBuffer; + VertexArrayObject array; const uint32_t vertex_start; - const uint32_t elements_start; - - std::vector groups; + uint32_t vertex_end = 0; }; } diff --git a/src/map/tile.cpp b/src/map/tile.cpp index 0d7258b24..938024d47 100644 --- a/src/map/tile.cpp +++ b/src/map/tile.cpp @@ -207,7 +207,7 @@ std::shared_ptr Tile::createLineBucket(const VectorTileLayer& layer, con } std::shared_ptr Tile::createPointBucket(const VectorTileLayer& layer, const BucketDescription& bucket_desc) { - std::shared_ptr bucket = std::make_shared(pointVertexBuffer, pointElementsBuffer, bucket_desc); + std::shared_ptr bucket = std::make_shared(pointVertexBuffer, bucket_desc); FilteredVectorTileLayer filtered_layer(layer, bucket_desc); for (pbf feature : filtered_layer) { diff --git a/src/renderer/point_bucket.cpp b/src/renderer/point_bucket.cpp index fcdcf96e9..1f786a0cb 100644 --- a/src/renderer/point_bucket.cpp +++ b/src/renderer/point_bucket.cpp @@ -16,43 +16,25 @@ struct geometry_too_long_exception : std::exception {}; using namespace llmr; PointBucket::PointBucket(const std::shared_ptr& vertexBuffer, - const std::shared_ptr& elementsBuffer, const BucketDescription& bucket_desc) : geometry(bucket_desc.geometry), vertexBuffer(vertexBuffer), - elementsBuffer(elementsBuffer), - vertex_start(vertexBuffer->index()), - elements_start(elementsBuffer->index()) -{ + vertex_start(vertexBuffer->index()) { } void PointBucket::addGeometry(pbf& geom) { - Coordinate point; - + Geometry::command cmd; Geometry geometry(geom); int32_t x, y; - geometry.next(x, y); - point.x = x; - point.y = y; - addGeometry(point); -} - -typedef uint16_t PointElement; - -void PointBucket::addGeometry(Coordinate& point) { - vertexBuffer->add(point.x, point.y); - - { - if (!groups.size() || (groups.back().vertex_length + 1 > 65535)) { - groups.emplace_back(); + while ((cmd = geometry.next(x, y)) != Geometry::end) { + if (cmd == Geometry::move_to) { + vertexBuffer->add(x, y); + } else { + fprintf(stderr, "other command than move_to in point geometry\n"); } - - group_type& group = groups.back(); - elementsBuffer->add(group.vertex_length + point); - - group.vertex_length++; - group.elements_length++; } + + vertex_end = vertexBuffer->index(); } void PointBucket::render(Painter& painter, const std::string& layer_name, const Tile::ID& id) { @@ -60,16 +42,11 @@ void PointBucket::render(Painter& painter, const std::string& layer_name, const } bool PointBucket::hasPoints() const { - return !groups.empty(); + return vertex_end > 0; } void PointBucket::drawPoints(PointShader& shader) { char *vertex_index = BUFFER_OFFSET(vertex_start * vertexBuffer->itemSize); - char *elements_index = BUFFER_OFFSET(elements_start * elementsBuffer->itemSize); - for (group_type& group : groups) { - group.array.bind(shader, *vertexBuffer, *elementsBuffer, vertex_index); - glDrawElements(GL_POINTS, group.elements_length, GL_UNSIGNED_SHORT, elements_index); - vertex_index += group.vertex_length * vertexBuffer->itemSize; - elements_index += group.elements_length * elementsBuffer->itemSize; - } + array.bind(shader, *vertexBuffer, vertex_index); + glDrawArrays(GL_POINTS, 0, vertex_end - vertex_start); } From dcb6c2b7877e8a1c723c85947e86ee37c4c6baa5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Konstantin=20Ka=CC=88fer?= Date: Wed, 19 Feb 2014 14:47:26 +0100 Subject: [PATCH 09/37] calculate the proper pixelRatio --- macosx/main.mm | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/macosx/main.mm b/macosx/main.mm index c9d3045c3..ff8e91e33 100644 --- a/macosx/main.mm +++ b/macosx/main.mm @@ -39,8 +39,14 @@ public: glfwSetWindowUserPointer(window, this); glfwMakeContextCurrent(window); + + int width, height; + glfwGetWindowSize(window, &width, &height); + int fb_width, fb_height; + glfwGetFramebufferSize(window, &fb_width, &fb_height); + settings.load(); - map.setup(); + map.setup((double)fb_width / width); resize(window, 0, 0); From 8880379b310119599b043b0f4eb78465837c90b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Konstantin=20Ka=CC=88fer?= Date: Wed, 19 Feb 2014 14:47:58 +0100 Subject: [PATCH 10/37] set the point size --- src/renderer/painter.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/renderer/painter.cpp b/src/renderer/painter.cpp index a53496cb3..28847b83e 100644 --- a/src/renderer/painter.cpp +++ b/src/renderer/painter.cpp @@ -402,7 +402,12 @@ void Painter::renderPoint(PointBucket& bucket, const std::string& layer_name, co useProgram(pointShader->program); pointShader->setMatrix(matrix); pointShader->setColor(color); - pointShader->setSize(properties.size * transform.pixelRatio); + const float pointSize = ceil(properties.size); + #if defined(GL_ES_VERSION_2_0) + pointShader->setSize(pointSize); + #else + glPointSize(pointSize); + #endif pointShader->setPointTopLeft({{ imagePos.tl.x, imagePos.tl.y }}); pointShader->setPointBottomRight({{ imagePos.br.x, imagePos.br.y }}); style.sprite->bind(true); From 06e23543cb60834fb7342c9bcbaf32b548c29d75 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Konstantin=20Ka=CC=88fer?= Date: Wed, 19 Feb 2014 14:48:34 +0100 Subject: [PATCH 11/37] don't use degenerate vertices --- src/shader/point.vertex.glsl | 3 +-- src/shader/shaders.cpp | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/shader/point.vertex.glsl b/src/shader/point.vertex.glsl index e506745e0..4ccc52663 100644 --- a/src/shader/point.vertex.glsl +++ b/src/shader/point.vertex.glsl @@ -4,7 +4,6 @@ uniform mat4 u_matrix; uniform float u_size; void main() { - float z = step(32767.0, a_pos.x) * 2.0; - gl_Position = u_matrix * vec4(a_pos, z, 1); + gl_Position = u_matrix * vec4(a_pos, 0, 1); gl_PointSize = u_size; } diff --git a/src/shader/shaders.cpp b/src/shader/shaders.cpp index d56d88dc1..e62527813 100644 --- a/src/shader/shaders.cpp +++ b/src/shader/shaders.cpp @@ -25,7 +25,7 @@ const shader_source llmr::shaders[SHADER_COUNT] = { "uniform vec4 u_color;\n\nvoid main() {\n gl_FragColor = u_color;\n}\n", }, { - "attribute vec2 a_pos;\n\nuniform mat4 u_matrix;\nuniform float u_size;\n\nvoid main() {\n float z = step(32767.0, a_pos.x) * 2.0;\n gl_Position = u_matrix * vec4(a_pos, z, 1);\n gl_PointSize = u_size;\n}\n", + "attribute vec2 a_pos;\n\nuniform mat4 u_matrix;\nuniform float u_size;\n\nvoid main() {\n gl_Position = u_matrix * vec4(a_pos, 0, 1);\n gl_PointSize = u_size;\n}\n", "#define root2 1.42\n\nuniform sampler2D u_image;\nuniform vec2 u_tl;\nuniform vec2 u_br;\nuniform vec4 u_color;\n\nuniform vec2 pos;\nuniform float inbounds;\nuniform vec4 color;\n\nvoid main() {\n vec2 pos = (gl_PointCoord * 2.0 - 1.0) * root2 / 2.0 + 0.5;\n\n float inbounds = step(0.0, pos.x) * step(0.0, pos.y) *\n (1.0 - step(1.0, pos.x)) * (1.0 - step(1.0, pos.y));\n\n vec4 color = texture2D(u_image, mix(u_tl, u_br, pos)) * inbounds;\n\n if (u_color.a > 0.0) {\n gl_FragColor = u_color * color.a;\n } else {\n gl_FragColor = vec4(color.rgb * color.a, color.a);\n }\n}\n", } }; From 2602774a9c0074a642f18f65dafdcbf7c2b7dadb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Konstantin=20Ka=CC=88fer?= Date: Wed, 19 Feb 2014 14:48:54 +0100 Subject: [PATCH 12/37] bind texture 0 --- src/style/sprite.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/style/sprite.cpp b/src/style/sprite.cpp index e07cb89fd..a3e5d145c 100644 --- a/src/style/sprite.cpp +++ b/src/style/sprite.cpp @@ -236,11 +236,13 @@ void Sprite::bind(bool linear) { if (!texture) { glGenTextures(1, &texture); + glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, texture); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, img.data()); } else { + glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, texture); } From 9710fbef994f96c3eeab66aab4d73c97c7270138 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Konstantin=20Ka=CC=88fer?= Date: Wed, 19 Feb 2014 15:39:44 +0100 Subject: [PATCH 13/37] enable texture interpolation during rotating and scaling --- include/llmr/map/map.hpp | 4 ++++ include/llmr/map/transform.hpp | 3 +++ ios/MBXViewController.mm | 10 ++++++++++ src/map/map.cpp | 21 +++++++++++++++++++-- src/renderer/painter.cpp | 4 ++-- src/shader/point.fragment.glsl | 9 ++------- src/shader/shaders.cpp | 2 +- 7 files changed, 41 insertions(+), 12 deletions(-) diff --git a/include/llmr/map/map.hpp b/include/llmr/map/map.hpp index ada84f05b..93614a4f6 100644 --- a/include/llmr/map/map.hpp +++ b/include/llmr/map/map.hpp @@ -47,12 +47,16 @@ public: void setLonLatZoom(double lon, double lat, double zoom, double duration = 0); void getLonLatZoom(double &lon, double &lat, double &zoom) const; void resetZoom(); + void startScaling(); + void stopScaling(); /* rotation */ void rotateBy(double cx, double cy, double sx, double sy, double ex, double ey, double duration = 0); void setAngle(double angle, double cx = -1, double cy = -1, double duration = 0); double getAngle() const; void resetNorth(); + void startRotating(); + void stopRotating(); void toggleDebug(); diff --git a/include/llmr/map/transform.hpp b/include/llmr/map/transform.hpp index 56a5a8be9..a0a6003ee 100644 --- a/include/llmr/map/transform.hpp +++ b/include/llmr/map/transform.hpp @@ -61,6 +61,9 @@ public: float pixelRatio = 1; + bool rotating = false; + bool scaling = false; + private: double x = 0, y = 0; // pixel values of the map center in the current scale double angle = 0; diff --git a/ios/MBXViewController.mm b/ios/MBXViewController.mm index a687350af..040c05803 100644 --- a/ios/MBXViewController.mm +++ b/ios/MBXViewController.mm @@ -236,6 +236,7 @@ class MBXMapView if (pinch.state == UIGestureRecognizerStateBegan) { + mapView->map.startScaling(); self.scale = mapView->map.getScale(); } else if (pinch.state == UIGestureRecognizerStateChanged) @@ -258,6 +259,7 @@ class MBXMapView } else if (pinch.state == UIGestureRecognizerStateEnded) { + mapView->map.stopScaling(); if (fabsf(pinch.velocity) < 20) return; @@ -270,6 +272,9 @@ class MBXMapView mapView->map.scaleBy(new_scale / scale, [pinch locationInView:pinch.view].x, [pinch locationInView:pinch.view].y, duration); } + else if (pinch.state == UIGestureRecognizerStateCancelled) { + mapView->map.stopScaling(); + } [self updateRender]; } @@ -280,12 +285,17 @@ class MBXMapView if (rotate.state == UIGestureRecognizerStateBegan) { + mapView->map.startRotating(); self.angle = mapView->map.getAngle(); } else if (rotate.state == UIGestureRecognizerStateChanged) { mapView->map.setAngle(self.angle + rotate.rotation, [rotate locationInView:rotate.view].x, [rotate locationInView:rotate.view].y); } + else if (rotate.state == UIGestureRecognizerStateEnded || rotate.state == UIGestureRecognizerStateCancelled) + { + mapView->map.stopRotating(); + } [self updateRender]; } diff --git a/src/map/map.cpp b/src/map/map.cpp index 35dcb471f..e81bba058 100644 --- a/src/map/map.cpp +++ b/src/map/map.cpp @@ -77,6 +77,15 @@ void Map::scaleBy(double ds, double cx, double cy, double duration) { settings.persist(); } +void Map::startScaling() { + transform.scaling = true; +} + +void Map::stopScaling() { + transform.scaling = false; + +} + void Map::rotateBy(double cx, double cy, double sx, double sy, double ex, double ey, double duration) { transform.rotateBy(cx, cy, sx, sy, ex, ey, duration); update(); @@ -85,6 +94,14 @@ void Map::rotateBy(double cx, double cy, double sx, double sy, double ex, double settings.persist(); } +void Map::startRotating() { + transform.rotating = true; +} + +void Map::stopRotating() { + transform.rotating = false; +} + void Map::setLonLat(double lon, double lat, double duration) { transform.setLonLat(lon, lat, duration); update(); @@ -93,7 +110,7 @@ void Map::setLonLat(double lon, double lat, double duration) { settings.persist(); } -void Map::getLonLat(double &lon, double &lat) const { +void Map::getLonLat(double& lon, double& lat) const { transform.getLonLat(lon, lat); } @@ -107,7 +124,7 @@ void Map::setLonLatZoom(double lon, double lat, double zoom, double duration) { settings.persist(); } -void Map::getLonLatZoom(double &lon, double &lat, double &zoom) const { +void Map::getLonLatZoom(double& lon, double& lat, double& zoom) const { transform.getLonLatZoom(lon, lat, zoom); } diff --git a/src/renderer/painter.cpp b/src/renderer/painter.cpp index 28847b83e..169d3b127 100644 --- a/src/renderer/painter.cpp +++ b/src/renderer/painter.cpp @@ -400,9 +400,10 @@ void Painter::renderPoint(PointBucket& bucket, const std::string& layer_name, co ImagePosition imagePos = style.sprite->getPosition(sized_image, false); useProgram(pointShader->program); + style.sprite->bind(transform.rotating || transform.scaling); pointShader->setMatrix(matrix); pointShader->setColor(color); - const float pointSize = ceil(properties.size); + const float pointSize = properties.size * 1.4142135623730951; #if defined(GL_ES_VERSION_2_0) pointShader->setSize(pointSize); #else @@ -410,7 +411,6 @@ void Painter::renderPoint(PointBucket& bucket, const std::string& layer_name, co #endif pointShader->setPointTopLeft({{ imagePos.tl.x, imagePos.tl.y }}); pointShader->setPointBottomRight({{ imagePos.br.x, imagePos.br.y }}); - style.sprite->bind(true); bucket.drawPoints(*pointShader); } diff --git a/src/shader/point.fragment.glsl b/src/shader/point.fragment.glsl index dcd45cc69..89a8c1ca7 100644 --- a/src/shader/point.fragment.glsl +++ b/src/shader/point.fragment.glsl @@ -1,4 +1,4 @@ -#define root2 1.42 +#define root2 1.4142135623730951 uniform sampler2D u_image; uniform vec2 u_tl; @@ -16,10 +16,5 @@ void main() { (1.0 - step(1.0, pos.x)) * (1.0 - step(1.0, pos.y)); vec4 color = texture2D(u_image, mix(u_tl, u_br, pos)) * inbounds; - - if (u_color.a > 0.0) { - gl_FragColor = u_color * color.a; - } else { - gl_FragColor = vec4(color.rgb * color.a, color.a); - } + gl_FragColor = color; } diff --git a/src/shader/shaders.cpp b/src/shader/shaders.cpp index e62527813..84a0bf083 100644 --- a/src/shader/shaders.cpp +++ b/src/shader/shaders.cpp @@ -26,6 +26,6 @@ const shader_source llmr::shaders[SHADER_COUNT] = { }, { "attribute vec2 a_pos;\n\nuniform mat4 u_matrix;\nuniform float u_size;\n\nvoid main() {\n gl_Position = u_matrix * vec4(a_pos, 0, 1);\n gl_PointSize = u_size;\n}\n", - "#define root2 1.42\n\nuniform sampler2D u_image;\nuniform vec2 u_tl;\nuniform vec2 u_br;\nuniform vec4 u_color;\n\nuniform vec2 pos;\nuniform float inbounds;\nuniform vec4 color;\n\nvoid main() {\n vec2 pos = (gl_PointCoord * 2.0 - 1.0) * root2 / 2.0 + 0.5;\n\n float inbounds = step(0.0, pos.x) * step(0.0, pos.y) *\n (1.0 - step(1.0, pos.x)) * (1.0 - step(1.0, pos.y));\n\n vec4 color = texture2D(u_image, mix(u_tl, u_br, pos)) * inbounds;\n\n if (u_color.a > 0.0) {\n gl_FragColor = u_color * color.a;\n } else {\n gl_FragColor = vec4(color.rgb * color.a, color.a);\n }\n}\n", + "#define root2 1.4142135623730951\n\nuniform sampler2D u_image;\nuniform vec2 u_tl;\nuniform vec2 u_br;\nuniform vec4 u_color;\n\nuniform vec2 pos;\nuniform float inbounds;\nuniform vec4 color;\n\nvoid main() {\n vec2 pos = (gl_PointCoord * 2.0 - 1.0) * root2 / 2.0 + 0.5;\n\n float inbounds = step(0.0, pos.x) * step(0.0, pos.y) *\n (1.0 - step(1.0, pos.x)) * (1.0 - step(1.0, pos.y));\n\n vec4 color = texture2D(u_image, mix(u_tl, u_br, pos)) * inbounds;\n gl_FragColor = color;\n}\n", } }; From 7f5a674a914377ca350234d46e01b38dffdf01e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Konstantin=20Ka=CC=88fer?= Date: Wed, 19 Feb 2014 18:14:42 +0100 Subject: [PATCH 14/37] add texture settings --- include/llmr/renderer/shader-point.hpp | 6 +++++- src/renderer/painter.cpp | 6 ++++-- src/renderer/shader-point.cpp | 7 +++++++ src/shader/point.fragment.glsl | 10 ++++++---- src/shader/shaders.cpp | 2 +- 5 files changed, 23 insertions(+), 8 deletions(-) diff --git a/include/llmr/renderer/shader-point.hpp b/include/llmr/renderer/shader-point.hpp index 12605fb5a..1de38504c 100644 --- a/include/llmr/renderer/shader-point.hpp +++ b/include/llmr/renderer/shader-point.hpp @@ -11,6 +11,7 @@ public: void bind(char *offset); + void setImage(int32_t image); void setColor(const std::array& color); void setPointTopLeft(const std::array& point_tl); void setPointBottomRight(const std::array& point_br); @@ -19,6 +20,9 @@ public: private: int32_t a_pos = -1; + int32_t image = -1; + int32_t u_image = -1; + std::array color = {}; int32_t u_color = -1; @@ -31,7 +35,7 @@ private: float size = 0; int32_t u_size = -1; }; - + } #endif diff --git a/src/renderer/painter.cpp b/src/renderer/painter.cpp index 169d3b127..433d7ff0b 100644 --- a/src/renderer/painter.cpp +++ b/src/renderer/painter.cpp @@ -399,9 +399,11 @@ void Painter::renderPoint(PointBucket& bucket, const std::string& layer_name, co ImagePosition imagePos = style.sprite->getPosition(sized_image, false); + // fprintf(stderr, "%f/%f => %f/%f\n", imagePos.tl.x, imagePos.tl.y, imagePos.br.x, imagePos.br.y); + useProgram(pointShader->program); - style.sprite->bind(transform.rotating || transform.scaling); pointShader->setMatrix(matrix); + pointShader->setImage(0); pointShader->setColor(color); const float pointSize = properties.size * 1.4142135623730951; #if defined(GL_ES_VERSION_2_0) @@ -411,7 +413,7 @@ void Painter::renderPoint(PointBucket& bucket, const std::string& layer_name, co #endif pointShader->setPointTopLeft({{ imagePos.tl.x, imagePos.tl.y }}); pointShader->setPointBottomRight({{ imagePos.br.x, imagePos.br.y }}); - + style.sprite->bind(transform.rotating || transform.scaling); bucket.drawPoints(*pointShader); } diff --git a/src/renderer/shader-point.cpp b/src/renderer/shader-point.cpp index cbd1d576b..4c732fb19 100644 --- a/src/renderer/shader-point.cpp +++ b/src/renderer/shader-point.cpp @@ -37,6 +37,13 @@ void PointShader::bind(char *offset) { glVertexAttribPointer(a_pos, 2, GL_SHORT, false, 0, offset); } +void PointShader::setImage(int32_t new_image) { + if (image != new_image) { + glUniform1i(u_image, new_image); + image = new_image; + } +} + void PointShader::setColor(const std::array& new_color) { if (color != new_color) { glUniform4fv(u_color, 1, new_color.data()); diff --git a/src/shader/point.fragment.glsl b/src/shader/point.fragment.glsl index 89a8c1ca7..618cbc851 100644 --- a/src/shader/point.fragment.glsl +++ b/src/shader/point.fragment.glsl @@ -10,11 +10,13 @@ uniform float inbounds; uniform vec4 color; void main() { - vec2 pos = (gl_PointCoord * 2.0 - 1.0) * root2 / 2.0 + 0.5; + // vec2 pos = (gl_PointCoord * 2.0 - 1.0) * root2 / 2.0 + 0.5; - float inbounds = step(0.0, pos.x) * step(0.0, pos.y) * - (1.0 - step(1.0, pos.x)) * (1.0 - step(1.0, pos.y)); + // float inbounds = step(0.0, pos.x) * step(0.0, pos.y) * + // (1.0 - step(1.0, pos.x)) * (1.0 - step(1.0, pos.y)); + + // vec4 color = texture2D(u_image, mix(u_tl, u_br, pos)) * inbounds; + vec4 color = vec4(gl_PointCoord.s, gl_PointCoord.t, 0, 1); - vec4 color = texture2D(u_image, mix(u_tl, u_br, pos)) * inbounds; gl_FragColor = color; } diff --git a/src/shader/shaders.cpp b/src/shader/shaders.cpp index 84a0bf083..bc65f6221 100644 --- a/src/shader/shaders.cpp +++ b/src/shader/shaders.cpp @@ -26,6 +26,6 @@ const shader_source llmr::shaders[SHADER_COUNT] = { }, { "attribute vec2 a_pos;\n\nuniform mat4 u_matrix;\nuniform float u_size;\n\nvoid main() {\n gl_Position = u_matrix * vec4(a_pos, 0, 1);\n gl_PointSize = u_size;\n}\n", - "#define root2 1.4142135623730951\n\nuniform sampler2D u_image;\nuniform vec2 u_tl;\nuniform vec2 u_br;\nuniform vec4 u_color;\n\nuniform vec2 pos;\nuniform float inbounds;\nuniform vec4 color;\n\nvoid main() {\n vec2 pos = (gl_PointCoord * 2.0 - 1.0) * root2 / 2.0 + 0.5;\n\n float inbounds = step(0.0, pos.x) * step(0.0, pos.y) *\n (1.0 - step(1.0, pos.x)) * (1.0 - step(1.0, pos.y));\n\n vec4 color = texture2D(u_image, mix(u_tl, u_br, pos)) * inbounds;\n gl_FragColor = color;\n}\n", + "#define root2 1.4142135623730951\n\nuniform sampler2D u_image;\nuniform vec2 u_tl;\nuniform vec2 u_br;\nuniform vec4 u_color;\n\nuniform vec2 pos;\nuniform float inbounds;\nuniform vec4 color;\n\nvoid main() {\n // vec2 pos = (gl_PointCoord * 2.0 - 1.0) * root2 / 2.0 + 0.5;\n\n // float inbounds = step(0.0, pos.x) * step(0.0, pos.y) *\n // (1.0 - step(1.0, pos.x)) * (1.0 - step(1.0, pos.y));\n\n // vec4 color = texture2D(u_image, mix(u_tl, u_br, pos)) * inbounds;\n vec4 color = vec4(gl_PointCoord.s, gl_PointCoord.t, 0, 1);\n\n gl_FragColor = color;\n}\n", } }; From cbf96ba1c6212e57bfa5abd696f9313fe28304fc Mon Sep 17 00:00:00 2001 From: "Justin R. Miller" Date: Wed, 19 Feb 2014 12:27:23 -0800 Subject: [PATCH 15/37] minor formatting --- ios/MBXViewController.mm | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/ios/MBXViewController.mm b/ios/MBXViewController.mm index 040c05803..b8cfbdb92 100644 --- a/ios/MBXViewController.mm +++ b/ios/MBXViewController.mm @@ -237,6 +237,7 @@ class MBXMapView if (pinch.state == UIGestureRecognizerStateBegan) { mapView->map.startScaling(); + self.scale = mapView->map.getScale(); } else if (pinch.state == UIGestureRecognizerStateChanged) @@ -260,6 +261,7 @@ class MBXMapView else if (pinch.state == UIGestureRecognizerStateEnded) { mapView->map.stopScaling(); + if (fabsf(pinch.velocity) < 20) return; @@ -272,7 +274,8 @@ class MBXMapView mapView->map.scaleBy(new_scale / scale, [pinch locationInView:pinch.view].x, [pinch locationInView:pinch.view].y, duration); } - else if (pinch.state == UIGestureRecognizerStateCancelled) { + else if (pinch.state == UIGestureRecognizerStateCancelled) + { mapView->map.stopScaling(); } @@ -286,6 +289,7 @@ class MBXMapView if (rotate.state == UIGestureRecognizerStateBegan) { mapView->map.startRotating(); + self.angle = mapView->map.getAngle(); } else if (rotate.state == UIGestureRecognizerStateChanged) From 73f06b39bcb093712bbce1ef84ef32916528dedc Mon Sep 17 00:00:00 2001 From: "Justin R. Miller" Date: Wed, 19 Feb 2014 12:41:15 -0800 Subject: [PATCH 16/37] fixes #72: clean up & make callbacks clearer --- ios/MBXViewController.mm | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/ios/MBXViewController.mm b/ios/MBXViewController.mm index c5d6effa1..28bee82ce 100644 --- a/ios/MBXViewController.mm +++ b/ios/MBXViewController.mm @@ -385,7 +385,7 @@ namespace llmr { } - void request_http(std::string url, std::function func, std::function cb) + void request_http(std::string url, std::function background_function, std::function foreground_callback) { [[NSNotificationCenter defaultCenter] postNotificationName:MBXUpdateActivityNotification object:nil userInfo:[NSDictionary dictionaryWithObject:@1 forKey:@"count"]]; @@ -407,10 +407,11 @@ namespace llmr res.body = { (const char *)[data bytes], [data length] }; } - func(res); + background_function(res); - dispatch_async(dispatch_get_main_queue(), ^(void) { - cb(); + dispatch_async(dispatch_get_main_queue(), ^(void) + { + foreground_callback(); }); [[NSNotificationCenter defaultCenter] postNotificationName:MBXUpdateActivityNotification object:nil userInfo:[NSDictionary dictionaryWithObject:@(-1) forKey:@"count"]]; From 3a5dbdb5cc2e0418545d3e57c4990060e306c20e Mon Sep 17 00:00:00 2001 From: "Justin R. Miller" Date: Wed, 19 Feb 2014 12:41:35 -0800 Subject: [PATCH 17/37] iOS stylistic changes --- ios/MBXViewController.mm | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/ios/MBXViewController.mm b/ios/MBXViewController.mm index 28bee82ce..f101e7c84 100644 --- a/ios/MBXViewController.mm +++ b/ios/MBXViewController.mm @@ -373,9 +373,9 @@ class MBXMapView return ([validSimultaneousGestures containsObject:[gestureRecognizer class]] && [validSimultaneousGestures containsObject:[otherGestureRecognizer class]]); } -CADisplayLink *displayLink; MBXMapView *mapView; -NSOperationQueue *queue = NULL; +CADisplayLink *displayLink; +NSOperationQueue *queue; namespace llmr { @@ -389,11 +389,10 @@ namespace llmr { [[NSNotificationCenter defaultCenter] postNotificationName:MBXUpdateActivityNotification object:nil userInfo:[NSDictionary dictionaryWithObject:@1 forKey:@"count"]]; - if (!queue) { - queue = [[NSOperationQueue alloc] init]; - } + if (!queue) + queue = [NSOperationQueue new]; - NSMutableURLRequest *urlRequest = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:[NSString stringWithUTF8String:url.c_str()]]]; + NSMutableURLRequest *urlRequest = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@(url.c_str())]]; [NSURLConnection sendAsynchronousRequest:urlRequest queue:queue From 2989b456a45cb786ea8242b2da9a039395e16999 Mon Sep 17 00:00:00 2001 From: "Justin R. Miller" Date: Wed, 19 Feb 2014 12:41:57 -0800 Subject: [PATCH 18/37] properly make use of platform::restart on iOS --- ios/MBXViewController.mm | 1 + 1 file changed, 1 insertion(+) diff --git a/ios/MBXViewController.mm b/ios/MBXViewController.mm index f101e7c84..bea95d2bb 100644 --- a/ios/MBXViewController.mm +++ b/ios/MBXViewController.mm @@ -383,6 +383,7 @@ namespace llmr { void restart(void *) { + [[NSNotificationCenter defaultCenter] postNotificationName:MBXNeedsRenderNotification object:nil]; } void request_http(std::string url, std::function background_function, std::function foreground_callback) From cfbb8e9f7ddd81f9c0b29a082169a589c6002501 Mon Sep 17 00:00:00 2001 From: "Justin R. Miller" Date: Wed, 19 Feb 2014 12:44:47 -0800 Subject: [PATCH 19/37] minor objc style stuff --- macosx/main.mm | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/macosx/main.mm b/macosx/main.mm index c9d3045c3..426e50911 100644 --- a/macosx/main.mm +++ b/macosx/main.mm @@ -217,7 +217,7 @@ public: }; MapView *mapView; -NSOperationQueue *queue = NULL; +NSOperationQueue *queue; namespace llmr { namespace platform { @@ -228,13 +228,12 @@ void restart(void *) { void request_http(std::string url, std::function func, std::function cb) { if (!queue) { - queue = [[NSOperationQueue alloc] init]; + queue = [NSOperationQueue new]; } NSMutableURLRequest *urlRequest = [NSMutableURLRequest requestWithURL:[NSURL - URLWithString:[NSString - stringWithUTF8String:url.c_str()]]]; + URLWithString:@(url.c_str())]]; [NSURLConnection sendAsynchronousRequest:urlRequest From 0f2beb6992942feb2e22bf5476cf35b25eabd863 Mon Sep 17 00:00:00 2001 From: "Justin R. Miller" Date: Wed, 19 Feb 2014 12:45:05 -0800 Subject: [PATCH 20/37] refs #72: clarity around bg/fg functions --- macosx/main.mm | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/macosx/main.mm b/macosx/main.mm index 426e50911..c4f3c87a5 100644 --- a/macosx/main.mm +++ b/macosx/main.mm @@ -226,7 +226,7 @@ void restart(void *) { mapView->dirty = true; } -void request_http(std::string url, std::function func, std::function cb) { +void request_http(std::string url, std::function background_function, std::function foreground_callback) { if (!queue) { queue = [NSOperationQueue new]; } @@ -246,9 +246,9 @@ void request_http(std::string url, std::function func, std::fun res.body = { (const char *)[data bytes], [data length] }; } - func(res); + background_function(res); dispatch_async(dispatch_get_main_queue(), ^(void) { - cb(); + foreground_callback(); }); [[NSNotificationCenter defaultCenter] postNotificationName:MBXNeedsRenderNotification object:nil]; }]; From 9fbe5b2ece81c646f1f3d60f1d280a9241ba8937 Mon Sep 17 00:00:00 2001 From: "Justin R. Miller" Date: Wed, 19 Feb 2014 14:51:46 -0800 Subject: [PATCH 21/37] properly deregister render observers --- ios/MBXViewController.mm | 2 ++ macosx/main.mm | 5 ++++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ios/MBXViewController.mm b/ios/MBXViewController.mm index bea95d2bb..8d734459c 100644 --- a/ios/MBXViewController.mm +++ b/ios/MBXViewController.mm @@ -141,6 +141,8 @@ class MBXMapView - (void)dealloc { + [[NSNotificationCenter defaultCenter] removeObserver:self]; + mapView->settings.sync(); } diff --git a/macosx/main.mm b/macosx/main.mm index c4f3c87a5..7c2f0cc1e 100644 --- a/macosx/main.mm +++ b/macosx/main.mm @@ -56,7 +56,7 @@ public: glfwSetCharCallback(window, character); glfwSetKeyCallback(window, key); - [[NSNotificationCenter defaultCenter] addObserverForName:MBXNeedsRenderNotification + renderObserver = [[NSNotificationCenter defaultCenter] addObserverForName:MBXNeedsRenderNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock: ^ (NSNotification * notification) { @@ -198,6 +198,7 @@ public: } ~MapView() { + [[NSNotificationCenter defaultCenter] removeObserver:renderObserver]; glfwTerminate(); } @@ -214,6 +215,8 @@ public: GLFWwindow *window; llmr::Settings_MacOSX settings; llmr::Map map; + + id renderObserver; }; MapView *mapView; From 1f2150fcd7aaa2f09213fa0a75bd38bf431dedb0 Mon Sep 17 00:00:00 2001 From: "Justin R. Miller" Date: Wed, 19 Feb 2014 15:15:23 -0800 Subject: [PATCH 22/37] add argument clarity to platform::request_http declaration --- include/llmr/platform/platform.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/llmr/platform/platform.hpp b/include/llmr/platform/platform.hpp index f56e738ff..4aa2fb571 100644 --- a/include/llmr/platform/platform.hpp +++ b/include/llmr/platform/platform.hpp @@ -23,7 +23,7 @@ struct Response { std::string body; }; -void request_http(std::string url, std::function func, std::function cb); +void request_http(std::string url, std::function background_function, std::function foreground_callback); // Returns a relative timestamp in seconds. This value must be monotonic. double time(); From 66a2c994ac66d937aa7e5f5674f772ca9db551a2 Mon Sep 17 00:00:00 2001 From: "Justin R. Miller" Date: Wed, 19 Feb 2014 17:23:22 -0800 Subject: [PATCH 23/37] clean up platform comments --- include/llmr/platform/platform.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/llmr/platform/platform.hpp b/include/llmr/platform/platform.hpp index 4aa2fb571..41144fa63 100644 --- a/include/llmr/platform/platform.hpp +++ b/include/llmr/platform/platform.hpp @@ -14,8 +14,7 @@ class Tile; namespace platform { -// Restarts painting. This could for example trigger the event loop of the -// controlling application. +// Restarts painting. This could for example trigger the event loop of the controlling application. void restart(void *obj); struct Response { @@ -23,6 +22,7 @@ struct Response { std::string body; }; +// Makes an HTTP request of a URL on a background thread, calls a function with the results on the same thread, and finally calls a callback function on the main thread. void request_http(std::string url, std::function background_function, std::function foreground_callback); // Returns a relative timestamp in seconds. This value must be monotonic. From 9e762f91eb6e59127bd6a1944bafc5e8b3095035 Mon Sep 17 00:00:00 2001 From: "Justin R. Miller" Date: Thu, 20 Feb 2014 15:53:17 -0800 Subject: [PATCH 24/37] gl_pointCoord requires GL_POINT_SPRITE on OS X --- src/renderer/painter.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/renderer/painter.cpp b/src/renderer/painter.cpp index 433d7ff0b..bba2af382 100644 --- a/src/renderer/painter.cpp +++ b/src/renderer/painter.cpp @@ -410,6 +410,7 @@ void Painter::renderPoint(PointBucket& bucket, const std::string& layer_name, co pointShader->setSize(pointSize); #else glPointSize(pointSize); + glEnable(GL_POINT_SPRITE); #endif pointShader->setPointTopLeft({{ imagePos.tl.x, imagePos.tl.y }}); pointShader->setPointBottomRight({{ imagePos.br.x, imagePos.br.y }}); From 49f9439b07e08f6f615b88ec24c0b53d9e14cd74 Mon Sep 17 00:00:00 2001 From: "Justin R. Miller" Date: Thu, 20 Feb 2014 15:53:46 -0800 Subject: [PATCH 25/37] add image debugging --- src/renderer/shader-point.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/renderer/shader-point.cpp b/src/renderer/shader-point.cpp index 4c732fb19..835728417 100644 --- a/src/renderer/shader-point.cpp +++ b/src/renderer/shader-point.cpp @@ -30,6 +30,7 @@ PointShader::PointShader() // fprintf(stderr, " - u_size: %d\n", u_size); // fprintf(stderr, " - u_point_tl: %d\n", u_point_tl); // fprintf(stderr, " - u_point_br: %d\n", u_point_br); + // fprintf(stderr, " - u_image: %d\n", u_image); } void PointShader::bind(char *offset) { From a9198570eaeefa97b3a22358e85e338123afbc4a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Konstantin=20Ka=CC=88fer?= Date: Fri, 21 Feb 2014 10:41:22 +0100 Subject: [PATCH 26/37] revert shader --- src/shader/point.fragment.glsl | 9 ++++----- src/shader/shaders.cpp | 2 +- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/shader/point.fragment.glsl b/src/shader/point.fragment.glsl index 618cbc851..2343f7db0 100644 --- a/src/shader/point.fragment.glsl +++ b/src/shader/point.fragment.glsl @@ -10,13 +10,12 @@ uniform float inbounds; uniform vec4 color; void main() { - // vec2 pos = (gl_PointCoord * 2.0 - 1.0) * root2 / 2.0 + 0.5; + vec2 pos = (gl_PointCoord * 2.0 - 1.0) * root2 / 2.0 + 0.5; - // float inbounds = step(0.0, pos.x) * step(0.0, pos.y) * - // (1.0 - step(1.0, pos.x)) * (1.0 - step(1.0, pos.y)); + float inbounds = step(0.0, pos.x) * step(0.0, pos.y) * + (1.0 - step(1.0, pos.x)) * (1.0 - step(1.0, pos.y)); - // vec4 color = texture2D(u_image, mix(u_tl, u_br, pos)) * inbounds; - vec4 color = vec4(gl_PointCoord.s, gl_PointCoord.t, 0, 1); + vec4 color = texture2D(u_image, mix(u_tl, u_br, pos)) * inbounds; gl_FragColor = color; } diff --git a/src/shader/shaders.cpp b/src/shader/shaders.cpp index bc65f6221..b6ee1b46b 100644 --- a/src/shader/shaders.cpp +++ b/src/shader/shaders.cpp @@ -26,6 +26,6 @@ const shader_source llmr::shaders[SHADER_COUNT] = { }, { "attribute vec2 a_pos;\n\nuniform mat4 u_matrix;\nuniform float u_size;\n\nvoid main() {\n gl_Position = u_matrix * vec4(a_pos, 0, 1);\n gl_PointSize = u_size;\n}\n", - "#define root2 1.4142135623730951\n\nuniform sampler2D u_image;\nuniform vec2 u_tl;\nuniform vec2 u_br;\nuniform vec4 u_color;\n\nuniform vec2 pos;\nuniform float inbounds;\nuniform vec4 color;\n\nvoid main() {\n // vec2 pos = (gl_PointCoord * 2.0 - 1.0) * root2 / 2.0 + 0.5;\n\n // float inbounds = step(0.0, pos.x) * step(0.0, pos.y) *\n // (1.0 - step(1.0, pos.x)) * (1.0 - step(1.0, pos.y));\n\n // vec4 color = texture2D(u_image, mix(u_tl, u_br, pos)) * inbounds;\n vec4 color = vec4(gl_PointCoord.s, gl_PointCoord.t, 0, 1);\n\n gl_FragColor = color;\n}\n", + "#define root2 1.4142135623730951\n\nuniform sampler2D u_image;\nuniform vec2 u_tl;\nuniform vec2 u_br;\nuniform vec4 u_color;\n\nuniform vec2 pos;\nuniform float inbounds;\nuniform vec4 color;\n\nvoid main() {\n vec2 pos = (gl_PointCoord * 2.0 - 1.0) * root2 / 2.0 + 0.5;\n\n float inbounds = step(0.0, pos.x) * step(0.0, pos.y) *\n (1.0 - step(1.0, pos.x)) * (1.0 - step(1.0, pos.y));\n\n vec4 color = texture2D(u_image, mix(u_tl, u_br, pos)) * inbounds;\n\n gl_FragColor = color;\n}\n", } }; From d5c611d7076e901b524b0d941b29b1a8180429e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Konstantin=20Ka=CC=88fer?= Date: Fri, 21 Feb 2014 11:31:24 +0100 Subject: [PATCH 27/37] add timeouts for panning,scaling,rotating --- include/llmr/map/map.hpp | 2 + include/llmr/map/transform.hpp | 14 ++++++- include/llmr/util/animation.hpp | 44 ++++++++++++++++++++-- macosx/main.mm | 14 ++++++- src/map/map.cpp | 23 ++++++++--- src/map/transform.cpp | 67 +++++++++++++++++++++++++++++---- src/renderer/painter.cpp | 2 +- src/util/animation.cpp | 11 +++--- 8 files changed, 153 insertions(+), 24 deletions(-) diff --git a/include/llmr/map/map.hpp b/include/llmr/map/map.hpp index 93614a4f6..664edf715 100644 --- a/include/llmr/map/map.hpp +++ b/include/llmr/map/map.hpp @@ -36,6 +36,8 @@ public: void moveBy(double dx, double dy, double duration = 0); void setLonLat(double lon, double lat, double duration = 0); void getLonLat(double &lon, double &lat) const; + void startPanning(); + void stopPanning(); void resetPosition(); /* scale */ diff --git a/include/llmr/map/transform.hpp b/include/llmr/map/transform.hpp index a0a6003ee..a628bf33d 100644 --- a/include/llmr/map/transform.hpp +++ b/include/llmr/map/transform.hpp @@ -42,6 +42,14 @@ public: void getLonLat(double& lon, double& lat) const; void getLonLatZoom(double& lon, double& lat, double& zoom) const; + // Animations + void startPanning(); + void stopPanning(); + void startRotating(); + void stopRotating(); + void startScaling(); + void stopScaling(); + // Temporary void mapCornersToBox(uint32_t z, box& b) const; @@ -63,6 +71,7 @@ public: bool rotating = false; bool scaling = false; + bool panning = false; private: double x = 0, y = 0; // pixel values of the map center in the current scale @@ -75,7 +84,10 @@ private: // cache values for spherical mercator math double zc, Bc, Cc; - std::forward_list animations; + std::forward_list> animations; + std::shared_ptr scale_timeout; + std::shared_ptr rotate_timeout; + std::shared_ptr pan_timeout; }; } diff --git a/include/llmr/util/animation.hpp b/include/llmr/util/animation.hpp index 4095fcba1..2024fb875 100644 --- a/include/llmr/util/animation.hpp +++ b/include/llmr/util/animation.hpp @@ -2,6 +2,7 @@ #define LLMR_UTIL_ANIMATION #include +#include namespace llmr { namespace util { @@ -12,14 +13,51 @@ public: running, complete }; + animation(double duration) + : start(platform::time()), + duration(duration) {} - animation(double from, double to, double &value, double duration); + double progress() const { + return (platform::time() - start) / duration; + } + + virtual state update() const = 0; + virtual ~animation(); + +protected: + const double start, duration; +}; + +class ease_animation : public animation { +public: + ease_animation(double from, double to, double& value, double duration); state update() const; private: - const double start, duration; const double from, to; - double &value; + double& value; +}; + +template +class timeout : public animation { +public: + timeout(T final_value, T& value, double duration) + : animation(duration), + final_value(final_value), + value(value) {} + + state update() const { + if (progress() >= 1) { + value = final_value; + return complete; + } else { + return running; + } + } + +private: + const T final_value; + T& value; }; } diff --git a/macosx/main.mm b/macosx/main.mm index ff8e91e33..4eba7e047 100644 --- a/macosx/main.mm +++ b/macosx/main.mm @@ -5,6 +5,8 @@ #include #include "settings.hpp" +#include + #include NSString *const MBXNeedsRenderNotification = @"MBXNeedsRenderNotification"; @@ -116,6 +118,7 @@ public: scale = 1.0 / scale; } + mapView->map.startScaling(); mapView->map.scaleBy(scale, mapView->last_x, mapView->last_y); } @@ -138,11 +141,14 @@ public: if (mapView->rotating) { mapView->start_x = mapView->last_x; mapView->start_y = mapView->last_y; + } else { + mapView->map.stopRotating(); } } else if (button == GLFW_MOUSE_BUTTON_LEFT) { mapView->tracking = action == GLFW_PRESS; if (action == GLFW_RELEASE) { + mapView->map.stopPanning(); double now = glfwGetTime(); if (now - mapView->last_click < 0.4) { mapView->map.scaleBy(2.0, mapView->last_x, mapView->last_y); @@ -155,8 +161,14 @@ public: static void mousemove(GLFWwindow *window, double x, double y) { MapView *mapView = (MapView *)glfwGetWindowUserPointer(window); if (mapView->tracking) { - mapView->map.moveBy(x - mapView->last_x, y - mapView->last_y); + double dx = x - mapView->last_x; + double dy = y - mapView->last_y; + if (dx || dy) { + mapView->map.startPanning(); + mapView->map.moveBy(dx, dy); + } } else if (mapView->rotating) { + mapView->map.startRotating(); mapView->map.rotateBy(mapView->start_x, mapView->start_y, mapView->last_x, mapView->last_y, x, y); } mapView->last_x = x; diff --git a/src/map/map.cpp b/src/map/map.cpp index e81bba058..c4313ece6 100644 --- a/src/map/map.cpp +++ b/src/map/map.cpp @@ -67,6 +67,16 @@ void Map::moveBy(double dx, double dy, double duration) { settings.persist(); } +void Map::startPanning() { + transform.startPanning(); + platform::restart(this); +} + +void Map::stopPanning() { + transform.stopPanning(); + platform::restart(this); +} + void Map::scaleBy(double ds, double cx, double cy, double duration) { transform.scaleBy(ds, cx, cy, duration); style.cascade(transform.getZoom()); @@ -78,12 +88,13 @@ void Map::scaleBy(double ds, double cx, double cy, double duration) { } void Map::startScaling() { - transform.scaling = true; + transform.startScaling(); + platform::restart(this); } void Map::stopScaling() { - transform.scaling = false; - + transform.stopScaling(); + platform::restart(this); } void Map::rotateBy(double cx, double cy, double sx, double sy, double ex, double ey, double duration) { @@ -95,11 +106,13 @@ void Map::rotateBy(double cx, double cy, double sx, double sy, double ex, double } void Map::startRotating() { - transform.rotating = true; + transform.startRotating(); + platform::restart(this); } void Map::stopRotating() { - transform.rotating = false; + transform.stopRotating(); + platform::restart(this); } void Map::setLonLat(double lon, double lat, double duration) { diff --git a/src/map/transform.cpp b/src/map/transform.cpp index 446cc23e2..12c55e1f9 100644 --- a/src/map/transform.cpp +++ b/src/map/transform.cpp @@ -1,6 +1,7 @@ #include #include #include +#include #include #include @@ -24,8 +25,8 @@ bool Transform::needsAnimation() const { } void Transform::updateAnimations() { - animations.remove_if([](const util::animation& animation) { - return animation.update() == util::animation::complete; + animations.remove_if([](const std::shared_ptr& animation) { + return animation->update() == util::animation::complete; }); } @@ -40,8 +41,25 @@ void Transform::moveBy(double dx, double dy, double duration) { x = xn; y = yn; } else { - animations.emplace_front(x, xn, x, duration); - animations.emplace_front(y, yn, y, duration); + animations.emplace_front(std::make_shared(x, xn, x, duration)); + animations.emplace_front(std::make_shared(y, yn, y, duration)); + } +} + +void Transform::startPanning() { + stopPanning(); + + // Add a 200ms timeout for resetting this to false + panning = true; + pan_timeout = std::make_shared>(false, panning, 0.2); + animations.emplace_front(pan_timeout); +} + +void Transform::stopPanning() { + panning = false; + if (pan_timeout) { + animations.remove(pan_timeout); + pan_timeout.reset(); } } @@ -59,6 +77,22 @@ void Transform::scaleBy(double ds, double cx, double cy, double duration) { setScale(new_scale, cx, cy, duration); } +void Transform::startScaling() { + stopScaling(); + + // Add a 200ms timeout for resetting this to false + scaling = true; + scale_timeout = std::make_shared>(false, scaling, 0.2); + animations.emplace_front(scale_timeout); +} + +void Transform::stopScaling() { + scaling = false; + if (scale_timeout) { + animations.remove(scale_timeout); + scale_timeout.reset(); + } +} void Transform::rotateBy(double anchor_x, double anchor_y, double start_x, double start_y, double end_x, double end_y, double duration) { double center_x = width / 2, center_y = height / 2; @@ -94,7 +128,24 @@ void Transform::setAngle(double new_angle, double duration) { if (duration == 0) { angle = new_angle; } else { - animations.emplace_front(angle, new_angle, angle, duration); + animations.emplace_front(std::make_shared(angle, new_angle, angle, duration)); + } +} + +void Transform::startRotating() { + stopRotating(); + + // Add a 200ms timeout for resetting this to false + rotating = true; + rotate_timeout = std::make_shared>(false, rotating, 0.2); + animations.emplace_front(rotate_timeout); +} + +void Transform::stopRotating() { + rotating = false; + if (rotate_timeout) { + animations.remove(rotate_timeout); + rotate_timeout.reset(); } } @@ -104,9 +155,9 @@ void Transform::setScaleXY(double new_scale, double xn, double yn, double durati x = xn; y = yn; } else { - animations.emplace_front(scale, new_scale, scale, duration); - animations.emplace_front(x, xn, x, duration); - animations.emplace_front(y, yn, y, duration); + animations.emplace_front(std::make_shared(scale, new_scale, scale, duration)); + animations.emplace_front(std::make_shared(x, xn, x, duration)); + animations.emplace_front(std::make_shared(y, yn, y, duration)); } const double s = scale * util::tileSize; diff --git a/src/renderer/painter.cpp b/src/renderer/painter.cpp index bba2af382..8d362ca29 100644 --- a/src/renderer/painter.cpp +++ b/src/renderer/painter.cpp @@ -414,7 +414,7 @@ void Painter::renderPoint(PointBucket& bucket, const std::string& layer_name, co #endif pointShader->setPointTopLeft({{ imagePos.tl.x, imagePos.tl.y }}); pointShader->setPointBottomRight({{ imagePos.br.x, imagePos.br.y }}); - style.sprite->bind(transform.rotating || transform.scaling); + style.sprite->bind(transform.rotating || transform.scaling || transform.panning); bucket.drawPoints(*pointShader); } diff --git a/src/util/animation.cpp b/src/util/animation.cpp index a2c3e778e..8624fc22a 100644 --- a/src/util/animation.cpp +++ b/src/util/animation.cpp @@ -6,16 +6,17 @@ using namespace llmr::util; UnitBezier ease(0.25, 0.1, 0.25, 1); -animation::animation(double from, double to, double &value, double duration) - : start(platform::time()), - duration(duration), +animation::~animation() {} + +ease_animation::ease_animation(double from, double to, double &value, double duration) + : animation(duration), from(from), to(to), value(value) { } -animation::state animation::update() const { - double t = (platform::time() - start) / duration; +animation::state ease_animation::update() const { + double t = progress(); if (t >= 1) { value = to; return complete; From bd2d865fc474f752b48b88b4b8fd2c8eb307f301 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Konstantin=20Ka=CC=88fer?= Date: Fri, 21 Feb 2014 12:05:27 +0100 Subject: [PATCH 28/37] trigger a bogus mouse move event to interrupt glfwWaitEvents() see https://github.com/glfw/glfw/issues/218 --- include/llmr/map/map.hpp | 2 -- macosx/main.mm | 3 +++ src/map/map.cpp | 15 ++------------- 3 files changed, 5 insertions(+), 15 deletions(-) diff --git a/include/llmr/map/map.hpp b/include/llmr/map/map.hpp index 84cb4d12e..c82fcae47 100644 --- a/include/llmr/map/map.hpp +++ b/include/llmr/map/map.hpp @@ -29,8 +29,6 @@ public: /* callback */ bool render(); void cancelAnimations(); - void tileLoaded(std::shared_ptr tile); - void tileFailed(std::shared_ptr tile); /* position */ void moveBy(double dx, double dy, double duration = 0); diff --git a/macosx/main.mm b/macosx/main.mm index 7c2f0cc1e..18229f9f4 100644 --- a/macosx/main.mm +++ b/macosx/main.mm @@ -227,6 +227,9 @@ namespace platform { void restart(void *) { mapView->dirty = true; + CGEventRef event = CGEventCreate(NULL); + CGEventSetType(event, kCGEventMouseMoved); + [[NSApplication sharedApplication] postEvent: [NSEvent eventWithCGEvent:event] atStart:NO]; } void request_http(std::string url, std::function background_function, std::function foreground_callback) { diff --git a/src/map/map.cpp b/src/map/map.cpp index e837ecffb..5e31c97c1 100644 --- a/src/map/map.cpp +++ b/src/map/map.cpp @@ -375,12 +375,12 @@ bool Map::updateTiles() { } bool Map::render() { - bool changed = false; if (transform.needsAnimation()) { transform.updateAnimations(); - changed = updateTiles(); } + bool changed = updateTiles(); + painter.clear(); for (Tile::Ptr& tile : tiles) { @@ -395,14 +395,3 @@ bool Map::render() { return changed || transform.needsAnimation(); } - -void Map::tileLoaded(Tile::Ptr tile) { - // std::cerr << "loaded " << tile->toString() << std::endl; - update(); -} - -void Map::tileFailed(Tile::Ptr tile) { - // fprintf(stderr, "[%8zx] tile failed to load %d/%d/%d\n", - // std::hash()(std::this_thread::get_id()), - // tile->z, tile->x, tile->y); -} From 0306e77ff09f3df4c0c809c153e135d92bb6db73 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Konstantin=20Ka=CC=88fer?= Date: Fri, 21 Feb 2014 12:18:11 +0100 Subject: [PATCH 29/37] remove void* parameter from platform::restart() --- include/llmr/platform/platform.hpp | 2 +- ios/MBXViewController.mm | 2 +- macosx/main.mm | 16 ++-------------- src/map/map.cpp | 14 +++++++------- src/map/tile.cpp | 3 +-- src/style/sprite.cpp | 2 +- 6 files changed, 13 insertions(+), 26 deletions(-) diff --git a/include/llmr/platform/platform.hpp b/include/llmr/platform/platform.hpp index 4431a662c..25778c561 100644 --- a/include/llmr/platform/platform.hpp +++ b/include/llmr/platform/platform.hpp @@ -15,7 +15,7 @@ class Tile; namespace platform { // Restarts painting. This could for example trigger the event loop of the controlling application. -void restart(void *obj); +void restart(); struct Response { int16_t code = -1; diff --git a/ios/MBXViewController.mm b/ios/MBXViewController.mm index 990045108..2c998f7af 100644 --- a/ios/MBXViewController.mm +++ b/ios/MBXViewController.mm @@ -397,7 +397,7 @@ namespace llmr { namespace platform { - void restart(void *) + void restart() { [[NSNotificationCenter defaultCenter] postNotificationName:MBXNeedsRenderNotification object:nil]; } diff --git a/macosx/main.mm b/macosx/main.mm index 1c1d77eee..472799d99 100644 --- a/macosx/main.mm +++ b/macosx/main.mm @@ -9,8 +9,6 @@ #include -NSString *const MBXNeedsRenderNotification = @"MBXNeedsRenderNotification"; - class MapView { public: MapView() : @@ -63,15 +61,9 @@ public: glfwSetScrollCallback(window, scroll); glfwSetCharCallback(window, character); glfwSetKeyCallback(window, key); - - renderObserver = [[NSNotificationCenter defaultCenter] addObserverForName:MBXNeedsRenderNotification - object:nil - queue:[NSOperationQueue mainQueue] - usingBlock: ^ (NSNotification * notification) { - dirty = true; - }]; } + static void character(GLFWwindow *window, unsigned int codepoint) { } @@ -216,7 +208,6 @@ public: } ~MapView() { - [[NSNotificationCenter defaultCenter] removeObserver:renderObserver]; glfwTerminate(); } @@ -233,8 +224,6 @@ public: GLFWwindow *window; llmr::Settings_MacOSX settings; llmr::Map map; - - id renderObserver; }; MapView *mapView; @@ -243,7 +232,7 @@ NSOperationQueue *queue; namespace llmr { namespace platform { -void restart(void *) { +void restart() { mapView->dirty = true; CGEventRef event = CGEventCreate(NULL); CGEventSetType(event, kCGEventMouseMoved); @@ -274,7 +263,6 @@ void request_http(std::string url, std::function background_fun dispatch_async(dispatch_get_main_queue(), ^(void) { foreground_callback(); }); - [[NSNotificationCenter defaultCenter] postNotificationName:MBXNeedsRenderNotification object:nil]; }]; } diff --git a/src/map/map.cpp b/src/map/map.cpp index 429b98e2b..d09b505f4 100644 --- a/src/map/map.cpp +++ b/src/map/map.cpp @@ -69,12 +69,12 @@ void Map::moveBy(double dx, double dy, double duration) { void Map::startPanning() { transform.startPanning(); - platform::restart(this); + platform::restart(); } void Map::stopPanning() { transform.stopPanning(); - platform::restart(this); + platform::restart(); } void Map::scaleBy(double ds, double cx, double cy, double duration) { @@ -89,12 +89,12 @@ void Map::scaleBy(double ds, double cx, double cy, double duration) { void Map::startScaling() { transform.startScaling(); - platform::restart(this); + platform::restart(); } void Map::stopScaling() { transform.stopScaling(); - platform::restart(this); + platform::restart(); } void Map::rotateBy(double cx, double cy, double sx, double sy, double ex, double ey, double duration) { @@ -107,12 +107,12 @@ void Map::rotateBy(double cx, double cy, double sx, double sy, double ex, double void Map::startRotating() { transform.startRotating(); - platform::restart(this); + platform::restart(); } void Map::stopRotating() { transform.stopRotating(); - platform::restart(this); + platform::restart(); } void Map::setLonLat(double lon, double lat, double duration) { @@ -233,7 +233,7 @@ void Map::cancelAnimations() { void Map::update() { updateTiles(); - platform::restart(this); + platform::restart(); } diff --git a/src/map/tile.cpp b/src/map/tile.cpp index 938024d47..f734a32e1 100644 --- a/src/map/tile.cpp +++ b/src/map/tile.cpp @@ -83,8 +83,7 @@ void Tile::request() { fprintf(stderr, "tile loading failed\n"); } }, []() { - // TODO: Make sure this gets passed the correct map ID/pointer. - platform::restart(nullptr); + platform::restart(); }); } diff --git a/src/style/sprite.cpp b/src/style/sprite.cpp index a3e5d145c..ed56a679f 100644 --- a/src/style/sprite.cpp +++ b/src/style/sprite.cpp @@ -36,7 +36,7 @@ void Sprite::load(const std::string& base_url, float pixelRatio) { std::lock_guard lock(sprite->mtx); if (sprite->img.size() && sprite->pos.size()) { sprite->loaded = true; - platform::restart(NULL); + platform::restart(); fprintf(stderr, "sprite loaded\n"); } }; From 4418f2d1c8f51ee268e2180c287abae0b8dbc574 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Konstantin=20Ka=CC=88fer?= Date: Fri, 21 Feb 2014 12:34:39 +0100 Subject: [PATCH 30/37] remove remnants of emscripten --- .gitignore | 17 ++-- emscripten/main.cpp | 154 ----------------------------------- emscripten/main.html | 9 -- enable-emscripten | 2 - include/llmr/platform/gl.hpp | 4 +- src/renderer/shader.cpp | 4 +- 6 files changed, 10 insertions(+), 180 deletions(-) delete mode 100644 emscripten/main.cpp delete mode 100644 emscripten/main.html delete mode 100644 enable-emscripten diff --git a/.gitignore b/.gitignore index bbd74195c..7a261599a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,11 +1,8 @@ -*.o -/emscripten/main.js -/emscripten/main.js.map -/build -*.sublime-* -config.gypi -config.mk -.DS_Store -out -mapnik-packaging *.xcodeproj +/out +/mapnik-packaging +/macosx/build +/ios/build +/config.gypi +/config.mk +/build \ No newline at end of file diff --git a/emscripten/main.cpp b/emscripten/main.cpp deleted file mode 100644 index ffdef046b..000000000 --- a/emscripten/main.cpp +++ /dev/null @@ -1,154 +0,0 @@ -#include -#include -#include -#include -#include - #include - -#include -#include - -bool dirty = true; - -class MapView; - -static MapView *view; - -class MapView { -public: - MapView() : - dirty(true), - platform(new llmr::platform(this)), - map(new llmr::map(platform)) { - - // Initialize GLFW - if (!glfwInit()) { - fprintf(stderr, "Failed to initialize GLFW\n"); - exit(1); - } - - int width, height; - emscripten_get_canvas_size(&width, &height, nullptr); - - glfwSetMousePosCallback(mousemove); - glfwSetMouseButtonCallback(mouseclick); - glfwSetMouseWheelCallback(scroll); - - // Open a window and create its OpenGL context - if (!glfwOpenWindow(width, height, 8, 8, 8, 8, 16, 8, GLFW_WINDOW)) { - fprintf(stderr, "Failed to open GLFW window\n"); - - glfwTerminate(); - exit(1); - } - - map->setup(); - map->resize(width, height); - - } - - ~MapView() { - delete map; - delete platform; - glfwTerminate(); - } - - static void mousemove(int x, int y) { - if (view->tracking) { - view->map->moveBy(x - view->last_x, y - view->last_y); - } - view->last_x = x; - view->last_y = y; - } - - static void scroll(float pos) { - double delta = pos; - - // bool is_wheel = delta != 0 && fmod(delta, 4.000244140625) == 0; - - double absdelta = delta < 0 ? -delta : delta; - double scale = 2.0 / (1.0 + exp(-absdelta / 100.0)); - - // Make the scroll wheel a bit slower. - // if (!is_wheel) { - // scale = (scale - 1.0) / 2.0 + 1.0; - // } - - // Zooming out. - if (delta < 0 && scale != 0) { - scale = 1.0 / scale; - } - - view->map->scaleBy(scale, view->last_x, view->last_y); - } - - static void mouseclick(int button, int action) { - if (button == GLFW_MOUSE_BUTTON_1) { - view->tracking = action == GLFW_PRESS; - } else if (button == GLFW_MOUSE_BUTTON_RIGHT) { - fprintf(stderr, "right mouse\n"); - } - } - - int run() { - emscripten_set_main_loop(render, 60, 1); - return 0; - } - - static void render() { - if (view->dirty) { - view->map->render(); - // glClearColor(1, 1, 0, 1); - // glClear(GL_COLOR_BUFFER_BIT); - - view->dirty = false; - } - } - - bool dirty; - double last_x, last_y; - bool tracking; - - - llmr::platform *platform; - llmr::map *map; - -}; - - -void llmr::platform::restart() { - view->dirty = true; -} - -void ontileload(void* custom, void* bytes, int length) { - fprintf(stderr, "data loaded successfully: length: %d\n", length); - llmr::tile *tile = (llmr::tile *)custom; - tile->setData((uint8_t *)bytes, length); - if (tile->parse()) { - view->map->tileLoaded(tile); - return; - } -} - -void ontileerror(void* custom) { - fprintf(stderr, "data load error\n"); - llmr::tile *tile = (llmr::tile *)custom; - view->map->tileFailed(tile); -} - -void llmr::platform::request(tile *tile) { - const char *urlTemplate = "http://api.tiles.mapbox.com/v3/mapbox.mapbox-streets-v4/%d/%d/%d.vector.pbf"; - char urlString[255]; - snprintf(urlString, 255, urlTemplate, tile->z, tile->x, tile->y); - fprintf(stderr, "requesting %s\n", urlString); - - emscripten_async_wget_data(urlString, tile, ontileload, ontileerror); -} - - -int main() { - view = new MapView(); - int ret = view->run(); - delete view; - return ret; -} diff --git a/emscripten/main.html b/emscripten/main.html deleted file mode 100644 index 967613052..000000000 --- a/emscripten/main.html +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/enable-emscripten b/enable-emscripten deleted file mode 100644 index d7feba1ea..000000000 --- a/enable-emscripten +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/sh -export PATH="`emsdk active_path`:$PATH" diff --git a/include/llmr/platform/gl.hpp b/include/llmr/platform/gl.hpp index 4074fa081..a0d059c75 100644 --- a/include/llmr/platform/gl.hpp +++ b/include/llmr/platform/gl.hpp @@ -1,9 +1,7 @@ #ifndef LLMR_RENDERER_GL #define LLMR_RENDERER_GL -#ifdef EMSCRIPTEN - #include -#elif __APPLE__ +#if __APPLE__ #include "TargetConditionals.h" #if TARGET_OS_IPHONE #include diff --git a/src/renderer/shader.cpp b/src/renderer/shader.cpp index cdb8e9a9f..679931004 100644 --- a/src/renderer/shader.cpp +++ b/src/renderer/shader.cpp @@ -105,8 +105,8 @@ bool Shader::compileShader(GLuint *shader, GLenum type, const GLchar *source) { *shader = glCreateShader(type); -#if defined(EMSCRIPTEN) || defined(GL_ES_VERSION_2_0) - // Add WebGL GLSL / OpenGL ES precision premable +#if defined(GL_ES_VERSION_2_0) + // Add OpenGL ES precision premable const GLchar *preamble = "precision highp float;\n\n"; #else // Desktop GLSL From e382cab17dd399ef851a4a2800a11dd7b9a69c15 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Konstantin=20Ka=CC=88fer?= Date: Fri, 21 Feb 2014 13:08:13 +0100 Subject: [PATCH 31/37] make implicit type conversions explicit --- include/llmr/geometry/vertex_buffer.hpp | 2 +- include/llmr/renderer/fill_bucket.hpp | 6 +++--- include/llmr/renderer/line_bucket.hpp | 6 +++--- include/llmr/renderer/point_bucket.hpp | 4 ++-- include/llmr/style/style.hpp | 2 +- include/llmr/util/pbf.hpp | 4 ++-- src/geometry/debug_font_buffer.cpp | 4 ++-- src/geometry/vertex_buffer.cpp | 2 +- src/map/vector_tile.cpp | 4 ++-- src/renderer/fill_bucket.cpp | 2 +- src/renderer/line_bucket.cpp | 22 +++++++++++----------- src/renderer/painter.cpp | 16 ++++++++-------- src/renderer/point_bucket.cpp | 2 +- src/style/sprite.cpp | 2 +- src/style/style.cpp | 2 +- 15 files changed, 40 insertions(+), 40 deletions(-) diff --git a/include/llmr/geometry/vertex_buffer.hpp b/include/llmr/geometry/vertex_buffer.hpp index 9d053693c..a9236992c 100644 --- a/include/llmr/geometry/vertex_buffer.hpp +++ b/include/llmr/geometry/vertex_buffer.hpp @@ -17,7 +17,7 @@ public: * Returns the number of elements in this buffer. This is not the number of * bytes, but rather the number of coordinates with associated information. */ - uint32_t index() const; + size_t index() const; /* * Transfers this buffer to the GPU and binds the buffer to the GL context. diff --git a/include/llmr/renderer/fill_bucket.hpp b/include/llmr/renderer/fill_bucket.hpp index 86188e4c7..166eff3fa 100644 --- a/include/llmr/renderer/fill_bucket.hpp +++ b/include/llmr/renderer/fill_bucket.hpp @@ -52,9 +52,9 @@ private: std::shared_ptr lineElementsBuffer; // hold information on where the vertices are located in the FillBuffer - const uint32_t vertex_start; - const uint32_t triangle_elements_start; - const uint32_t line_elements_start; + const size_t vertex_start; + const size_t triangle_elements_start; + const size_t line_elements_start; VertexArrayObject array; std::vector triangleGroups; std::vector lineGroups; diff --git a/include/llmr/renderer/line_bucket.hpp b/include/llmr/renderer/line_bucket.hpp index 6ec9d960d..17ee226cf 100644 --- a/include/llmr/renderer/line_bucket.hpp +++ b/include/llmr/renderer/line_bucket.hpp @@ -47,9 +47,9 @@ private: std::shared_ptr triangleElementsBuffer; std::shared_ptr pointElementsBuffer; - const uint32_t vertex_start; - const uint32_t triangle_elements_start; - const uint32_t point_elements_start; + const size_t vertex_start; + const size_t triangle_elements_start; + const size_t point_elements_start; std::vector triangleGroups; std::vector pointGroups; diff --git a/include/llmr/renderer/point_bucket.hpp b/include/llmr/renderer/point_bucket.hpp index 9c8de8f88..9da7edc30 100644 --- a/include/llmr/renderer/point_bucket.hpp +++ b/include/llmr/renderer/point_bucket.hpp @@ -42,8 +42,8 @@ private: std::shared_ptr vertexBuffer; VertexArrayObject array; - const uint32_t vertex_start; - uint32_t vertex_end = 0; + const size_t vertex_start; + size_t vertex_end = 0; }; } diff --git a/include/llmr/style/style.hpp b/include/llmr/style/style.hpp index d1212f9fe..7a491d810 100644 --- a/include/llmr/style/style.hpp +++ b/include/llmr/style/style.hpp @@ -22,7 +22,7 @@ public: Style(); void reset(); - void load(const uint8_t *const data, uint32_t bytes); + void load(const uint8_t *const data, size_t bytes); // This is commented out because it is not fully implemented yet. For now, // we keep using the protobuf stylesheet format diff --git a/include/llmr/util/pbf.hpp b/include/llmr/util/pbf.hpp index 132cc1435..2e99cd91c 100644 --- a/include/llmr/util/pbf.hpp +++ b/include/llmr/util/pbf.hpp @@ -20,7 +20,7 @@ struct pbf { struct unknown_field_type_exception : exception {}; struct end_of_buffer_exception : exception {}; - inline pbf(const unsigned char *data, uint32_t length); + inline pbf(const unsigned char *data, size_t length); inline pbf(); inline operator bool() const; @@ -49,7 +49,7 @@ struct pbf { uint32_t tag = 0; }; -pbf::pbf(const unsigned char *data, uint32_t length) +pbf::pbf(const unsigned char *data, size_t length) : data(data), end(data + length), value(0), diff --git a/src/geometry/debug_font_buffer.cpp b/src/geometry/debug_font_buffer.cpp index 4db1aa285..a91865fb8 100644 --- a/src/geometry/debug_font_buffer.cpp +++ b/src/geometry/debug_font_buffer.cpp @@ -10,8 +10,8 @@ using namespace llmr; void DebugFontBuffer::addText(const char *text, double left, double baseline, double scale) { uint16_t *coords = nullptr; - int32_t length = strlen(text); - for (int32_t i = 0; i < length; ++i) { + size_t length = strlen(text); + for (size_t i = 0; i < length; ++i) { if (text[i] < 32 || text[i] > 127) { continue; } diff --git a/src/geometry/vertex_buffer.cpp b/src/geometry/vertex_buffer.cpp index 47fe73a2a..0ce21fd51 100644 --- a/src/geometry/vertex_buffer.cpp +++ b/src/geometry/vertex_buffer.cpp @@ -12,7 +12,7 @@ VertexBuffer::~VertexBuffer() { } } -uint32_t VertexBuffer::index() const { +size_t VertexBuffer::index() const { // We store 2 coordinates per vertex + 1 linesofar + 1 extrude coord pair == 4 (== 8 bytes) return array.size() / 2; } diff --git a/src/map/vector_tile.cpp b/src/map/vector_tile.cpp index e64d7114b..129ddd997 100644 --- a/src/map/vector_tile.cpp +++ b/src/map/vector_tile.cpp @@ -52,13 +52,13 @@ FilteredVectorTileLayer::FilteredVectorTileLayer(const VectorTileLayer& layer, c // Find out what key/value IDs we need. auto key_it = std::find(layer.keys.begin(), layer.keys.end(), bucket_desc.source_field); if (key_it != layer.keys.end()) { - key = key_it - layer.keys.begin(); + key = (int32_t)(key_it - layer.keys.begin()); } for (const Value& source_value : bucket_desc.source_value) { auto value_it = std::find(layer.values.begin(), layer.values.end(), source_value); if (value_it != layer.values.end()) { - values.insert(value_it - layer.values.begin()); + values.insert((uint32_t)(value_it - layer.values.begin())); } } } diff --git a/src/renderer/fill_bucket.cpp b/src/renderer/fill_bucket.cpp index 6270ef0e5..4420d3b97 100644 --- a/src/renderer/fill_bucket.cpp +++ b/src/renderer/fill_bucket.cpp @@ -50,7 +50,7 @@ void FillBucket::addGeometry(pbf& geom) { } void FillBucket::addGeometry(const std::vector& line) { - uint32_t vertex_start = vertexBuffer->index(); + size_t vertex_start = vertexBuffer->index(); size_t length = line.size(); diff --git a/src/renderer/line_bucket.cpp b/src/renderer/line_bucket.cpp index f24c42d5b..1ceb2cb0a 100644 --- a/src/renderer/line_bucket.cpp +++ b/src/renderer/line_bucket.cpp @@ -103,7 +103,7 @@ void LineBucket::addGeometry(const std::vector& vertices) { nextNormal = util::normal(currentVertex, lastVertex); } - size_t start_vertex = vertexBuffer->index(); + int32_t start_vertex = (int32_t)vertexBuffer->index(); std::vector triangle_store; std::vector point_store; @@ -174,7 +174,7 @@ void LineBucket::addGeometry(const std::vector& vertices) { // Add offset square begin cap. if (!prevVertex && beginCap == CapType::Square) { // Add first vertex - e3 = vertexBuffer->add(currentVertex.x, currentVertex.y, // vertex pos + e3 = (int32_t)vertexBuffer->add(currentVertex.x, currentVertex.y, // vertex pos flip * (prevNormal.x + prevNormal.y), flip * (-prevNormal.x + prevNormal.y), // extrude normal 0, 0, distance) - start_vertex; // texture normal @@ -182,7 +182,7 @@ void LineBucket::addGeometry(const std::vector& vertices) { e1 = e2; e2 = e3; // Add second vertex - e3 = vertexBuffer->add(currentVertex.x, currentVertex.y, // vertex pos + e3 = (int32_t)vertexBuffer->add(currentVertex.x, currentVertex.y, // vertex pos flip * (prevNormal.x - prevNormal.y), flip * (prevNormal.x + prevNormal.y), // extrude normal 0, 1, distance) - start_vertex; // texture normal @@ -193,7 +193,7 @@ void LineBucket::addGeometry(const std::vector& vertices) { // Add offset square end cap. else if (!nextVertex && endCap == CapType::Square) { // Add first vertex - e3 = vertexBuffer->add(currentVertex.x, currentVertex.y, // vertex pos + e3 = (int32_t)vertexBuffer->add(currentVertex.x, currentVertex.y, // vertex pos nextNormal.x - flip * nextNormal.y, flip * nextNormal.x + nextNormal.y, // extrude normal 0, 0, distance) - start_vertex; // texture normal @@ -201,7 +201,7 @@ void LineBucket::addGeometry(const std::vector& vertices) { e1 = e2; e2 = e3; // Add second vertex - e3 = vertexBuffer->add(currentVertex.x, currentVertex.y, // vertex pos + e3 = (int32_t)vertexBuffer->add(currentVertex.x, currentVertex.y, // vertex pos nextNormal.x + flip * nextNormal.y, -flip * nextNormal.x + nextNormal.y, // extrude normal 0, 1, distance) - start_vertex; // texture normal @@ -227,7 +227,7 @@ void LineBucket::addGeometry(const std::vector& vertices) { } // Add first vertex - e3 = vertexBuffer->add(currentVertex.x, currentVertex.y, // vertex pos + e3 = (int32_t)vertexBuffer->add(currentVertex.x, currentVertex.y, // vertex pos flip * joinNormal.x, flip * joinNormal.y, // extrude normal 0, 0, distance) - start_vertex; // texture normal @@ -235,7 +235,7 @@ void LineBucket::addGeometry(const std::vector& vertices) { e1 = e2; e2 = e3; // Add second vertex - e3 = vertexBuffer->add(currentVertex.x, currentVertex.y, // vertex pos + e3 = (int32_t)vertexBuffer->add(currentVertex.x, currentVertex.y, // vertex pos -flip * joinNormal.x, -flip * joinNormal.y, // extrude normal 0, 1, distance) - start_vertex; // texture normal @@ -251,7 +251,7 @@ void LineBucket::addGeometry(const std::vector& vertices) { else { // Close up the previous line // Add first vertex - e3 = vertexBuffer->add(currentVertex.x, currentVertex.y, // vertex pos + e3 = (int32_t)vertexBuffer->add(currentVertex.x, currentVertex.y, // vertex pos flip * prevNormal.y, -flip * prevNormal.x, // extrude normal 0, 0, distance) - start_vertex; // texture normal @@ -259,7 +259,7 @@ void LineBucket::addGeometry(const std::vector& vertices) { e1 = e2; e2 = e3; // Add second vertex. - e3 = vertexBuffer->add(currentVertex.x, currentVertex.y, // vertex pos + e3 = (int32_t)vertexBuffer->add(currentVertex.x, currentVertex.y, // vertex pos -flip * prevNormal.y, flip * prevNormal.x, // extrude normal 0, 1, distance) - start_vertex; // texture normal @@ -289,7 +289,7 @@ void LineBucket::addGeometry(const std::vector& vertices) { // Start the new quad. // Add first vertex - e3 = vertexBuffer->add(currentVertex.x, currentVertex.y, // vertex pos + e3 = (int32_t)vertexBuffer->add(currentVertex.x, currentVertex.y, // vertex pos -flip * nextNormal.y, flip * nextNormal.x, // extrude normal 0, 0, distance) - start_vertex; // texture normal @@ -297,7 +297,7 @@ void LineBucket::addGeometry(const std::vector& vertices) { e1 = e2; e2 = e3; // Add second vertex - e3 = vertexBuffer->add(currentVertex.x, currentVertex.y, // vertex pos + e3 = (int32_t)vertexBuffer->add(currentVertex.x, currentVertex.y, // vertex pos flip * nextNormal.y, -flip * nextNormal.x, // extrude normal 0, 1, distance) - start_vertex; // texture normal diff --git a/src/renderer/painter.cpp b/src/renderer/painter.cpp index 8d362ca29..83bf8d4d9 100644 --- a/src/renderer/painter.cpp +++ b/src/renderer/painter.cpp @@ -117,7 +117,7 @@ void Painter::drawClippingMask() { // Draw the clipping mask plainShader->setColor(1.0f, 0.0f, 1.0f, 1.0f); - glDrawArrays(GL_TRIANGLES, 0, tileStencilBuffer.index()); + glDrawArrays(GL_TRIANGLES, 0, (GLsizei)tileStencilBuffer.index()); // glEnable(GL_STENCIL_TEST); glStencilFunc(GL_EQUAL, 0x80, 0x80); @@ -287,7 +287,7 @@ void Painter::renderFill(FillBucket& bucket, const std::string& layer_name, cons // Draw a rectangle that covers the entire viewport. coveringPatternArray.bind(*patternShader, tileStencilBuffer, BUFFER_OFFSET(0)); - glDrawArrays(GL_TRIANGLES, 0, tileStencilBuffer.index()); + glDrawArrays(GL_TRIANGLES, 0, (GLsizei)tileStencilBuffer.index()); } else { // Draw filling rectangle. @@ -297,7 +297,7 @@ void Painter::renderFill(FillBucket& bucket, const std::string& layer_name, cons // Draw a rectangle that covers the entire viewport. coveringPlainArray.bind(*plainShader, tileStencilBuffer, BUFFER_OFFSET(0)); - glDrawArrays(GL_TRIANGLES, 0, tileStencilBuffer.index()); + glDrawArrays(GL_TRIANGLES, 0, (GLsizei)tileStencilBuffer.index()); } glStencilFunc(GL_EQUAL, 0x80, 0x80); @@ -428,16 +428,16 @@ void Painter::renderDebug(const Tile::Ptr& tile) { tileBorderArray.bind(*plainShader, tileBorderBuffer, BUFFER_OFFSET(0)); plainShader->setColor(1.0f, 0.0f, 0.0f, 1.0f); lineWidth(4.0f * transform.pixelRatio); - glDrawArrays(GL_LINE_STRIP, 0, tileBorderBuffer.index()); + glDrawArrays(GL_LINE_STRIP, 0, (GLsizei)tileBorderBuffer.index()); // draw debug info tile->debugFontArray.bind(*plainShader, tile->debugFontBuffer, BUFFER_OFFSET(0)); plainShader->setColor(1.0f, 1.0f, 1.0f, 1.0f); lineWidth(4.0f * transform.pixelRatio); - glDrawArrays(GL_LINES, 0, tile->debugFontBuffer.index()); + glDrawArrays(GL_LINES, 0, (GLsizei)tile->debugFontBuffer.index()); plainShader->setColor(0.0f, 0.0f, 0.0f, 1.0f); lineWidth(2.0f * transform.pixelRatio); - glDrawArrays(GL_LINES, 0, tile->debugFontBuffer.index()); + glDrawArrays(GL_LINES, 0, (GLsizei)tile->debugFontBuffer.index()); // Revert blending mode to blend to the back. glBlendFunc(GL_ONE_MINUS_DST_ALPHA, GL_ONE); @@ -454,7 +454,7 @@ void Painter::renderMatte() { // Draw the clipping mask matteArray.bind(*plainShader, matteBuffer, BUFFER_OFFSET(0)); plainShader->setColor(white); - glDrawArrays(GL_TRIANGLES, 0, matteBuffer.index()); + glDrawArrays(GL_TRIANGLES, 0, (GLsizei)matteBuffer.index()); glEnable(GL_STENCIL_TEST); } @@ -468,5 +468,5 @@ void Painter::renderBackground() { // Draw the clipping mask coveringPlainArray.bind(*plainShader, tileStencilBuffer, BUFFER_OFFSET(0)); plainShader->setColor(white); - glDrawArrays(GL_TRIANGLES, 0, tileStencilBuffer.index()); + glDrawArrays(GL_TRIANGLES, 0, (GLsizei)tileStencilBuffer.index()); } diff --git a/src/renderer/point_bucket.cpp b/src/renderer/point_bucket.cpp index 1f786a0cb..04e9fbe9d 100644 --- a/src/renderer/point_bucket.cpp +++ b/src/renderer/point_bucket.cpp @@ -48,5 +48,5 @@ bool PointBucket::hasPoints() const { void PointBucket::drawPoints(PointShader& shader) { char *vertex_index = BUFFER_OFFSET(vertex_start * vertexBuffer->itemSize); array.bind(shader, *vertexBuffer, vertex_index); - glDrawArrays(GL_POINTS, 0, vertex_end - vertex_start); + glDrawArrays(GL_POINTS, 0, (GLsizei)(vertex_end - vertex_start)); } diff --git a/src/style/sprite.cpp b/src/style/sprite.cpp index dcdfd0cb6..70626ef39 100644 --- a/src/style/sprite.cpp +++ b/src/style/sprite.cpp @@ -180,7 +180,7 @@ void Sprite::loadImage(const std::string& data) { png_read_update_info(png, info); - unsigned int rowbytes = png_get_rowbytes(png, info); + png_size_t rowbytes = png_get_rowbytes(png, info); assert(width * 4 == rowbytes); img = (char *)malloc(width * height * 4); diff --git a/src/style/style.cpp b/src/style/style.cpp index 2aac0c384..28e740e4c 100644 --- a/src/style/style.cpp +++ b/src/style/style.cpp @@ -15,7 +15,7 @@ void Style::reset() { computed.points.clear(); } -void Style::load(const uint8_t *const data, uint32_t bytes) { +void Style::load(const uint8_t *const data, size_t bytes) { pbf style(data, bytes); while (style.next()) { From 54735ddd9ee1c4f3403392bbacc9dc56c9d73995 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Konstantin=20Ka=CC=88fer?= Date: Fri, 21 Feb 2014 13:08:25 +0100 Subject: [PATCH 32/37] rename -osx project to -x86 --- Makefile | 2 +- linux/llmr-app.gyp | 2 +- llmr.gyp | 4 ++-- macosx/llmr-app.gyp | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Makefile b/Makefile index 0586f6017..854b5fb81 100644 --- a/Makefile +++ b/Makefile @@ -7,7 +7,7 @@ V ?= 1 all: llmr llmr: config.gypi src llmr.gyp - $(MAKE) -C out BUILDTYPE=Release V=$(V) llmr-osx + $(MAKE) -C out BUILDTYPE=Release V=$(V) llmr-x86 # build OS X app with pure make app: config.gypi src macosx/llmr-app.gyp diff --git a/linux/llmr-app.gyp b/linux/llmr-app.gyp index 40b8c76ec..06d7ed822 100644 --- a/linux/llmr-app.gyp +++ b/linux/llmr-app.gyp @@ -25,7 +25,7 @@ '<@(glfw3_cflags)' ], "dependencies": [ - "../llmr.gyp:llmr-osx" + "../llmr.gyp:llmr-x86" ] } ] diff --git a/llmr.gyp b/llmr.gyp index bd94746fa..d6e4c71c6 100644 --- a/llmr.gyp +++ b/llmr.gyp @@ -5,8 +5,8 @@ ], 'targets': [ { - 'target_name': 'llmr-osx', - 'product_name': 'llmr-osx', + 'target_name': 'llmr-x86', + 'product_name': 'llmr-x86', 'type': 'static_library', 'sources': [ ' Date: Fri, 21 Feb 2014 13:12:31 +0100 Subject: [PATCH 33/37] add missing include for size_t --- include/llmr/geometry/vertex_buffer.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/include/llmr/geometry/vertex_buffer.hpp b/include/llmr/geometry/vertex_buffer.hpp index a9236992c..9478d7b15 100644 --- a/include/llmr/geometry/vertex_buffer.hpp +++ b/include/llmr/geometry/vertex_buffer.hpp @@ -2,6 +2,7 @@ #define LLMR_GEOMETRY_VERTEX_BUFFER #include +#include #include #include From 495d47ab422988053666c0d3d647e3e235fa21e3 Mon Sep 17 00:00:00 2001 From: "Justin R. Miller" Date: Fri, 21 Feb 2014 16:00:01 -0800 Subject: [PATCH 34/37] refs #60: add some more point styles --- bin/style.js | 77 +++++++++++++++++++++++++++++++++++++++----- resources/style.pbf | Bin 1090 -> 1622 bytes 2 files changed, 69 insertions(+), 8 deletions(-) diff --git a/bin/style.js b/bin/style.js index 0383c3210..7675f101e 100644 --- a/bin/style.js +++ b/bin/style.js @@ -52,13 +52,41 @@ module.exports = { "layer": "building", "type": "fill" }, - "alcohol": { + "alcohol_poi": { "datasource": "streets", "layer": "poi_label", "field": "type", "value": ["Alcohol"], "type": "point" - } + }, + "cafe_poi": { + "datasource": "streets", + "layer": "poi_label", + "field": "type", + "value": ["Cafe"], + "type": "point" + }, + "embassy_poi": { + "datasource": "streets", + "layer": "poi_label", + "field": "type", + "value": ["Embassy"], + "type": "point" + }, + "park_poi": { + "datasource": "streets", + "layer": "poi_label", + "field": "type", + "value": ["Park"], + "type": "point" + }, + "restaurant_poi": { + "datasource": "streets", + "layer": "poi_label", + "field": "type", + "value": ["Restaurant"], + "type": "point" + }, }, "sprite": "img/maki-sprite", "structure": [ @@ -69,7 +97,11 @@ module.exports = { { "name": "road_limited", "bucket": "road_limited" }, { "name": "road_regular", "bucket": "road_regular" }, { "name": "road_large", "bucket": "road_large" }, - { "name": "alcohol", "bucket": "alcohol" } + { "name": "alcohol_poi", "bucket": "alcohol_poi" }, + { "name": "cafe_poi", "bucket": "cafe_poi" }, + { "name": "embassy_poi", "bucket": "embassy_poi" }, + { "name": "park_poi", "bucket": "park_poi" }, + { "name": "restaurant_poi", "bucket": "restaurant_poi" }, ], "classes": [ { @@ -138,12 +170,41 @@ module.exports = { { z: 30, val: 64 } ], }, - "alcohol": { + "alcohol_poi": { "type": "marker", - "color": "#999999", - "size": 24, - "image": "alcohol-shop" - } + "color": "#cccccc", + "size": 18, + "image": "alcohol-shop", + "opacity": 0.75 + }, + "cafe_poi": { + "type": "marker", + "color": "#cccccc", + "size": 18, + "image": "cafe", + "opacity": 0.75 + }, + "embassy_poi": { + "type": "marker", + "color": "#cccccc", + "size": 18, + "image": "embassy", + "opacity": 0.75 + }, + "park_poi": { + "type": "marker", + "color": "#cccccc", + "size": 18, + "image": "park", + "opacity": 0.75 + }, + "restaurant_poi": { + "type": "marker", + "color": "#cccccc", + "size": 18, + "image": "restaurant", + "opacity": 0.75 + }, } } ] diff --git a/resources/style.pbf b/resources/style.pbf index 46e117e52dcff7d78ee2fbec60fb4842abc611c5..6823fc7b813619ba42f38beb845537d3cc2b5f80 100644 GIT binary patch delta 530 zcmX@aagArgJw`qgF7CvfLoFRnlCLs}obA;dy69Vc$a*PlP2dD$)8X*Kr0o^S^aJO+n94B>wW%E9!SjKwP zP?7zA=FAx-4h|+E76yh1jz&Pe8{Fh8LyN2q22DN!;-_b6@+T!`2K0LuEJ_5c6? delta 105 zcmcb{bBJTZJw`4AF80KnK|>LU36jm@=sr=FMy@v5e|! fa5>rkGiT0J;^1HsVqsu7;ON8yHBq-XBfkIuz#$-x From b6d7169b831e07fd7e1d0d9507c8cfe28a5a220d Mon Sep 17 00:00:00 2001 From: "Justin R. Miller" Date: Fri, 21 Feb 2014 16:00:55 -0800 Subject: [PATCH 35/37] refs #60: add support for point colorization & opacity --- src/shader/point.fragment.glsl | 2 +- src/shader/shaders.cpp | 2 +- src/style/resources.cpp | 113 +++++++++++++++++++++------------ 3 files changed, 75 insertions(+), 42 deletions(-) diff --git a/src/shader/point.fragment.glsl b/src/shader/point.fragment.glsl index 2343f7db0..2f099feb7 100644 --- a/src/shader/point.fragment.glsl +++ b/src/shader/point.fragment.glsl @@ -17,5 +17,5 @@ void main() { vec4 color = texture2D(u_image, mix(u_tl, u_br, pos)) * inbounds; - gl_FragColor = color; + gl_FragColor = color * u_color; } diff --git a/src/shader/shaders.cpp b/src/shader/shaders.cpp index b6ee1b46b..638c554cf 100644 --- a/src/shader/shaders.cpp +++ b/src/shader/shaders.cpp @@ -26,6 +26,6 @@ const shader_source llmr::shaders[SHADER_COUNT] = { }, { "attribute vec2 a_pos;\n\nuniform mat4 u_matrix;\nuniform float u_size;\n\nvoid main() {\n gl_Position = u_matrix * vec4(a_pos, 0, 1);\n gl_PointSize = u_size;\n}\n", - "#define root2 1.4142135623730951\n\nuniform sampler2D u_image;\nuniform vec2 u_tl;\nuniform vec2 u_br;\nuniform vec4 u_color;\n\nuniform vec2 pos;\nuniform float inbounds;\nuniform vec4 color;\n\nvoid main() {\n vec2 pos = (gl_PointCoord * 2.0 - 1.0) * root2 / 2.0 + 0.5;\n\n float inbounds = step(0.0, pos.x) * step(0.0, pos.y) *\n (1.0 - step(1.0, pos.x)) * (1.0 - step(1.0, pos.y));\n\n vec4 color = texture2D(u_image, mix(u_tl, u_br, pos)) * inbounds;\n\n gl_FragColor = color;\n}\n", + "#define root2 1.4142135623730951\n\nuniform sampler2D u_image;\nuniform vec2 u_tl;\nuniform vec2 u_br;\nuniform vec4 u_color;\n\nuniform vec2 pos;\nuniform float inbounds;\nuniform vec4 color;\n\nvoid main() {\n vec2 pos = (gl_PointCoord * 2.0 - 1.0) * root2 / 2.0 + 0.5;\n\n float inbounds = step(0.0, pos.x) * step(0.0, pos.y) *\n (1.0 - step(1.0, pos.x)) * (1.0 - step(1.0, pos.y));\n\n vec4 color = texture2D(u_image, mix(u_tl, u_br, pos)) * inbounds;\n\n gl_FragColor = color * u_color;\n}\n", } }; diff --git a/src/style/resources.cpp b/src/style/resources.cpp index bf0eb207e..1b819223b 100644 --- a/src/style/resources.cpp +++ b/src/style/resources.cpp @@ -33,45 +33,78 @@ const unsigned char resources::style[] = { 108, 97, 110, 100, 117, 115, 101, 42, 5, 99, 108, 97, 115, 115, 50, 12, 10, 10, 105, 110, 100, 117, 115, 116, 114, 105, 97, 108, 10, 31, 10, 8, 98, 117, 105, 108, 100, 105, 110, 103, 16, 1, 26, 7, 115, 116, 114, 101, - 101, 116, 115, 34, 8, 98, 117, 105, 108, 100, 105, 110, 103, 10, 48, 10, - 7, 97, 108, 99, 111, 104, 111, 108, 16, 3, 26, 7, 115, 116, 114, 101, - 101, 116, 115, 34, 9, 112, 111, 105, 95, 108, 97, 98, 101, 108, 42, 4, - 116, 121, 112, 101, 50, 9, 10, 7, 65, 108, 99, 111, 104, 111, 108, 18, - 12, 10, 4, 112, 97, 114, 107, 18, 4, 112, 97, 114, 107, 18, 12, 10, - 4, 119, 111, 111, 100, 18, 4, 119, 111, 111, 100, 18, 14, 10, 5, 119, - 97, 116, 101, 114, 18, 5, 119, 97, 116, 101, 114, 18, 20, 10, 8, 98, - 117, 105, 108, 100, 105, 110, 103, 18, 8, 98, 117, 105, 108, 100, 105, 110, - 103, 18, 28, 10, 12, 114, 111, 97, 100, 95, 108, 105, 109, 105, 116, 101, - 100, 18, 12, 114, 111, 97, 100, 95, 108, 105, 109, 105, 116, 101, 100, 18, - 28, 10, 12, 114, 111, 97, 100, 95, 114, 101, 103, 117, 108, 97, 114, 18, - 12, 114, 111, 97, 100, 95, 114, 101, 103, 117, 108, 97, 114, 18, 24, 10, - 10, 114, 111, 97, 100, 95, 108, 97, 114, 103, 101, 18, 10, 114, 111, 97, - 100, 95, 108, 97, 114, 103, 101, 18, 18, 10, 7, 97, 108, 99, 111, 104, - 111, 108, 18, 7, 97, 108, 99, 111, 104, 111, 108, 26, 132, 3, 10, 7, - 100, 101, 102, 97, 117, 108, 116, 18, 27, 10, 4, 112, 97, 114, 107, 34, - 8, 8, 2, 18, 4, 0, 0, 128, 63, 45, 255, 159, 223, 200, 66, 4, - 112, 97, 114, 107, 18, 31, 10, 4, 119, 111, 111, 100, 34, 8, 8, 2, - 18, 4, 0, 0, 128, 63, 45, 255, 102, 170, 51, 58, 8, 8, 2, 18, - 4, 205, 204, 204, 61, 18, 39, 10, 5, 119, 97, 116, 101, 114, 34, 8, - 8, 2, 18, 4, 0, 0, 128, 63, 45, 255, 233, 224, 186, 53, 255, 230, - 182, 115, 66, 10, 119, 97, 116, 101, 114, 95, 101, 116, 115, 121, 18, 51, - 10, 8, 98, 117, 105, 108, 100, 105, 110, 103, 34, 8, 8, 2, 18, 4, - 0, 0, 128, 63, 45, 255, 0, 0, 0, 58, 24, 8, 4, 18, 20, 0, - 0, 80, 65, 0, 0, 0, 0, 205, 204, 204, 61, 0, 0, 0, 0, 205, - 204, 204, 61, 26, 41, 10, 12, 114, 111, 97, 100, 95, 108, 105, 109, 105, - 116, 101, 100, 29, 255, 187, 187, 187, 34, 20, 8, 3, 18, 16, 0, 0, - 0, 0, 0, 0, 128, 63, 0, 0, 240, 65, 0, 0, 128, 63, 26, 65, - 10, 12, 114, 111, 97, 100, 95, 114, 101, 103, 117, 108, 97, 114, 29, 255, - 153, 153, 153, 34, 44, 8, 3, 18, 40, 0, 0, 0, 0, 0, 0, 0, - 63, 0, 0, 80, 65, 0, 0, 0, 63, 0, 0, 128, 65, 0, 0, 0, - 64, 0, 0, 160, 65, 0, 0, 0, 66, 0, 0, 240, 65, 0, 0, 0, - 66, 26, 71, 10, 10, 114, 111, 97, 100, 95, 108, 97, 114, 103, 101, 29, - 255, 102, 102, 102, 34, 52, 8, 3, 18, 48, 0, 0, 0, 0, 0, 0, - 0, 63, 0, 0, 48, 65, 0, 0, 0, 63, 0, 0, 80, 65, 0, 0, - 128, 63, 0, 0, 128, 65, 0, 0, 128, 64, 0, 0, 160, 65, 0, 0, - 128, 66, 0, 0, 240, 65, 0, 0, 128, 66, 34, 38, 10, 7, 97, 108, - 99, 111, 104, 111, 108, 29, 255, 153, 153, 153, 34, 8, 8, 2, 18, 4, - 0, 0, 192, 65, 66, 12, 97, 108, 99, 111, 104, 111, 108, 45, 115, 104, - 111, 112 + 101, 116, 115, 34, 8, 98, 117, 105, 108, 100, 105, 110, 103, 10, 52, 10, + 11, 97, 108, 99, 111, 104, 111, 108, 95, 112, 111, 105, 16, 3, 26, 7, + 115, 116, 114, 101, 101, 116, 115, 34, 9, 112, 111, 105, 95, 108, 97, 98, + 101, 108, 42, 4, 116, 121, 112, 101, 50, 9, 10, 7, 65, 108, 99, 111, + 104, 111, 108, 10, 46, 10, 8, 99, 97, 102, 101, 95, 112, 111, 105, 16, + 3, 26, 7, 115, 116, 114, 101, 101, 116, 115, 34, 9, 112, 111, 105, 95, + 108, 97, 98, 101, 108, 42, 4, 116, 121, 112, 101, 50, 6, 10, 4, 67, + 97, 102, 101, 10, 52, 10, 11, 101, 109, 98, 97, 115, 115, 121, 95, 112, + 111, 105, 16, 3, 26, 7, 115, 116, 114, 101, 101, 116, 115, 34, 9, 112, + 111, 105, 95, 108, 97, 98, 101, 108, 42, 4, 116, 121, 112, 101, 50, 9, + 10, 7, 69, 109, 98, 97, 115, 115, 121, 10, 46, 10, 8, 112, 97, 114, + 107, 95, 112, 111, 105, 16, 3, 26, 7, 115, 116, 114, 101, 101, 116, 115, + 34, 9, 112, 111, 105, 95, 108, 97, 98, 101, 108, 42, 4, 116, 121, 112, + 101, 50, 6, 10, 4, 80, 97, 114, 107, 10, 58, 10, 14, 114, 101, 115, + 116, 97, 117, 114, 97, 110, 116, 95, 112, 111, 105, 16, 3, 26, 7, 115, + 116, 114, 101, 101, 116, 115, 34, 9, 112, 111, 105, 95, 108, 97, 98, 101, + 108, 42, 4, 116, 121, 112, 101, 50, 12, 10, 10, 82, 101, 115, 116, 97, + 117, 114, 97, 110, 116, 18, 12, 10, 4, 112, 97, 114, 107, 18, 4, 112, + 97, 114, 107, 18, 12, 10, 4, 119, 111, 111, 100, 18, 4, 119, 111, 111, + 100, 18, 14, 10, 5, 119, 97, 116, 101, 114, 18, 5, 119, 97, 116, 101, + 114, 18, 20, 10, 8, 98, 117, 105, 108, 100, 105, 110, 103, 18, 8, 98, + 117, 105, 108, 100, 105, 110, 103, 18, 28, 10, 12, 114, 111, 97, 100, 95, + 108, 105, 109, 105, 116, 101, 100, 18, 12, 114, 111, 97, 100, 95, 108, 105, + 109, 105, 116, 101, 100, 18, 28, 10, 12, 114, 111, 97, 100, 95, 114, 101, + 103, 117, 108, 97, 114, 18, 12, 114, 111, 97, 100, 95, 114, 101, 103, 117, + 108, 97, 114, 18, 24, 10, 10, 114, 111, 97, 100, 95, 108, 97, 114, 103, + 101, 18, 10, 114, 111, 97, 100, 95, 108, 97, 114, 103, 101, 18, 26, 10, + 11, 97, 108, 99, 111, 104, 111, 108, 95, 112, 111, 105, 18, 11, 97, 108, + 99, 111, 104, 111, 108, 95, 112, 111, 105, 18, 20, 10, 8, 99, 97, 102, + 101, 95, 112, 111, 105, 18, 8, 99, 97, 102, 101, 95, 112, 111, 105, 18, + 26, 10, 11, 101, 109, 98, 97, 115, 115, 121, 95, 112, 111, 105, 18, 11, + 101, 109, 98, 97, 115, 115, 121, 95, 112, 111, 105, 18, 20, 10, 8, 112, + 97, 114, 107, 95, 112, 111, 105, 18, 8, 112, 97, 114, 107, 95, 112, 111, + 105, 18, 32, 10, 14, 114, 101, 115, 116, 97, 117, 114, 97, 110, 116, 95, + 112, 111, 105, 18, 14, 114, 101, 115, 116, 97, 117, 114, 97, 110, 116, 95, + 112, 111, 105, 26, 208, 4, 10, 7, 100, 101, 102, 97, 117, 108, 116, 18, + 27, 10, 4, 112, 97, 114, 107, 34, 8, 8, 2, 18, 4, 0, 0, 128, + 63, 45, 255, 159, 223, 200, 66, 4, 112, 97, 114, 107, 18, 31, 10, 4, + 119, 111, 111, 100, 34, 8, 8, 2, 18, 4, 0, 0, 128, 63, 45, 255, + 102, 170, 51, 58, 8, 8, 2, 18, 4, 205, 204, 204, 61, 18, 39, 10, + 5, 119, 97, 116, 101, 114, 34, 8, 8, 2, 18, 4, 0, 0, 128, 63, + 45, 255, 233, 224, 186, 53, 255, 230, 182, 115, 66, 10, 119, 97, 116, 101, + 114, 95, 101, 116, 115, 121, 18, 51, 10, 8, 98, 117, 105, 108, 100, 105, + 110, 103, 34, 8, 8, 2, 18, 4, 0, 0, 128, 63, 45, 255, 0, 0, + 0, 58, 24, 8, 4, 18, 20, 0, 0, 80, 65, 0, 0, 0, 0, 205, + 204, 204, 61, 0, 0, 0, 0, 205, 204, 204, 61, 26, 41, 10, 12, 114, + 111, 97, 100, 95, 108, 105, 109, 105, 116, 101, 100, 29, 255, 187, 187, 187, + 34, 20, 8, 3, 18, 16, 0, 0, 0, 0, 0, 0, 128, 63, 0, 0, + 240, 65, 0, 0, 128, 63, 26, 65, 10, 12, 114, 111, 97, 100, 95, 114, + 101, 103, 117, 108, 97, 114, 29, 255, 153, 153, 153, 34, 44, 8, 3, 18, + 40, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 80, 65, 0, 0, 0, + 63, 0, 0, 128, 65, 0, 0, 0, 64, 0, 0, 160, 65, 0, 0, 0, + 66, 0, 0, 240, 65, 0, 0, 0, 66, 26, 71, 10, 10, 114, 111, 97, + 100, 95, 108, 97, 114, 103, 101, 29, 255, 102, 102, 102, 34, 52, 8, 3, + 18, 48, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 48, 65, 0, 0, + 0, 63, 0, 0, 80, 65, 0, 0, 128, 63, 0, 0, 128, 65, 0, 0, + 128, 64, 0, 0, 160, 65, 0, 0, 128, 66, 0, 0, 240, 65, 0, 0, + 128, 66, 34, 52, 10, 11, 97, 108, 99, 111, 104, 111, 108, 95, 112, 111, + 105, 29, 255, 204, 204, 204, 34, 8, 8, 2, 18, 4, 0, 0, 144, 65, + 50, 8, 8, 2, 18, 4, 0, 0, 64, 63, 66, 12, 97, 108, 99, 111, + 104, 111, 108, 45, 115, 104, 111, 112, 34, 41, 10, 8, 99, 97, 102, 101, + 95, 112, 111, 105, 29, 255, 204, 204, 204, 34, 8, 8, 2, 18, 4, 0, + 0, 144, 65, 50, 8, 8, 2, 18, 4, 0, 0, 64, 63, 66, 4, 99, + 97, 102, 101, 34, 47, 10, 11, 101, 109, 98, 97, 115, 115, 121, 95, 112, + 111, 105, 29, 255, 204, 204, 204, 34, 8, 8, 2, 18, 4, 0, 0, 144, + 65, 50, 8, 8, 2, 18, 4, 0, 0, 64, 63, 66, 7, 101, 109, 98, + 97, 115, 115, 121, 34, 41, 10, 8, 112, 97, 114, 107, 95, 112, 111, 105, + 29, 255, 204, 204, 204, 34, 8, 8, 2, 18, 4, 0, 0, 144, 65, 50, + 8, 8, 2, 18, 4, 0, 0, 64, 63, 66, 4, 112, 97, 114, 107, 34, + 53, 10, 14, 114, 101, 115, 116, 97, 117, 114, 97, 110, 116, 95, 112, 111, + 105, 29, 255, 204, 204, 204, 34, 8, 8, 2, 18, 4, 0, 0, 144, 65, + 50, 8, 8, 2, 18, 4, 0, 0, 64, 63, 66, 10, 114, 101, 115, 116, + 97, 117, 114, 97, 110, 116 }; const unsigned long resources::style_size = sizeof(resources::style); From 7a48e8ddce1261c94ef2e9a0527e4d1eadadae21 Mon Sep 17 00:00:00 2001 From: "Justin R. Miller" Date: Fri, 21 Feb 2014 16:22:45 -0800 Subject: [PATCH 36/37] move to linear properties for POI opacity --- bin/style.js | 10 +++++----- resources/style.pbf | Bin 1622 -> 1702 bytes src/style/resources.cpp | 27 ++++++++++++++++----------- 3 files changed, 21 insertions(+), 16 deletions(-) diff --git a/bin/style.js b/bin/style.js index 7675f101e..50b365c1d 100644 --- a/bin/style.js +++ b/bin/style.js @@ -175,35 +175,35 @@ module.exports = { "color": "#cccccc", "size": 18, "image": "alcohol-shop", - "opacity": 0.75 + "opacity": [ "linear", 15, 0, 1.0, 0, 0.75 ] }, "cafe_poi": { "type": "marker", "color": "#cccccc", "size": 18, "image": "cafe", - "opacity": 0.75 + "opacity": [ "linear", 15, 0, 1.0, 0, 0.75 ] }, "embassy_poi": { "type": "marker", "color": "#cccccc", "size": 18, "image": "embassy", - "opacity": 0.75 + "opacity": [ "linear", 15, 0, 1.0, 0, 0.75 ] }, "park_poi": { "type": "marker", "color": "#cccccc", "size": 18, "image": "park", - "opacity": 0.75 + "opacity": [ "linear", 15, 0, 1.0, 0, 0.75 ] }, "restaurant_poi": { "type": "marker", "color": "#cccccc", "size": 18, "image": "restaurant", - "opacity": 0.75 + "opacity": [ "linear", 15, 0, 1.0, 0, 0.75 ] }, } } diff --git a/resources/style.pbf b/resources/style.pbf index 6823fc7b813619ba42f38beb845537d3cc2b5f80..0cec5c89254ea3012d00fdf05a51de8d0d3f0a8f 100644 GIT binary patch delta 246 zcmcb{vy68G3k%Z%*3E1zv5Z_UT-=E{$@v-iIg=N#ifBr3un37TFcdg4fI)*jgm$oZ z;(;pDEzZa)sdFgO4J delta 166 zcmZ3+dyQuU3k%Z)md$J|v5Z_MT-=E{$@v-iIg>ZAib!&BFbT0RFgVyd@j!)ji!<^I zlr$%=VwI9Y$g(6Srll(Bb8)BUCM6aZSAsMnNwY(Rl{C3H3KEO5LDGUqx Date: Fri, 21 Feb 2014 16:25:42 -0800 Subject: [PATCH 37/37] refs #60: size POIs properly based on pixel ratio --- src/renderer/painter.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/renderer/painter.cpp b/src/renderer/painter.cpp index 83bf8d4d9..d1ab26389 100644 --- a/src/renderer/painter.cpp +++ b/src/renderer/painter.cpp @@ -405,7 +405,7 @@ void Painter::renderPoint(PointBucket& bucket, const std::string& layer_name, co pointShader->setMatrix(matrix); pointShader->setImage(0); pointShader->setColor(color); - const float pointSize = properties.size * 1.4142135623730951; + const float pointSize = properties.size * 1.4142135623730951 * transform.pixelRatio; #if defined(GL_ES_VERSION_2_0) pointShader->setSize(pointSize); #else