Merge branch 'master' of github.com:mapbox/llmr-native into clear-caches

Conflicts:
	Makefile
This commit is contained in:
Dane Springmeyer
2014-05-12 10:38:07 -07:00
30 changed files with 237 additions and 119 deletions

View File

@@ -7,10 +7,12 @@ V ?= 1
all: llmr
# Builds the regular library
llmr: config.gypi llmr.gyp
llmr: config.gypi llmr.gyp node
deps/run_gyp llmr.gyp --depth=. -Goutput_dir=.. --generator-output=./build/llmr -f make
make -C build/llmr V=$(V) llmr-x86
node:
@if [ ! `which node` ]; then echo 'error: depends on node.js. please make sure node is on your PATH'; exit 1; fi;
##### Test cases ###############################################################
@@ -40,7 +42,7 @@ run-headless-test: build/test/Makefile
# Builds the linux app with make. This is also used by Travis CI
linux: config.gypi linux/llmr-app.gyp
linux: config.gypi linux/llmr-app.gyp node
deps/run_gyp linux/llmr-app.gyp --depth=. -Goutput_dir=.. --generator-output=./build/linux -f make
make -C build/linux V=$(V) linuxapp
@@ -55,17 +57,17 @@ clear_xcode_cache:
@if [[ -d ~/Library/Developer/Xcode/DerivedData/ ]]; then echo 'clearing files in ~/Library/Developer/Xcode/DerivedData/ older than one day'; find ~/Library/Developer/Xcode/DerivedData/llmr-app-* -mtime +1 | xargs rm -rf; fi
# build Mac OS X project for Xcode
xproj: config.gypi macosx/llmr-app.gyp clear_xcode_cache
xproj: config.gypi macosx/llmr-app.gyp clear_xcode_cache node
deps/run_gyp macosx/llmr-app.gyp --depth=. --generator-output=./build -f xcode
open ./build/macosx/llmr-app.xcodeproj
# build iOS project for Xcode
iproj: config.gypi ios/llmr-app.gyp clear_xcode_cache
iproj: config.gypi ios/llmr-app.gyp clear_xcode_cache node
deps/run_gyp ios/llmr-app.gyp --depth=. --generator-output=./build -f xcode
open ./build/ios/llmr-app.xcodeproj
# build Linux project for Xcode (Runs on Mac OS X too, but without platform-specific code)
lproj: config.gypi linux/llmr-app.gyp clear_xcode_cache
lproj: config.gypi linux/llmr-app.gyp clear_xcode_cache node
deps/run_gyp linux/llmr-app.gyp --depth=. --generator-output=./build -f xcode
open ./build/linux/llmr-app.xcodeproj

View File

@@ -2067,6 +2067,19 @@ module.exports = {
"opacity": 0.25
},
}
}, {
"name": "satellite",
"layers": {
"building": {
"enabled": false,
},
"building_wall": {
"enabled": false,
},
"building_shadow": {
"enabled": false,
},
}
}],
"sprite": "/img/maki-sprite"
};

View File

@@ -115,6 +115,8 @@ private:
// Unconditionally performs a render with the current map state.
void render();
void renderLayers(const std::vector<LayerDescription>& layers);
void renderLayer(const LayerDescription& layer_desc);
private:
// If cleared, the next time the render thread attempts to render the map, it will *actually*

View File

@@ -17,6 +17,7 @@ public:
virtual void parse();
virtual void render(Painter &painter, const LayerDescription& layer_desc);
virtual bool hasData(const LayerDescription& layer_desc) const;
protected:
RasterBucket bucket;

View File

@@ -36,7 +36,8 @@ public:
bool update();
size_t prepareRender(const TransformState &transform);
void render();
void render(const LayerDescription& layer_desc, const BucketDescription &bucket_desc);
void finishRender();
std::forward_list<Tile::ID> getIDs() const;
void updateClipIDs(const std::map<Tile::ID, ClipID> &mapping);

