encode icon texture coordinate in buffer so we can render all pois with 1 draw call
This commit is contained in:
182
bin/style.js
182
bin/style.js
@@ -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",
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user