summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Shalamov <alexander.shalamov@mapbox.com>2020-02-26 14:25:48 +0200
committerAlexander Shalamov <alexander.shalamov@mapbox.com>2020-03-05 17:43:37 +0200
commitca4356fd0f1bb3dc78052a0a514f2ddb82f8376b (patch)
treef2bcb7b47ed73154aa3764894c3c17dc05966f4b
parent9a0bc1b58b775209417582867c713b2015353a78 (diff)
downloadqtlocation-mapboxgl-ca4356fd0f1bb3dc78052a0a514f2ddb82f8376b.tar.gz
[glfw] Add snapshotter to glfw test app
-rw-r--r--platform/glfw/CMakeLists.txt6
-rw-r--r--platform/glfw/glfw_view.cpp147
-rw-r--r--platform/glfw/glfw_view.hpp7
-rw-r--r--platform/glfw/main.cpp6
4 files changed, 114 insertions, 52 deletions
diff --git a/platform/glfw/CMakeLists.txt b/platform/glfw/CMakeLists.txt
index 0b26cc83b1..93df7d58a4 100644
--- a/platform/glfw/CMakeLists.txt
+++ b/platform/glfw/CMakeLists.txt
@@ -11,11 +11,15 @@ add_executable(
${PROJECT_SOURCE_DIR}/platform/glfw/glfw_renderer_frontend.cpp
${PROJECT_SOURCE_DIR}/platform/glfw/settings_json.cpp
${PROJECT_SOURCE_DIR}/platform/glfw/test_writer.cpp
+ ${PROJECT_SOURCE_DIR}/platform/default/src/mbgl/map/map_snapshotter.cpp
)
target_include_directories(
mbgl-glfw
- PRIVATE ${GLFW_INCLUDE_DIRS}
+ PRIVATE
+ ${GLFW_INCLUDE_DIRS}
+ # For /platform/default/src/mbgl/map/map_snapshotter.hpp
+ PRIVATE ${PROJECT_SOURCE_DIR}/src
)
include(${PROJECT_SOURCE_DIR}/vendor/cheap-ruler-cpp.cmake)
diff --git a/platform/glfw/glfw_view.cpp b/platform/glfw/glfw_view.cpp
index 1511e07bfc..b7f2b0009a 100644
--- a/platform/glfw/glfw_view.cpp
+++ b/platform/glfw/glfw_view.cpp
@@ -37,15 +37,50 @@
#include <cassert>
#include <cstdlib>
+#include <fstream>
#include <iostream>
+namespace {
+void addFillExtrusionLayer(mbgl::style::Style &style, bool visible) {
+ using namespace mbgl::style;
+ using namespace mbgl::style::expression::dsl;
+
+ // Satellite-only style does not contain building extrusions data.
+ if (!style.getSource("composite")) {
+ return;
+ }
+
+ if (auto layer = style.getLayer("3d-buildings")) {
+ layer->setVisibility(VisibilityType(!visible));
+ return;
+ }
+
+ auto extrusionLayer = std::make_unique<FillExtrusionLayer>("3d-buildings", "composite");
+ extrusionLayer->setSourceLayer("building");
+ extrusionLayer->setMinZoom(15.0f);
+ extrusionLayer->setFilter(Filter(eq(get("extrude"), literal("true"))));
+ extrusionLayer->setFillExtrusionColor(PropertyExpression<mbgl::Color>(interpolate(linear(),
+ number(get("height")),
+ 0.f,
+ toColor(literal("#160e23")),
+ 50.f,
+ toColor(literal("#00615f")),
+ 100.f,
+ toColor(literal("#55e9ff")))));
+ extrusionLayer->setFillExtrusionOpacity(0.6f);
+ extrusionLayer->setFillExtrusionHeight(PropertyExpression<float>(get("height")));
+ extrusionLayer->setFillExtrusionBase(PropertyExpression<float>(get("min_height")));
+ style.addLayer(std::move(extrusionLayer));
+}
+} // namespace
+
void glfwError(int error, const char *description) {
mbgl::Log::Error(mbgl::Event::OpenGL, "GLFW error (%i): %s", error, description);
assert(false);
}
-GLFWView::GLFWView(bool fullscreen_, bool benchmark_)
- : fullscreen(fullscreen_), benchmark(benchmark_) {
+GLFWView::GLFWView(bool fullscreen_, bool benchmark_, const mbgl::ResourceOptions &options)
+ : fullscreen(fullscreen_), benchmark(benchmark_), mapResourceOptions(options.clone()) {
glfwSetErrorCallback(glfwError);
std::srand(static_cast<unsigned int>(std::time(nullptr)));
@@ -134,6 +169,8 @@ GLFWView::GLFWView(bool fullscreen_, bool benchmark_)
printf("- Press `T` to add custom geometry source\n");
printf("- Press `F` to enable feature-state demo\n");
printf("- Press `U` to toggle pitch bounds\n");
+ printf("- Press `H` to take a snapshot of a current map.\n");
+ printf("- Press `J` to take a snapshot of a current map with an extrusions overlay.\n");
printf("\n");
printf("- Press `1` through `6` to add increasing numbers of point annotations for testing\n");
printf("- Press `7` through `0` to add increasing numbers of shape annotations for testing\n");
@@ -182,23 +219,23 @@ void GLFWView::onKey(GLFWwindow *window, int key, int /*scancode*/, int action,
view->animateRouteCallback = nullptr;
switch (key) {
- case GLFW_KEY_ESCAPE:
- glfwSetWindowShouldClose(window, true);
- break;
- case GLFW_KEY_TAB:
- view->cycleDebugOptions();
- break;
- case GLFW_KEY_X:
- if (!mods)
- view->map->jumpTo(mbgl::CameraOptions().withCenter(mbgl::LatLng {}).withZoom(0.0).withBearing(0.0).withPitch(0.0));
- break;
- case GLFW_KEY_O:
- view->onlineStatusCallback();
- break;
- case GLFW_KEY_S:
- if (view->changeStyleCallback)
- view->changeStyleCallback();
- break;
+ case GLFW_KEY_ESCAPE:
+ glfwSetWindowShouldClose(window, true);
+ break;
+ case GLFW_KEY_TAB:
+ view->cycleDebugOptions();
+ break;
+ case GLFW_KEY_X:
+ if (!mods)
+ view->map->jumpTo(
+ mbgl::CameraOptions().withCenter(mbgl::LatLng{}).withZoom(0.0).withBearing(0.0).withPitch(0.0));
+ break;
+ case GLFW_KEY_O:
+ view->onlineStatusCallback();
+ break;
+ case GLFW_KEY_S:
+ if (view->changeStyleCallback) view->changeStyleCallback();
+ break;
#if not MBGL_USE_GLES2
case GLFW_KEY_B: {
auto debug = view->map->getDebug();
@@ -401,6 +438,13 @@ void GLFWView::onKey(GLFWwindow *window, int key, int /*scancode*/, int action,
view->map->setBounds(mbgl::BoundOptions().withMinPitch(0).withMaxPitch(60));
}
} break;
+ case GLFW_KEY_H: {
+ view->makeSnapshot();
+ } break;
+ case GLFW_KEY_J: {
+ // Snapshot with overlay
+ view->makeSnapshot(true);
+ } break;
}
}
@@ -574,6 +618,42 @@ void GLFWView::popAnnotation() {
annotationIDs.pop_back();
}
+void GLFWView::makeSnapshot(bool withOverlay) {
+ if (!snapshotter || snapshotter->getStyleURL() != map->getStyle().getURL()) {
+ snapshotter =
+ std::make_unique<mbgl::MapSnapshotter>(std::pair<bool, std::string>{false, map->getStyle().getURL()},
+ map->getMapOptions().size(),
+ map->getMapOptions().pixelRatio(),
+ map->getCameraOptions(),
+ mbgl::nullopt,
+ mbgl::nullopt,
+ mapResourceOptions);
+ } else {
+ snapshotter->setCameraOptions(map->getCameraOptions());
+ }
+
+ if (withOverlay) {
+ addFillExtrusionLayer(snapshotter->getStyle(), withOverlay);
+ }
+
+ snapshotter->snapshot([](std::exception_ptr ptr,
+ mbgl::PremultipliedImage image,
+ mbgl::MapSnapshotter::Attributions,
+ mbgl::MapSnapshotter::PointForFn,
+ mbgl::MapSnapshotter::LatLngForFn) {
+ if (!ptr) {
+ mbgl::Log::Info(mbgl::Event::General,
+ "Made snapshot './snapshot.png' with size w:%dpx h:%dpx",
+ image.size.width,
+ image.size.height);
+ std::ofstream file("./snapshot.png");
+ file << mbgl::encodePNG(image);
+ } else {
+ mbgl::Log::Error(mbgl::Event::General, "Failed to make a snapshot!");
+ }
+ });
+}
+
void GLFWView::onScroll(GLFWwindow *window, double /*xOffset*/, double yOffset) {
auto *view = reinterpret_cast<GLFWView *>(glfwGetWindowUserPointer(window));
double delta = yOffset * 40;
@@ -790,35 +870,8 @@ void GLFWView::onDidFinishLoadingStyle() {
}
void GLFWView::toggle3DExtrusions(bool visible) {
- using namespace mbgl::style;
- using namespace mbgl::style::expression::dsl;
-
show3DExtrusions = visible;
-
- // Satellite-only style does not contain building extrusions data.
- if (!map->getStyle().getSource("composite")) {
- return;
- }
-
- if (auto layer = map->getStyle().getLayer("3d-buildings")) {
- layer->setVisibility(VisibilityType(!show3DExtrusions));
- return;
- }
-
- auto extrusionLayer = std::make_unique<FillExtrusionLayer>("3d-buildings", "composite");
- extrusionLayer->setSourceLayer("building");
- extrusionLayer->setMinZoom(15.0f);
- extrusionLayer->setFilter(Filter(eq(get("extrude"), literal("true"))));
- extrusionLayer->setFillExtrusionColor(PropertyExpression<mbgl::Color>(
- interpolate(linear(), number(get("height")),
- 0.f, toColor(literal("#160e23")),
- 50.f, toColor(literal("#00615f")),
- 100.f, toColor(literal("#55e9ff")))));
- extrusionLayer->setFillExtrusionOpacity(0.6f);
- extrusionLayer->setFillExtrusionHeight(PropertyExpression<float>(get("height")));
- extrusionLayer->setFillExtrusionBase(PropertyExpression<float>(get("min_height")));
-
- map->getStyle().addLayer(std::move(extrusionLayer));
+ addFillExtrusionLayer(map->getStyle(), show3DExtrusions);
}
void GLFWView::toggleCustomSource() {
diff --git a/platform/glfw/glfw_view.hpp b/platform/glfw/glfw_view.hpp
index e9867f14da..2fad6fe247 100644
--- a/platform/glfw/glfw_view.hpp
+++ b/platform/glfw/glfw_view.hpp
@@ -1,6 +1,7 @@
#pragma once
#include <mbgl/map/map.hpp>
+#include <mbgl/map/map_snapshotter.hpp>
#include <mbgl/util/geometry.hpp>
#include <mbgl/util/optional.hpp>
#include <mbgl/util/run_loop.hpp>
@@ -18,7 +19,7 @@ class RendererBackend;
class GLFWView : public mbgl::MapObserver {
public:
- GLFWView(bool fullscreen, bool benchmark);
+ GLFWView(bool fullscreen, bool benchmark, const mbgl::ResourceOptions &options);
~GLFWView() override;
float getPixelRatio() const;
@@ -94,6 +95,8 @@ private:
void clearAnnotations();
void popAnnotation();
+ void makeSnapshot(bool withOverlay = false);
+
mbgl::AnnotationIDs annotationIDs;
std::vector<std::string> spriteIDs;
@@ -141,4 +144,6 @@ private:
GLFWwindow *window = nullptr;
bool dirty = false;
mbgl::optional<std::string> featureID;
+ std::unique_ptr<mbgl::MapSnapshotter> snapshotter;
+ mbgl::ResourceOptions mapResourceOptions;
};
diff --git a/platform/glfw/main.cpp b/platform/glfw/main.cpp
index 784e002a65..fa1ac73799 100644
--- a/platform/glfw/main.cpp
+++ b/platform/glfw/main.cpp
@@ -95,9 +95,6 @@ int main(int argc, char *argv[]) {
mbgl::Log::Info(mbgl::Event::General, "BENCHMARK MODE: Some optimizations are disabled.");
}
- GLFWView backend(fullscreen, benchmark);
- view = &backend;
-
// Set access token if present
std::string token(getenv("MAPBOX_ACCESS_TOKEN") ?: "");
if (token.empty()) {
@@ -107,6 +104,9 @@ int main(int argc, char *argv[]) {
mbgl::ResourceOptions resourceOptions;
resourceOptions.withCachePath(cacheDB).withAccessToken(token);
+ GLFWView backend(fullscreen, benchmark, resourceOptions);
+ view = &backend;
+
std::shared_ptr<mbgl::FileSource> onlineFileSource =
mbgl::FileSourceManager::get()->getFileSource(mbgl::FileSourceType::Network, resourceOptions);
if (!settings.online) {