summaryrefslogtreecommitdiff
path: root/src/mbgl/geometry/dem_pyramid.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mbgl/geometry/dem_pyramid.cpp')
-rw-r--r--src/mbgl/geometry/dem_pyramid.cpp48
1 files changed, 48 insertions, 0 deletions
diff --git a/src/mbgl/geometry/dem_pyramid.cpp b/src/mbgl/geometry/dem_pyramid.cpp
new file mode 100644
index 0000000000..fb3a9d108e
--- /dev/null
+++ b/src/mbgl/geometry/dem_pyramid.cpp
@@ -0,0 +1,48 @@
+#include <mbgl/geometry/dem_pyramid.hpp>
+
+namespace mbgl {
+
+void DEMPyramid::buildLevels() {
+ while (true) {
+ auto& prev = levels.back();
+ const int32_t width = std::ceil(prev.width / 2);
+ const int32_t height = std::ceil(prev.height / 2);
+ const int32_t border = std::max<int32_t>(std::ceil(prev.border / 2), 1);
+
+ if (width == 1 || height == 1) {
+ break;
+ }
+ Level next(width, height, border);
+ prev.resample(next);
+ levels.emplace_back(std::move(next));
+ }
+
+ // Build remaining two levels. They aren't actually used in rendering, but we
+ // need them for OpenGL's mipmapping feature.
+ levels.emplace_back(2, 2, 0);
+ levels.emplace_back(1, 1, 0);
+}
+
+DEMPyramid::Level::Level(int32_t width_, int32_t height_, size_t border_)
+ : width(width_),
+ height(height_),
+ border(border_),
+ stride(width + 2 * border),
+ image({ static_cast<uint32_t>(width + 2 * border),
+ static_cast<uint32_t>(height + 2 * border) }) {
+ assert(width > 0);
+ assert(height > 0);
+ std::memset(image.data.get(), 0, image.bytes());
+}
+
+void DEMPyramid::Level::resample(Level& target) {
+ for (int32_t y = 0; y < target.height; y++) {
+ const int32_t fy = y * 2;
+ for (int32_t x = 0; x < target.width; x++) {
+ const int32_t fx = x * 2;
+ target.set(x, y, (get(fx, fy) + get(fx + 1, fy) + get(fx, fy + 1) + get(fx + 1, fy + 1)) / 4);
+ }
+ }
+}
+
+} // namespace mbgl