View File

@@ -48,6 +48,7 @@ public:
// Override this in the child class.
virtual void parse() = 0;
virtual void render(Painter &painter, const LayerDescription& layer_desc) = 0;
virtual bool hasData(const LayerDescription& layer_desc) const = 0;
public:

View File

@@ -27,6 +27,7 @@ public:
virtual void parse();
virtual void render(Painter &painter, const LayerDescription& layer_desc);
virtual bool hasData(const LayerDescription& layer_desc) const;
protected:
// Holds the actual geometries in this tile.

View File

@@ -12,6 +12,7 @@ class Painter;
class Bucket : private util::noncopyable {
public:
virtual void render(Painter& painter, const std::string& layer_name, const Tile::ID& id) = 0;
virtual bool hasData() const = 0;
virtual ~Bucket() {}
};

View File

@@ -22,6 +22,7 @@ public:
DebugBucket(DebugFontBuffer& fontBuffer);
virtual void render(Painter& painter, const std::string& layer_name, const Tile::ID& id);
virtual bool hasData() const;
void drawLines(PlainShader& shader);
void drawPoints(PlainShader& shader);

View File

@@ -45,9 +45,9 @@ public:
~FillBucket();
virtual void render(Painter& painter, const std::string& layer_name, const Tile::ID& id);
virtual bool hasData() const;
void addGeometry(pbf& data);
bool empty() const;
void tessellate();
void drawElements(PlainShader& shader);

View File

@@ -28,11 +28,11 @@ public:
const BucketDescription& bucket_desc);
virtual void render(Painter& painter, const std::string& layer_name, const Tile::ID& id);
virtual bool hasData() const;
void addGeometry(pbf& data);
void addGeometry(const std::vector<Coordinate>& line);
bool empty() const;
bool hasPoints() const;
void drawLines(LineShader& shader);

View File

@@ -43,11 +43,23 @@ public:
void setup();
void clear();
// Updates the default matrices to the current viewport dimensions.
void changeMatrix();
void render(const Tile& tile);
// Renders a particular layer from a tile.
void renderTileLayer(const Tile& tile, const LayerDescription &layer_desc);
// Renders debug information for a tile.
void renderTileDebug(const Tile& tile);
// Renders the backdrop of the OpenGL view. This also paints in areas where we don't have any
// tiles whatsoever.
void renderMatte();
// Renders the red debug frame around a tile, visualizing its perimeter.
void renderDebugFrame();
void renderDebugText(DebugBucket& bucket);
void renderDebugText(const std::vector<std::string> &strings);
void renderFill(FillBucket& bucket, const std::string& layer_name, const Tile::ID& id);
@@ -61,19 +73,24 @@ public:
// Changes whether debug information is drawn onto the map
void setDebug(bool enabled);
// Opaque/Translucent pass setting
void startOpaquePass();
void startTranslucentPass();
void endPass();
// Configures the painter strata that is used for early z-culling of fragments.
void setStrata(float strata);
void prepareClippingMask();
void drawClippingMask(const mat4& matrix, const ClipID& clip);
void finishClippingMask();
void setCurrentSourceName(const std::string &name);
bool needsAnimation() const;
private:
void setupShaders();
void renderLayers(const std::shared_ptr<TileData>& tile, const std::vector<LayerDescription>& layers);
void renderLayer(const std::shared_ptr<TileData>& tile_data, const LayerDescription& layer_desc);
void translateLayer(std::array<float, 2> translation, bool reverse = false);
void prepareTile(const Tile& tile);
void useProgram(uint32_t program);
void lineWidth(float lineWidth);
void depthMask(bool value);
@@ -96,9 +113,8 @@ private:
bool gl_depthMask = true;
std::array<uint16_t, 2> gl_viewport = {{ 0, 0 }};
float strata = 0;
const float strata_epsilon = 1.0f / (1 << 16);
enum { Opaque, Translucent } pass = Opaque;
std::string currentSourceName;
const float strata_epsilon = 1.0f / (1 << 16);
std::unique_ptr<PlainShader> plainShader;
std::unique_ptr<OutlineShader> outlineShader;

