[glfw] Add snapshotter to glfw test app
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user