diff --git a/examples/srtm.cpp b/examples/srtm.cpp index 85de728f..3cdd2459 100644 --- a/examples/srtm.cpp +++ b/examples/srtm.cpp @@ -27,8 +27,8 @@ #include #include #include -#include #include +#include #include #include @@ -79,6 +79,8 @@ private: T speed_; }; +static const float exaggeration = 1.f; + struct height_provider { float height_at(geom::vector const & v); @@ -272,8 +274,6 @@ struct node_controller std::size_t loader_queue_size() const { return loader_.task_count(); } - void preload(int max_level); - private: struct node_impl : node @@ -284,10 +284,8 @@ private: std::unique_ptr children[node_child_count]; std::size_t uid; - std::vector height_data; - std::atomic height_data_ready = false; - bool height_data_loaded = false; - bool height_data_loader_dispatched = false; + bool data_ready = false; + async::future> height_data_future; bool draw(int level) override; node * child(int id) override; @@ -304,7 +302,7 @@ private: height_provider height_provider_; node_cache node_cache_; - util::threadpool loader_{"load", 1}; + async::threadpool loader_{"load", 1}; std::atomic cancel_ = false; std::size_t node_count_ = 0; @@ -367,40 +365,6 @@ node * node_controller::root(int f) return roots_[f].get(); } -void node_controller::preload(int) -{ - std::string strid; - auto visit = util::recursive([this, &strid](auto & self, node * n, int level) -> void - { - auto nn = static_cast(n); - log::info() << "Loading " << strid << "..."; - util::clock<> clock; - nn->load_heights(); - while (!nn->height_data_ready) - std::this_thread::yield(); - auto const time = clock.count(); - log::info() << "Loading " << strid << " done (" << time << "s)"; - - if (level + 1 < max_child_level && (time >= 0.05 || level < 5)) - { - std::string old_strid = strid; - for (int i = 0; i < node_child_count; ++i) - { - strid = old_strid + "/" + std::to_string(i); - self(n->child(i), level + 1); - } - - strid = old_strid; - } - }); - - for (int f = 0; f < 20; ++f) - { - strid = std::to_string(f); - visit(root(f), 0); - } -} - std::unique_ptr node_controller::make_node() { auto n = std::make_unique(); @@ -419,21 +383,20 @@ std::unique_ptr node_controller::make_node() bool node_controller::node_impl::draw(int level) { - if (!height_data_loaded) + if (!data_ready) { - if (!height_data_loader_dispatched) - { - load_heights(); - } + load_heights(); - if (!height_data_ready) return false; + if (!height_data_future.ready()) return false; + + auto height_data = std::move(height_data_future.get()); for (auto h : height_data) - height_range |= static_cast(h); + height_range |= exaggeration * static_cast(h); height_buffer.load(height_data, gl::STATIC_DRAW); height_data.clear(); - height_data_loaded = true; + data_ready = true; } array.bind(); @@ -501,19 +464,19 @@ node * node_controller::node_impl::child(int id) void node_controller::node_impl::load_heights() { - height_data_loader_dispatched = true; - controller->loader_.dispatch([this]{ - if (controller->cancel_) return; + if (height_data_future) + return; + + height_data_future = controller->loader_.dispatch(async::auto_cancel, [this]() -> std::vector { + if (controller->cancel_) return {}; auto cached = controller->node_cache_.load(uid); if (cached) { - height_data = std::move(*cached); - height_data_ready = true; - return; + return std::move(*cached); } - height_data.assign(((node_size + 2) * (node_size + 1)) / 2, 0); + std::vector height_data(((node_size + 2) * (node_size + 1)) / 2, 0); auto * out = height_data.data(); @@ -530,7 +493,7 @@ void node_controller::node_impl::load_heights() { for (int j = 0; j <= i; ++j) { - if (controller->cancel_) return; + if (controller->cancel_) return {}; *out++ = static_cast(controller->height_provider_.height_at(at(i, j))); } @@ -538,7 +501,7 @@ void node_controller::node_impl::load_heights() controller->node_cache_.store(uid, height_data); - height_data_ready = true; + return height_data; }); } @@ -546,6 +509,7 @@ static char const tile_vs[] = R"(#version 330 uniform mat4 u_transform; +uniform float u_exaggeration; uniform int u_N; uniform vec3 u_p0; @@ -571,7 +535,7 @@ void main() float t1 = float(j) / float(u_N); float t2 = 1.0 - t0 - t1; - vec3 p = normalize(u_p0 * t0 + u_p1 * t1 + u_p2 * t2) * (1.0 + in_height / 6400000.0); + vec3 p = normalize(u_p0 * t0 + u_p1 * t1 + u_p2 * t2) * (1.0 + u_exaggeration * in_height / 6400000.0); pos = p; gl_Position = u_transform * vec4(p, 1.0); float C = 1.0; @@ -721,8 +685,6 @@ srtm_app::srtm_app() color_map_neg.clamp(); color_map_neg.linear_filter(); } - -// nodes.preload(6); } void srtm_app::on_resize(int width, int height) @@ -858,6 +820,7 @@ void srtm_app::present() tile_close_program.bind(); tile_close_program["u_transform"] = camera_transform; + tile_close_program["u_exaggeration"] = exaggeration; tile_close_program["u_N"] = static_cast(node_size); tile_close_program["u_light"] = light; tile_close_program["u_colormap"] = 0; @@ -865,6 +828,7 @@ void srtm_app::present() tile_close_program["u_far"] = camera.far_clip; tile_far_program.bind(); tile_far_program["u_transform"] = camera_transform; + tile_far_program["u_exaggeration"] = exaggeration; tile_far_program["u_N"] = static_cast(node_size); tile_far_program["u_light"] = light; tile_far_program["u_colormap"] = 0;