View File

@@ -28,11 +28,10 @@ public:
const BucketDescription& bucket_desc);
virtual void render(Painter& painter, const std::string& layer_name, const Tile::ID& id);
virtual bool hasData() const;
void addGeometry(pbf& data);
bool hasPoints() const;
void drawPoints(PointShader& shader);
void drawPoints(DotShader& shader);

View File

@@ -16,6 +16,7 @@ public:
RasterBucket(Texturepool &texturepool);
virtual void render(Painter& painter, const std::string& layer_name, const Tile::ID& id);
virtual bool hasData() const;
bool setImage(const std::string &data);

View File

@@ -29,8 +29,8 @@ public:
TriangleElementsBuffer &triangleElementsBuffer,
const BucketDescription &bucket_desc, Placement &placement);
virtual void render(Painter &painter, const std::string &layer_name,
const Tile::ID &id);
virtual void render(Painter &painter, const std::string &layer_name, const Tile::ID &id);
virtual bool hasData() const;
void addGlyphs(const PlacedGlyphs &glyphs, float placementZoom,
PlacementRange placementRange, float zoom);
@@ -39,8 +39,6 @@ public:
const IndexedFaces &faces,
const std::map<Value, Shaping> &shapings);
bool empty() const;
void drawGlyphs(TextShader &shader);
public:

View File

@@ -5,6 +5,7 @@
#include <string>
#include <mutex>
#include <memory>
#include <atomic>
#include <llmr/util/raster.hpp>
#include <llmr/util/vec.hpp>

29
setup-libraries-cross.sh Executable file
View File

@@ -0,0 +1,29 @@
#!/bin/bash
set -e -u
export CXX11=true
export SYSROOT=`pwd`/../rootfs
export SDK_PATH=`pwd`/../arm-linux-gnueabi-linaro_4.8.3-2014.04
export V=1
cd mapnik-packaging/osx/
source Linaro-softfp.sh
echo $PATH
if [ ! -f out/build-cpp11-libstdcpp-gcc-arm-linux-gnueabi/lib/libpng.a ] ; then ./scripts/build_png.sh ; fi
# if [ ! -f out/build-cpp11-libstdcpp-gcc-arm-linux-gnueabi/lib/libglfw3.a ] ; then ./scripts/build_glfw.sh ; fi
if [ ! -f out/build-cpp11-libstdcpp-gcc-arm-linux-gnueabi/lib/libuv.a ] ; then ./scripts/build_libuv.sh ; fi
if [ ! -f out/build-cpp11-libstdcpp-gcc-arm-linux-gnueabi/lib/libssl.a ] ; then ./scripts/build_openssl.sh ; fi
# if [ ! -f out/build-cpp11-libstdcpp-gcc-x86_64/lib/libcurl.a ] ; then ./scripts/build_curl.sh ; fi
# if [ ! -d out/build-cpp11-libstdcpp-gcc-arm-linux-gnueabi/include/boost ] ; then ./scripts/build_boost.sh `pwd`/../../src/ `pwd`/../../linux/ `pwd`/../../common/ ; fi
# cd ../../
# ./configure \
# --pkg-config-root=`pwd`/mapnik-packaging/osx/out/build-cpp11-libstdcpp-gcc-x86_64/lib/pkgconfig \
# --boost=`pwd`/mapnik-packaging/osx/out/build-cpp11-libstdcpp-gcc-x86_64
# fi

View File

@@ -25,7 +25,7 @@ fi
if [[ $MISSING_DEPS != false ]]; then
if [ ${UNAME} = 'Darwin' ]; then
echo 'Please run "brew install autoconf automake libtool makedependc cmake" and then re-run ./setup-libraries.sh'
echo 'Please run "brew install autoconf automake libtool makedepend cmake" and then re-run ./setup-libraries.sh'
elif [ ${UNAME} = 'Linux' ]; then
echo 'Please run "sudo apt-get install automake libtool xutils-dev cmake" and then re-run ./setup-libraries.sh'
fi

