encode icon texture coordinate in buffer so we can render all pois with 1 draw call

This commit is contained in:
Konstantin Käfer
2014-05-15 17:19:14 +02:00
parent 264bcd34d9
commit 27f8ed29e4
22 changed files with 120 additions and 253 deletions

View File

@@ -452,116 +452,13 @@ module.exports = {
"feature_type": "point",
"type": "text"
},
"poi_airport": {
"poi": {
"source": "mapbox streets",
"layer": "poi_label",
"field": "maki",
"value": "airport",
"size": {
"x": 12,
"y": 12
},
"icon": "maki",
"size": 12,
"type": "point"
},
"poi_rail": {
"source": "mapbox streets",
"layer": "poi_label",
"field": "maki",
"value": "rail",
"size": {
"x": 12,
"y": 12
},
"type": "point"
},
"poi_fire_station": {
"source": "mapbox streets",
"layer": "poi_label",
"field": "maki",
"value": "fire-station",
"size": {
"x": 12,
"y": 12
},
"type": "point"
},
"poi_bus": {
"source": "mapbox streets",
"layer": "poi_label",
"field": "maki",
"value": "bus",
"size": {
"x": 12,
"y": 12
},
"type": "point"
},
"poi_restaurant": {
"source": "mapbox streets",
"layer": "poi_label",
"field": "maki",
"value": "restaurant",
"size": {
"x": 12,
"y": 12
},
"type": "point"
},
"poi_park": {
"source": "mapbox streets",
"layer": "poi_label",
"field": "maki",
"value": "park",
"size": {
"x": 12,
"y": 12
},
"type": "point"
},
"poi_playground": {
"source": "mapbox streets",
"layer": "poi_label",
"field": "maki",
"value": "playground",
"size": {
"x": 12,
"y": 12
},
"type": "point"
},
"poi_hospital": {
"source": "mapbox streets",
"layer": "poi_label",
"field": "maki",
"value": "hospital",
"size": {
"x": 12,
"y": 12
},
"type": "point"
},
"poi_cafe": {
"source": "mapbox streets",
"layer": "poi_label",
"field": "maki",
"value": "cafe",
"size": {
"x": 12,
"y": 12
},
"type": "point"
},
"poi_beer": {
"source": "mapbox streets",
"layer": "poi_label",
"field": "maki",
"value": "beer",
"size": {
"x": 12,
"y": 12
},
"type": "point"
}
},
"constants": {
"land": "#f8f4f0",
@@ -801,42 +698,12 @@ module.exports = {
}, {
"name": "road_label",
"bucket": "road_label"
}, {
"name": "poi_label",
"bucket": "poi_label"
}, {
"name": "water_label",
"bucket": "water_label"
}, {
"name": "poi_airport",
"bucket": "poi_airport"
}, {
"name": "poi_rail",
"bucket": "poi_rail"
}, {
"name": "poi_bus",
"bucket": "poi_bus"
}, {
"name": "poi_fire_station",
"bucket": "poi_fire_station"
}, {
"name": "poi_restaurant",
"bucket": "poi_restaurant"
}, {
"name": "poi_park",
"bucket": "poi_park"
}, {
"name": "poi_hospital",
"bucket": "poi_hospital"
}, {
"name": "poi_playground",
"bucket": "poi_playground"
}, {
"name": "poi_cafe",
"bucket": "poi_cafe"
}, {
"name": "poi_beer",
"bucket": "poi_beer"
"name": "poi",
"bucket": "poi"
}],
"classes": [{
"name": "default",
@@ -2010,45 +1877,8 @@ module.exports = {
0.75
],
},
"poi_airport": {
"poi": {
"color": "maki",
"image": "airport-12",
},
"poi_restaurant": {
"color": "maki",
"image": "restaurant-12",
},
"poi_bus": {
"color": "maki",
"image": "bus-12",
},
"poi_rail": {
"color": "maki",
"image": "rail-12",
},
"poi_fire_station": {
"color": "maki",
"image": "fire-station-12",
},
"poi_park": {
"color": "maki",
"image": "park-12",
},
"poi_hospital": {
"color": "maki",
"image": "hospital-12",
},
"poi_playground": {
"color": "maki",
"image": "playground-12",
},
"poi_cafe": {
"color": "maki",
"image": "cafe-12",
},
"poi_beer": {
"color": "maki",
"image": "beer-12",
},
"satellite": {
"type": "raster",

View File

@@ -11,15 +11,13 @@ namespace llmr {
template <
size_t item_size,
int bufferType = GL_ARRAY_BUFFER,
size_t defaultLength = 8192
size_t defaultLength = 8192,
bool retainAfterUpload = false
>
class Buffer : private util::noncopyable {
public:
~Buffer() {
if (array) {
free(array);
array = nullptr;
}
cleanup();
if (buffer != 0) {
glDeleteBuffers(1, &buffer);
buffer = 0;
@@ -33,18 +31,27 @@ public:
}
// Transfers this buffer to the GPU and binds the buffer to the GL context.
void bind() {
void bind(bool force = false) {
if (buffer == 0) {
glGenBuffers(1, &buffer);
glBindBuffer(bufferType, buffer);
force = true;
}
glBindBuffer(bufferType, buffer);
if (force) {
assert("Buffer was already deleted" && array != nullptr);
glBufferData(bufferType, pos, array, GL_STATIC_DRAW);
free(array);
array = nullptr;
} else {
glBindBuffer(bufferType, buffer);
if (!retainAfterUpload) {
cleanup();
}
}
}
void cleanup() {
if (array) {
free(array);
array = nullptr;
}
}
protected:
// increase the buffer size by at least /required/ bytes.
@@ -59,6 +66,17 @@ protected:
return static_cast<char *>(array) + (pos - itemSize);
}
// Get a pointer to the item at a given index.
inline void *getElement(size_t index) {
assert("Buffer was deleted" && array != nullptr);
if (index * itemSize >= pos) {
throw new std::runtime_error("Can't get element after array bounds");
} else {
return static_cast<char *>(array) + (index * itemSize);
}
}
public:
static const size_t itemSize = item_size;

View File

@@ -6,12 +6,13 @@
namespace llmr {
class IconVertexBuffer : public Buffer<
4 // 2 coordinates per vertex (== 4 bytes)
4 + // int16 x/y coordinates per vertex (== 4 bytes)
4 // uint16 x/y coordinates of icon in sprite (== 4 bytes)
> {
public:
typedef int16_t vertex_type;
void add(vertex_type x, vertex_type y);
void add(vertex_type x, vertex_type y, uint16_t tx, uint16_t ty);
};
}

View File

@@ -27,6 +27,7 @@ private:
std::unique_ptr<Bucket> createIconBucket(const VectorTileLayer& layer, const BucketDescription& bucket_desc);
std::unique_ptr<Bucket> createTextBucket(const VectorTileLayer& layer, const BucketDescription& bucket_desc);
template <class Bucket> void addBucketFeatures(Bucket& bucket, const VectorTileLayer& layer, const BucketDescription& bucket_desc);
template <class Bucket, typename... Args> void addBucketFeatures(Bucket& bucket, const VectorTileLayer& layer, const BucketDescription& bucket_desc, Args... args);
private:
const VectorTile vector_data;

View File

@@ -20,7 +20,8 @@ class IconVertexBuffer;
class BucketDescription;
class IconShader;
class DotShader;
struct pbf;
class Sprite;
class VectorTileFeature;
class IconBucket : public Bucket {
public:
@@ -30,7 +31,7 @@ public:
virtual void render(Painter& painter, const std::string& layer_name, const Tile::ID& id);
virtual bool hasData() const;
void addGeometry(pbf& data);
void addFeature(const VectorTileFeature &feature, const std::shared_ptr<Sprite> &sprite);
void drawIcons(IconShader& shader);
void drawIcons(DotShader& shader);

View File

@@ -13,12 +13,12 @@ public:
void setImage(int32_t image);
void setColor(const std::array<float, 4>& color);
void setPosition(const std::array<float, 2>& pos);
void setDimension(const std::array<float, 2>& dimension);
void setSize(float size);
private:
int32_t a_pos = -1;
int32_t a_tex = -1;
int32_t image = -1;
int32_t u_image = -1;
@@ -26,9 +26,6 @@ private:
std::array<float, 4> color = {{}};
int32_t u_color = -1;
std::array<float, 2> pos = {{}};
int32_t u_pos = -1;
std::array<float, 2> dimension = {{}};
int32_t u_dimension = -1;

View File

@@ -73,8 +73,9 @@ public:
CapType cap = CapType::None;
JoinType join = JoinType::None;
std::string font;
std::string text_field;
float font_size = 0.0f;
std::string field;
std::string icon;
float size = 0.0f;
float miter_limit = 2.0f;
float round_limit = 1.0f;
TextPathType path = TextPathType::Horizontal;

View File

@@ -5,8 +5,14 @@
using namespace llmr;
void IconVertexBuffer::add(vertex_type x, vertex_type y) {
vertex_type *vertices = static_cast<vertex_type *>(addElement());
void IconVertexBuffer::add(vertex_type x, vertex_type y, uint16_t tx, uint16_t ty) {
void *data = addElement();
vertex_type *vertices = static_cast<vertex_type *>(data);
vertices[0] = x;
vertices[1] = y;
uint16_t *texture = static_cast<uint16_t *>(data);
texture[2] = tx;
texture[3] = ty;
}

View File

@@ -120,6 +120,15 @@ void TileParser::addBucketFeatures(Bucket& bucket, const VectorTileLayer& layer,
}
}
template <class Bucket, typename... Args>
void TileParser::addBucketFeatures(Bucket& bucket, const VectorTileLayer& layer, const BucketDescription& bucket_desc, Args... args) {
FilteredVectorTileLayer filtered_layer(layer, bucket_desc);
for (const pbf& feature_pbf : filtered_layer) {
if (obsolete()) return;
bucket->addFeature({ feature_pbf, layer }, args...);
}
}
std::unique_ptr<Bucket> TileParser::createFillBucket(const VectorTileLayer& layer, const BucketDescription& bucket_desc) {
std::unique_ptr<FillBucket> bucket = std::make_unique<FillBucket>(
tile.fillVertexBuffer, tile.triangleElementsBuffer, tile.lineElementsBuffer, bucket_desc);
@@ -137,7 +146,7 @@ std::unique_ptr<Bucket> TileParser::createLineBucket(const VectorTileLayer& laye
std::unique_ptr<Bucket> TileParser::createIconBucket(const VectorTileLayer& layer, const BucketDescription& bucket_desc) {
std::unique_ptr<IconBucket> bucket = std::make_unique<IconBucket>(
tile.iconVertexBuffer, bucket_desc);
addBucketFeatures(bucket, layer, bucket_desc);
addBucketFeatures(bucket, layer, bucket_desc, style.sprite);
return obsolete() ? nullptr : std::move(bucket);
}
@@ -166,12 +175,6 @@ std::unique_ptr<Bucket> TileParser::createTextBucket(const VectorTileLayer& laye
std::unique_ptr<TextBucket> bucket = std::make_unique<TextBucket>(
tile.textVertexBuffer, tile.triangleElementsBuffer, bucket_desc, placement);
FilteredVectorTileLayer filtered_layer(layer, bucket_desc);
for (const pbf& feature_pbf : filtered_layer) {
if (obsolete()) return nullptr;
bucket->addFeature({ feature_pbf, layer }, faces, shaping);
}
addBucketFeatures(bucket, layer, bucket_desc, faces, shaping);
return std::move(bucket);
}

View File

@@ -5,6 +5,7 @@
#include <llmr/renderer/painter.hpp>
#include <llmr/style/style.hpp>
#include <llmr/style/sprite.hpp>
#include <llmr/map/vector_tile.hpp>
#include <llmr/platform/gl.hpp>
@@ -22,13 +23,35 @@ IconBucket::IconBucket(IconVertexBuffer& vertexBuffer,
vertex_start(vertexBuffer.index()) {
}
void IconBucket::addGeometry(pbf& geom) {
void IconBucket::addFeature(const VectorTileFeature &feature, const std::shared_ptr<Sprite> &sprite) {
// TODO: We somehow need to reparse the stylesheet, or maintain a mapping of id => sprite name
// For now, we're just not showing points if the sprite was not yet loaded at *parse time* of
// the tile.
if (!sprite || !sprite->isLoaded()) return;
auto field_it = feature.properties.find(geometry.field);
if (field_it == feature.properties.end()) {
fprintf(stderr, "feature doesn't contain field '%s'\n", geometry.field.c_str());
return;
}
std::string field = toString(field_it->second);
if (geometry.size) {
field.append("-");
field.append(std::to_string(static_cast<int>(std::round(geometry.size))));
}
const SpritePosition &pos = sprite->getSpritePosition(field);
const uint16_t tx = pos.x + pos.width / 2;
const uint16_t ty = pos.y + pos.height / 2;
Geometry::command cmd;
pbf geom = feature.geometry;
Geometry geometry(geom);
int32_t x, y;
while ((cmd = geometry.next(x, y)) != Geometry::end) {
if (cmd == Geometry::move_to) {
vertexBuffer.add(x, y);
vertexBuffer.add(x, y, tx, ty);
} else {
fprintf(stderr, "other command than move_to in icon geometry\n");
}

View File

@@ -24,21 +24,11 @@ void Painter::renderIcon(IconBucket& bucket, const std::string& layer_name, cons
color[2] *= properties.opacity;
color[3] *= properties.opacity;
auto &sprite = map.getStyle().sprite;
SpritePosition spritePos;
if (properties.image.length() && sprite && sprite->isLoaded()) {
std::string sized_image = properties.image;
if (properties.size) {
sized_image.append("-");
sized_image.append(std::to_string(static_cast<int>(std::round(properties.size))));
}
spritePos = sprite->getSpritePosition(sized_image);
}
const mat4 &vtxMatrix = translatedMatrix(properties.translate, id, properties.translateAnchor);
if (!spritePos.width || !spritePos.height) {
const std::shared_ptr<Sprite> &sprite = map.getStyle().sprite;
if (!sprite || !sprite->isLoaded()) {
useProgram(dotShader->program);
dotShader->setMatrix(vtxMatrix);
dotShader->setColor(color);
@@ -58,10 +48,6 @@ void Painter::renderIcon(IconBucket& bucket, const std::string& layer_name, cons
iconShader->setMatrix(vtxMatrix);
iconShader->setColor(color);
iconShader->setImage(0);
iconShader->setPosition({{
spritePos.x + (float)spritePos.width / 2.0f,
spritePos.y + (float)spritePos.height / 2.0f,
}});
iconShader->setDimension({{
static_cast<float>(sprite->raster.width),
@@ -70,7 +56,7 @@ void Painter::renderIcon(IconBucket& bucket, const std::string& layer_name, cons
sprite->raster.bind(map.getState().isChanging());
const float iconSize = util::max(spritePos.width, spritePos.height) + 2;
const float iconSize = bucket.geometry.size * map.getState().getPixelRatio();
iconShader->setSize(iconSize);
#ifndef GL_ES_VERSION_2_0
glPointSize(iconSize);

View File

@@ -28,7 +28,7 @@ void Painter::renderText(TextBucket& bucket, const std::string& layer_name, cons
}
// If layerStyle.size > bucket.info.fontSize then labels may collide
float fontSize = std::fmin(properties.size, bucket.geom_desc.font_size);
float fontSize = std::fmin(properties.size, bucket.geom_desc.size);
matrix::scale(exMatrix, exMatrix, fontSize / 24.0f, fontSize / 24.0f, 1.0f);
const mat4 &vtxMatrix = translatedMatrix(properties.translate, id, properties.translateAnchor);
@@ -47,7 +47,7 @@ void Painter::renderText(TextBucket& bucket, const std::string& layer_name, cons
float angle = std::round((map.getState().getAngle() + rotate) / M_PI * 128);
// adjust min/max zooms for variable font sies
float zoomAdjust = log(fontSize / bucket.geom_desc.font_size) / log(2);
float zoomAdjust = log(fontSize / bucket.geom_desc.size) / log(2);
textShader->setAngle((int32_t)(angle + 256) % 256);
textShader->setFlip(bucket.geom_desc.path == TextPathType::Curve ? 1 : 0);

View File

@@ -102,7 +102,7 @@ void TextBucket::addGlyphs(const PlacedGlyphs &glyphs, float placementZoom,
void TextBucket::addFeature(const VectorTileFeature &feature,
const IndexedFaces &faces,
const std::map<Value, Shaping> &shapings) {
auto it_prop = feature.properties.find(geom_desc.text_field);
auto it_prop = feature.properties.find(geom_desc.field);
if (it_prop == feature.properties.end()) {
// feature does not have the correct property
return;

View File

@@ -32,7 +32,7 @@ DotShader::DotShader()
void DotShader::bind(char *offset) {
glEnableVertexAttribArray(a_pos);
glVertexAttribPointer(a_pos, 2, GL_SHORT, false, 0, offset);
glVertexAttribPointer(a_pos, 2, GL_SHORT, false, 8, offset);
}
void DotShader::setColor(const std::array<float, 4>& new_color) {

View File

@@ -1,10 +1,11 @@
uniform sampler2D u_image;
uniform vec2 u_pos;
uniform vec2 u_dimension;
uniform vec4 u_color;
uniform float u_size;
varying vec2 v_tex;
void main() {
vec2 pos = (u_pos + (gl_PointCoord - 0.5) * u_size) / u_dimension;
vec2 pos = (v_tex + (gl_PointCoord - 0.5) * u_size) / u_dimension;
gl_FragColor = texture2D(u_image, pos) * u_color;
}

View File

@@ -1,9 +1,13 @@
attribute vec2 a_pos;
attribute vec2 a_tex;
uniform mat4 u_matrix;
uniform float u_size;
varying vec2 v_tex;
void main() {
gl_Position = u_matrix * vec4(a_pos, 0, 1);
gl_PointSize = u_size;
v_tex = a_tex;
}

View File

@@ -17,25 +17,27 @@ IconShader::IconShader()
}
a_pos = glGetAttribLocation(program, "a_pos");
a_tex = glGetAttribLocation(program, "a_tex");
u_matrix = glGetUniformLocation(program, "u_matrix");
u_color = glGetUniformLocation(program, "u_color");
u_size = glGetUniformLocation(program, "u_size");
u_pos = glGetUniformLocation(program, "u_pos");
u_dimension = glGetUniformLocation(program, "u_dimension");
// fprintf(stderr, "IconShader:\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_pos: %d\n", u_pos);
// fprintf(stderr, " - u_dimension: %d\n", u_dimension);
// fprintf(stderr, " - u_image: %d\n", u_image);
}
void IconShader::bind(char *offset) {
glEnableVertexAttribArray(a_pos);
glVertexAttribPointer(a_pos, 2, GL_SHORT, false, 0, offset);
glVertexAttribPointer(a_pos, 2, GL_SHORT, false, 8, offset);
glEnableVertexAttribArray(a_tex);
glVertexAttribPointer(a_tex, 2, GL_UNSIGNED_SHORT, false, 8, offset + 4);
}
void IconShader::setImage(int32_t new_image) {
@@ -59,13 +61,6 @@ void IconShader::setSize(float new_size) {
}
}
void IconShader::setPosition(const std::array<float, 2>& new_pos) {
if (pos != new_pos) {
glUniform2fv(u_pos, 1, new_pos.data());
pos = new_pos;
}
}
void IconShader::setDimension(const std::array<float, 2>& new_dimension) {
if (dimension != new_dimension) {
glUniform2fv(u_dimension, 1, new_dimension.data());

View File

@@ -11,8 +11,8 @@ const shader_source llmr::shaders[SHADER_COUNT] = {
"#version 120\nuniform vec4 u_color;\nuniform float u_blur;\nvoid main ()\n{\n vec2 x_1;\n x_1 = (gl_PointCoord - 0.5);\n float tmpvar_2;\n tmpvar_2 = clamp (((\n sqrt(dot (x_1, x_1))\n - 0.5) / (\n (0.5 - u_blur)\n - 0.5)), 0.0, 1.0);\n gl_FragColor = (u_color * (tmpvar_2 * (tmpvar_2 * \n (3.0 - (2.0 * tmpvar_2))\n )));\n}\n\n",
},
{
"#version 120\nattribute vec2 a_pos;\nuniform mat4 u_matrix;\nuniform float u_size;\nvoid main ()\n{\n vec4 tmpvar_1;\n tmpvar_1.zw = vec2(0.0, 1.0);\n tmpvar_1.xy = a_pos;\n gl_Position = (u_matrix * tmpvar_1);\n gl_PointSize = u_size;\n}\n\n",
"#version 120\nuniform sampler2D u_image;\nuniform vec2 u_pos;\nuniform vec2 u_dimension;\nuniform vec4 u_color;\nuniform float u_size;\nvoid main ()\n{\n gl_FragColor = (texture2D (u_image, ((u_pos + \n ((gl_PointCoord - 0.5) * u_size)\n ) / u_dimension)) * u_color);\n}\n\n",
"#version 120\nattribute vec2 a_pos;\nattribute vec2 a_tex;\nuniform mat4 u_matrix;\nuniform float u_size;\nvarying vec2 v_tex;\nvoid main ()\n{\n vec4 tmpvar_1;\n tmpvar_1.zw = vec2(0.0, 1.0);\n tmpvar_1.xy = a_pos;\n gl_Position = (u_matrix * tmpvar_1);\n gl_PointSize = u_size;\n v_tex = a_tex;\n}\n\n",
"#version 120\nuniform sampler2D u_image;\nuniform vec2 u_dimension;\nuniform vec4 u_color;\nuniform float u_size;\nvarying vec2 v_tex;\nvoid main ()\n{\n gl_FragColor = (texture2D (u_image, ((v_tex + \n ((gl_PointCoord - 0.5) * u_size)\n ) / u_dimension)) * u_color);\n}\n\n",
},
{
"#version 120\nattribute vec2 a_pos;\nattribute vec2 a_extrude;\nattribute float a_linesofar;\nuniform mat4 u_matrix;\nuniform mat4 u_exmatrix;\nuniform float u_ratio;\nuniform vec2 u_linewidth;\nvarying vec2 v_normal;\nvarying float v_linesofar;\nvoid main ()\n{\n vec2 normal_1;\n vec2 tmpvar_2;\n tmpvar_2 = (vec2(mod (a_pos, 2.0)));\n normal_1.x = tmpvar_2.x;\n normal_1.y = sign((tmpvar_2.y - 0.5));\n v_normal = normal_1;\n vec4 tmpvar_3;\n tmpvar_3.zw = vec2(0.0, 0.0);\n tmpvar_3.xy = ((u_linewidth.x * a_extrude) * 0.015873);\n vec4 tmpvar_4;\n tmpvar_4.zw = vec2(0.0, 1.0);\n tmpvar_4.xy = floor((a_pos * 0.5));\n gl_Position = ((u_matrix * tmpvar_4) + (u_exmatrix * tmpvar_3));\n v_linesofar = (a_linesofar * u_ratio);\n}\n\n",

View File

@@ -11,8 +11,8 @@ const shader_source llmr::shaders[SHADER_COUNT] = {
"precision highp float;\nuniform vec4 u_color;\nuniform float u_blur;\nvoid main ()\n{\n mediump vec2 x_1;\n x_1 = (gl_PointCoord - 0.5);\n mediump float tmpvar_2;\n tmpvar_2 = clamp (((\n sqrt(dot (x_1, x_1))\n - 0.5) / (\n (0.5 - u_blur)\n - 0.5)), 0.0, 1.0);\n gl_FragColor = (u_color * (tmpvar_2 * (tmpvar_2 * \n (3.0 - (2.0 * tmpvar_2))\n )));\n}\n\n",
},
{
"precision highp float;\nattribute vec2 a_pos;\nuniform mat4 u_matrix;\nuniform float u_size;\nvoid main ()\n{\n vec4 tmpvar_1;\n tmpvar_1.zw = vec2(0.0, 1.0);\n tmpvar_1.xy = a_pos;\n gl_Position = (u_matrix * tmpvar_1);\n gl_PointSize = u_size;\n}\n\n",
"precision highp float;\nuniform sampler2D u_image;\nuniform vec2 u_pos;\nuniform vec2 u_dimension;\nuniform vec4 u_color;\nuniform float u_size;\nvoid main ()\n{\n mediump vec2 tmpvar_1;\n tmpvar_1 = ((u_pos + (\n (gl_PointCoord - 0.5)\n * u_size)) / u_dimension);\n lowp vec4 tmpvar_2;\n tmpvar_2 = (texture2D (u_image, tmpvar_1) * u_color);\n gl_FragColor = tmpvar_2;\n}\n\n",
"precision highp float;\nattribute vec2 a_pos;\nattribute vec2 a_tex;\nuniform mat4 u_matrix;\nuniform float u_size;\nvarying vec2 v_tex;\nvoid main ()\n{\n vec4 tmpvar_1;\n tmpvar_1.zw = vec2(0.0, 1.0);\n tmpvar_1.xy = a_pos;\n gl_Position = (u_matrix * tmpvar_1);\n gl_PointSize = u_size;\n v_tex = a_tex;\n}\n\n",
"precision highp float;\nuniform sampler2D u_image;\nuniform vec2 u_dimension;\nuniform vec4 u_color;\nuniform float u_size;\nvarying vec2 v_tex;\nvoid main ()\n{\n mediump vec2 tmpvar_1;\n tmpvar_1 = ((v_tex + (\n (gl_PointCoord - 0.5)\n * u_size)) / u_dimension);\n lowp vec4 tmpvar_2;\n tmpvar_2 = (texture2D (u_image, tmpvar_1) * u_color);\n gl_FragColor = tmpvar_2;\n}\n\n",
},
{
"precision highp float;\nattribute vec2 a_pos;\nattribute vec2 a_extrude;\nattribute float a_linesofar;\nuniform mat4 u_matrix;\nuniform mat4 u_exmatrix;\nuniform float u_ratio;\nuniform vec2 u_linewidth;\nvarying vec2 v_normal;\nvarying float v_linesofar;\nvoid main ()\n{\n vec2 normal_1;\n vec2 tmpvar_2;\n tmpvar_2 = (vec2(mod (a_pos, 2.0)));\n normal_1.x = tmpvar_2.x;\n normal_1.y = sign((tmpvar_2.y - 0.5));\n v_normal = normal_1;\n vec4 tmpvar_3;\n tmpvar_3.zw = vec2(0.0, 0.0);\n tmpvar_3.xy = ((u_linewidth.x * a_extrude) * 0.015873);\n vec4 tmpvar_4;\n tmpvar_4.zw = vec2(0.0, 1.0);\n tmpvar_4.xy = floor((a_pos * 0.5));\n gl_Position = ((u_matrix * tmpvar_4) + (u_exmatrix * tmpvar_3));\n v_linesofar = (a_linesofar * u_ratio);\n}\n\n",

View File

@@ -14,6 +14,6 @@ std::ostream& llmr::operator<<(std::ostream& os, const BucketDescription& bucket
os << " - cap: " << (uint32_t)bucket.geometry.cap << std::endl;
os << " - join: " << (uint32_t)bucket.geometry.join << std::endl;
os << " - font: " << bucket.geometry.font << std::endl;
os << " - font_size: " << bucket.geometry.font_size << std::endl;
os << " - size: " << bucket.geometry.size << std::endl;
return os;
}

View File

@@ -83,15 +83,15 @@ BucketDescription StyleParser::parseBucket(JSVal value) {
} else {
throw Style::exception("font stack must be a string");
}
} else if (name == "fontSize") {
} else if (name == "fontSize" || name == "size") {
if (value.IsNumber()) {
bucket.geometry.font_size = value.GetDouble();
bucket.geometry.size = value.GetDouble();
} else {
throw Style::exception("font size must be a number");
}
} else if (name == "text_field") {
} else if (name == "text_field" || name == "icon") {
if (value.IsString()) {
bucket.geometry.text_field = { value.GetString(), value.GetStringLength() };
bucket.geometry.field = { value.GetString(), value.GetStringLength() };
} else {
throw Style::exception("text field must be a string");
}

View File

@@ -278,7 +278,7 @@ void Placement::addFeature(TextBucket& bucket,
const float textMinDistance = info.textMinDistance;
const float rotate = info.rotate;
const float fontScale =
(tileExtent / util::tileSize) / (glyphSize / info.font_size);
(tileExtent / util::tileSize) / (glyphSize / info.size);
const float advance = measureText(faces, shaping);
Anchors anchors;