Update srtm example

This commit is contained in:
Nikita Lisitsa 2020-11-21 16:27:48 +03:00
parent 0d64e86ffe
commit ff5483bfef

View file

@ -27,8 +27,8 @@
#include <psemek/util/to_string.hpp>
#include <psemek/util/moving_average.hpp>
#include <psemek/util/recursive.hpp>
#include <psemek/util/threadpool.hpp>
#include <psemek/util/lru_cache.hpp>
#include <psemek/async/threadpool.hpp>
#include <fstream>
#include <iomanip>
@ -79,6 +79,8 @@ private:
T speed_;
};
static const float exaggeration = 1.f;
struct height_provider
{
float height_at(geom::vector<float, 3> 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<node> children[node_child_count];
std::size_t uid;
std::vector<std::int16_t> height_data;
std::atomic<bool> height_data_ready = false;
bool height_data_loaded = false;
bool height_data_loader_dispatched = false;
bool data_ready = false;
async::future<std::vector<std::int16_t>> 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<bool> 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<node_impl *>(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::node_impl> node_controller::make_node()
{
auto n = std::make_unique<node_controller::node_impl>();
@ -419,21 +383,20 @@ std::unique_ptr<node_controller::node_impl> 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<float>(h);
height_range |= exaggeration * static_cast<float>(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<std::int16_t> {
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<std::int16_t> 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<std::int16_t>(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<int>(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<int>(node_size);
tile_far_program["u_light"] = light;
tile_far_program["u_colormap"] = 0;