View File

@@ -423,14 +423,18 @@ void Map::render() {
painter.finishClippingMask();
// Render per layer in the stylesheet.
renderLayers(style.layers);
// Then, render each source's tiles. TODO: handle more than one
// vector source.
// Finalize the rendering, e.g. by calling debug render calls per tile.
// This guarantees that we have at least one function per tile called.
// When only rendering layers via the stylesheet, it's possible that we don't
// ever visit a tile during rendering.
for (auto &pair : sources) {
Source &source = *pair.second;
painter.setCurrentSourceName(pair.first);
source.render();
const std::string &name = pair.first;
gl::group group(std::string("debug ") + name);
source.finishRender();
}
painter.renderMatte();
@@ -442,3 +446,57 @@ void Map::render() {
update();
}
}
void Map::renderLayers(const std::vector<LayerDescription>& layers) {
// TODO: Correctly compute the number of layers recursively beforehand.
float strata_thickness = 1.0f / (layers.size() + 1);
// - FIRST PASS ------------------------------------------------------------
// Render everything top-to-bottom by using reverse iterators. Render opaque
// objects first.
painter.startOpaquePass();
typedef std::vector<LayerDescription>::const_reverse_iterator riterator;
int i = 0;
for (riterator it = layers.rbegin(), end = layers.rend(); it != end; ++it, ++i) {
painter.setStrata(i * strata_thickness);
renderLayer(*it);
}
painter.endPass();
// - SECOND PASS -----------------------------------------------------------
// Make a second pass, rendering translucent objects. This time, we render
// bottom-to-top.
painter.startTranslucentPass();
typedef std::vector<LayerDescription>::const_iterator iterator;
--i;
for (iterator it = layers.begin(), end = layers.end(); it != end; ++it, --i) {
painter.setStrata(i * strata_thickness);
renderLayer(*it);
}
painter.endPass();
}
void Map::renderLayer(const LayerDescription& layer_desc) {
gl::group group(std::string("layer: ") + layer_desc.name);
if (layer_desc.child_layer.size()) {
// This is a layer group.
// TODO: create framebuffer
renderLayers(layer_desc.child_layer);
// TODO: render framebuffer on previous framebuffer
} else {
// This is a singular layer. Try to find the bucket associated with
// this layer and render it.
auto bucket_it = style.buckets.find(layer_desc.bucket_name);
if (bucket_it != style.buckets.end()) {
const BucketDescription &bucket_desc = bucket_it->second;
// Find the source and render all tiles in it.
auto source_it = sources.find(bucket_desc.source_name);
if (source_it != sources.end()) {
const std::unique_ptr<Source> &source = source_it->second;
source->render(layer_desc, bucket_desc);
}
}
}
}

View File

