From ca4356fd0f1bb3dc78052a0a514f2ddb82f8376b Mon Sep 17 00:00:00 2001 From: Alexander Shalamov Date: Wed, 26 Feb 2020 14:25:48 +0200 Subject: [glfw] Add snapshotter to glfw test app --- platform/glfw/CMakeLists.txt | 6 +- platform/glfw/glfw_view.cpp | 147 +++++++++++++++++++++++++++++-------------- platform/glfw/glfw_view.hpp | 7 ++- platform/glfw/main.cpp | 6 +- 4 files changed, 114 insertions(+), 52 deletions(-) (limited to 'platform/glfw') 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 #include +#include #include +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("3d-buildings", "composite"); + extrusionLayer->setSourceLayer("building"); + extrusionLayer->setMinZoom(15.0f); + extrusionLayer->setFilter(Filter(eq(get("extrude"), literal("true")))); + extrusionLayer->setFillExtrusionColor(PropertyExpression(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(get("height"))); + extrusionLayer->setFillExtrusionBase(PropertyExpression(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(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(std::pair{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(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("3d-buildings", "composite"); - extrusionLayer->setSourceLayer("building"); - extrusionLayer->setMinZoom(15.0f); - extrusionLayer->setFilter(Filter(eq(get("extrude"), literal("true")))); - extrusionLayer->setFillExtrusionColor(PropertyExpression( - 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(get("height"))); - extrusionLayer->setFillExtrusionBase(PropertyExpression(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 +#include #include #include #include @@ -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 spriteIDs; @@ -141,4 +144,6 @@ private: GLFWwindow *window = nullptr; bool dirty = false; mbgl::optional featureID; + std::unique_ptr 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 onlineFileSource = mbgl::FileSourceManager::get()->getFileSource(mbgl::FileSourceType::Network, resourceOptions); if (!settings.online) { -- cgit v1.2.1