@@ -28,3 +28,7 @@ void RasterTileData::parse() {
void RasterTileData::render(Painter &painter, const LayerDescription& layer_desc) {
bucket.render(painter, layer_desc.name, id);
}
bool RasterTileData::hasData(const LayerDescription& layer_desc) const {
return bucket.hasData();
}

View File

@@ -48,6 +48,7 @@ size_t Source::prepareRender(const TransformState &transform) {
size_t masks = 0;
for (Tile& tile : tiles) {
gl::group group(util::sprintf<32>("mask %d/%d/%d", tile.id.z, tile.id.y, tile.id.z));
transform.matrixFor(tile.matrix, tile.id);
matrix::multiply(tile.matrix, painter.projMatrix, tile.matrix);
painter.drawClippingMask(tile.matrix, tile.clip);
@@ -57,16 +58,25 @@ size_t Source::prepareRender(const TransformState &transform) {
return masks;
}
void Source::render() {
void Source::render(const LayerDescription& layer_desc, const BucketDescription &bucket_desc) {
if (!enabled) return;
for (const Tile& tile : tiles) {
if (tile.data && tile.data->state == TileData::State::parsed) {
painter.render(tile);
painter.renderTileLayer(tile, layer_desc);
}
}
}
void Source::finishRender() {
if (!enabled) return;
for (const Tile& tile : tiles) {
painter.renderTileDebug(tile);
}
}
std::forward_list<Tile::ID> Source::getIDs() const {
std::forward_list<Tile::ID> ptrs;
std::transform(tiles.begin(), tiles.end(), std::front_inserter(ptrs), [](const Tile &tile) {

View File

@@ -40,4 +40,16 @@ void VectorTileData::render(Painter &painter, const LayerDescription& layer_desc
assert(databucket_it->second);
databucket_it->second->render(painter, layer_desc.name, id);
}
}
}
bool VectorTileData::hasData(const LayerDescription& layer_desc) const {
if (state != State::parsed) return false;
auto databucket_it = buckets.find(layer_desc.bucket_name);
if (databucket_it != buckets.end()) {
assert(databucket_it->second);
return databucket_it->second->hasData();
} else {
return false;
}
}

View File

@@ -18,6 +18,10 @@ void DebugBucket::render(Painter& painter, const std::string& /*layer_name*/, co
painter.renderDebugText(*this);
}
bool DebugBucket::hasData() const {
return fontBuffer.index() > 0;
}
void DebugBucket::drawLines(PlainShader& shader) {
array.bind(shader, fontBuffer, BUFFER_OFFSET(0));
glDrawArrays(GL_LINES, 0, (GLsizei)(fontBuffer.index()));

View File

@@ -206,8 +206,8 @@ void FillBucket::render(Painter& painter, const std::string& layer_name, const T
painter.renderFill(*this, layer_name, id);
}
bool FillBucket::empty() const {
return triangleGroups.empty() && lineGroups.empty();
bool FillBucket::hasData() const {
return !triangleGroups.empty() || !lineGroups.empty();
}
void FillBucket::drawElements(PlainShader& shader) {

View File

@@ -348,8 +348,8 @@ void LineBucket::render(Painter& painter, const std::string& layer_name, const T
painter.renderLine(*this, layer_name, id);
}
bool LineBucket::empty() const {
return triangleGroups.empty();
bool LineBucket::hasData() const {
return !triangleGroups.empty() || !pointGroups.empty();
}
bool LineBucket::hasPoints() const {

View File

@@ -141,7 +141,6 @@ void Painter::prepareClippingMask() {
}
void Painter::drawClippingMask(const mat4& matrix, const ClipID &clip) {
gl::group group("mask");
plainShader->setMatrix(matrix);
GLint id = clip.mask.to_ulong();
@@ -167,11 +166,6 @@ void Painter::finishClippingMask() {
gl::end_group();
}
void Painter::setCurrentSourceName(const std::string &name) {
currentSourceName = name;
}
void Painter::clear() {
gl::group group("clear");
glStencilMask(0xFF);
@@ -185,83 +179,53 @@ void Painter::clear() {
#endif
}
void Painter::render(const Tile& tile) {
gl::group group(util::sprintf<32>("render %d/%d/%d", tile.id.z, tile.id.y, tile.id.z));
assert(tile.data);
if (tile.data->state == TileData::State::parsed) {
matrix = tile.matrix;
GLint id = tile.clip.mask.to_ulong();
GLuint mask = clipMask[tile.clip.length];
glStencilFunc(GL_EQUAL, id, mask);
renderLayers(tile.data, map.getStyle().layers);
} else {
fprintf(stderr, "tile not parsed yet\n");
}
frameHistory.record(map.getAnimationTime(), map.getState().getNormalizedZoom());
if (debug) {
renderDebugText(tile.data->debugBucket);
renderDebugFrame();
}
}
void Painter::renderLayers(const std::shared_ptr<TileData>& tile_data, const std::vector<LayerDescription>& layers) {
float strata_thickness = 1.0f / (layers.size() + 1);
// - FIRST PASS ------------------------------------------------------------
// Render everything top-to-bottom by using reverse iterators. Render opaque
// objects first.
void Painter::startOpaquePass() {
gl::start_group("opaque pass");
pass = Opaque;
glDisable(GL_BLEND);
depthMask(true);
}
typedef std::vector<LayerDescription>::const_reverse_iterator riterator;
int i = 0;
for (riterator it = layers.rbegin(), end = layers.rend(); it != end; ++it, ++i) {
strata = i * strata_thickness;
renderLayer(tile_data, *it);
}
gl::end_group();
// - SECOND PASS -----------------------------------------------------------
// Make a second pass, rendering translucent objects. This time, we render
// bottom-to-top.
void Painter::startTranslucentPass() {
gl::start_group("translucent pass");
pass = Translucent;
glEnable(GL_BLEND);
depthMask(false);
}
typedef std::vector<LayerDescription>::const_iterator iterator;
--i;
for (iterator it = layers.begin(), end = layers.end(); it != end; ++it, --i) {
strata = i * strata_thickness;
renderLayer(tile_data, *it);
}
void Painter::endPass() {
gl::end_group();
}
void Painter::renderLayer(const std::shared_ptr<TileData>& tile_data, const LayerDescription& layer_desc) {
if (layer_desc.child_layer.size()) {
// This is a layer group.
// TODO: create framebuffer
renderLayers(tile_data, layer_desc.child_layer);
// TODO: render framebuffer on previous framebuffer
} else {
// This is a singular layer. Try to find the bucket associated with
// this layer and render it.
auto bucket_it = map.getStyle().buckets.find(layer_desc.bucket_name);
if (bucket_it != map.getStyle().buckets.end()) {
const BucketDescription &bucket = bucket_it->second;
// Only try to render the bucket if it draws data from the current source.
if (bucket.source_name == currentSourceName) {
tile_data->render(*this, layer_desc);
}
}
void Painter::setStrata(float value) {
strata = value;
}
void Painter::prepareTile(const Tile& tile) {
matrix = tile.matrix;
GLint id = (GLint)tile.clip.mask.to_ulong();
GLuint mask = clipMask[tile.clip.length];
glStencilFunc(GL_EQUAL, id, mask);
}
void Painter::renderTileLayer(const Tile& tile, const LayerDescription &layer_desc) {
assert(tile.data);
if (tile.data->hasData(layer_desc)) {
gl::group group(util::sprintf<32>("render %d/%d/%d", tile.id.z, tile.id.y, tile.id.z));
prepareTile(tile);
tile.data->render(*this, layer_desc);
frameHistory.record(map.getAnimationTime(), map.getState().getNormalizedZoom());
}
}
void Painter::renderTileDebug(const Tile& tile) {
gl::group group(util::sprintf<32>("debug %d/%d/%d", tile.id.z, tile.id.y, tile.id.z));
assert(tile.data);
if (debug) {
prepareTile(tile);
renderDebugText(tile.data->debugBucket);
renderDebugFrame();
}
}
@@ -289,8 +253,6 @@ void Painter::renderRaster(RasterBucket& bucket, const std::string& layer_name,
const RasterProperties& properties = raster_properties_it->second;
if (!properties.enabled) return;
gl::group group(layer_name + " (raster)");
depthMask(false);
useProgram(rasterShader->program);
@@ -306,7 +268,7 @@ void Painter::renderRaster(RasterBucket& bucket, const std::string& layer_name,
void Painter::renderFill(FillBucket& bucket, const std::string& layer_name, const Tile::ID& id) {
// Abort early.
if (bucket.empty()) return;
if (!bucket.hasData()) return;
auto fill_properties = map.getStyle().computed.fills;
auto fill_properties_it = fill_properties.find(layer_name);
@@ -336,7 +298,6 @@ void Painter::renderFill(FillBucket& bucket, const std::string& layer_name, cons
translateLayer(properties.translate);
gl::group group(layer_name + " (fill)");
// Because we're drawing top-to-bottom, and we update the stencil mask
// below, we have to draw the outline first (!)
if (outline && pass == Translucent) {
@@ -445,7 +406,7 @@ void Painter::renderFill(FillBucket& bucket, const std::string& layer_name, cons
void Painter::renderLine(LineBucket& bucket, const std::string& layer_name, const Tile::ID& /*id*/) {
// Abort early.
if (pass == Opaque) return;
if (bucket.empty()) return;
if (!bucket.hasData()) return;
auto line_properties = map.getStyle().computed.lines;
auto line_properties_it = line_properties.find(layer_name);
@@ -473,7 +434,6 @@ void Painter::renderLine(LineBucket& bucket, const std::string& layer_name, cons
translateLayer(properties.translate);
gl::group group(layer_name + " (line)");
glDepthRange(strata, 1.0f);
// We're only drawing end caps + round line joins if the line is > 2px. Otherwise, they aren't visible anyway.
@@ -532,7 +492,7 @@ 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&*/) {
// Abort early.
if (!bucket.hasPoints()) return;
if (!bucket.hasData()) return;
if (pass == Opaque) return;
auto point_properties = map.getStyle().computed.points;
@@ -544,8 +504,6 @@ void Painter::renderPoint(PointBucket& bucket, const std::string& layer_name, co
translateLayer(properties.translate);
gl::group group(layer_name + " (point)");
Color color = properties.color;
color[0] *= properties.opacity;
color[1] *= properties.opacity;
@@ -609,7 +567,7 @@ void Painter::renderPoint(PointBucket& bucket, const std::string& layer_name, co
void Painter::renderText(TextBucket& bucket, const std::string& layer_name, const Tile::ID& /*id*/) {
// Abort early.
if (pass == Opaque) return;
if (bucket.empty()) return;
if (!bucket.hasData()) return;
auto text_properties = map.getStyle().computed.texts;
auto text_properties_it = text_properties.find(layer_name);
@@ -620,8 +578,6 @@ void Painter::renderText(TextBucket& bucket, const std::string& layer_name, cons
translateLayer(properties.translate);
gl::group group(layer_name + " (text)");
mat4 exMatrix;
matrix::copy(exMatrix, projMatrix);
if (bucket.geom_desc.path == TextPathType::Curve) {

View File

@@ -41,7 +41,7 @@ void PointBucket::render(Painter& painter, const std::string& layer_name, const
painter.renderPoint(*this, layer_name, id);
}
bool PointBucket::hasPoints() const {
bool PointBucket::hasData() const {
return vertex_end > 0;
}

View File

@@ -21,3 +21,7 @@ void RasterBucket::drawRaster(RasterShader& shader, VertexBuffer &vertices, Vert
array.bind(shader, vertices, BUFFER_OFFSET(0));
glDrawArrays(GL_TRIANGLES, 0, (GLsizei)vertices.index());
}
bool RasterBucket::hasData() const {
return raster.isLoaded();
}

View File

@@ -146,7 +146,9 @@ void TextBucket::render(Painter &painter, const std::string &layer_name,
painter.renderText(*this, layer_name, id);
}
bool TextBucket::empty() const { return triangleGroups.empty(); }
bool TextBucket::hasData() const {
return !triangleGroups.empty();
}
void TextBucket::drawGlyphs(TextShader &shader) {
char *vertex_index = BUFFER_OFFSET(vertex_start * vertexBuffer.itemSize);

View File

@@ -36,7 +36,8 @@ void Texturepool::removeTextureID(GLuint texture_id) {
}
if (needs_clear) {
clearTextureIDs();
// TODO: We need to find a better way to deal with texture pool cleanup
// clearTextureIDs();
}
}