Update srtm example
This commit is contained in:
parent
0d64e86ffe
commit
ff5483bfef
1 changed files with 26 additions and 62 deletions
|
|
@ -27,8 +27,8 @@
|
||||||
#include <psemek/util/to_string.hpp>
|
#include <psemek/util/to_string.hpp>
|
||||||
#include <psemek/util/moving_average.hpp>
|
#include <psemek/util/moving_average.hpp>
|
||||||
#include <psemek/util/recursive.hpp>
|
#include <psemek/util/recursive.hpp>
|
||||||
#include <psemek/util/threadpool.hpp>
|
|
||||||
#include <psemek/util/lru_cache.hpp>
|
#include <psemek/util/lru_cache.hpp>
|
||||||
|
#include <psemek/async/threadpool.hpp>
|
||||||
|
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
|
|
@ -79,6 +79,8 @@ private:
|
||||||
T speed_;
|
T speed_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const float exaggeration = 1.f;
|
||||||
|
|
||||||
struct height_provider
|
struct height_provider
|
||||||
{
|
{
|
||||||
float height_at(geom::vector<float, 3> const & v);
|
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(); }
|
std::size_t loader_queue_size() const { return loader_.task_count(); }
|
||||||
|
|
||||||
void preload(int max_level);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct node_impl
|
struct node_impl
|
||||||
: node
|
: node
|
||||||
|
|
@ -284,10 +284,8 @@ private:
|
||||||
std::unique_ptr<node> children[node_child_count];
|
std::unique_ptr<node> children[node_child_count];
|
||||||
std::size_t uid;
|
std::size_t uid;
|
||||||
|
|
||||||
std::vector<std::int16_t> height_data;
|
bool data_ready = false;
|
||||||
std::atomic<bool> height_data_ready = false;
|
async::future<std::vector<std::int16_t>> height_data_future;
|
||||||
bool height_data_loaded = false;
|
|
||||||
bool height_data_loader_dispatched = false;
|
|
||||||
|
|
||||||
bool draw(int level) override;
|
bool draw(int level) override;
|
||||||
node * child(int id) override;
|
node * child(int id) override;
|
||||||
|
|
@ -304,7 +302,7 @@ private:
|
||||||
height_provider height_provider_;
|
height_provider height_provider_;
|
||||||
node_cache node_cache_;
|
node_cache node_cache_;
|
||||||
|
|
||||||
util::threadpool loader_{"load", 1};
|
async::threadpool loader_{"load", 1};
|
||||||
std::atomic<bool> cancel_ = false;
|
std::atomic<bool> cancel_ = false;
|
||||||
|
|
||||||
std::size_t node_count_ = 0;
|
std::size_t node_count_ = 0;
|
||||||
|
|
@ -367,40 +365,6 @@ node * node_controller::root(int f)
|
||||||
return roots_[f].get();
|
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()
|
std::unique_ptr<node_controller::node_impl> node_controller::make_node()
|
||||||
{
|
{
|
||||||
auto n = std::make_unique<node_controller::node_impl>();
|
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)
|
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)
|
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_buffer.load(height_data, gl::STATIC_DRAW);
|
||||||
height_data.clear();
|
height_data.clear();
|
||||||
height_data_loaded = true;
|
data_ready = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
array.bind();
|
array.bind();
|
||||||
|
|
@ -501,19 +464,19 @@ node * node_controller::node_impl::child(int id)
|
||||||
|
|
||||||
void node_controller::node_impl::load_heights()
|
void node_controller::node_impl::load_heights()
|
||||||
{
|
{
|
||||||
height_data_loader_dispatched = true;
|
if (height_data_future)
|
||||||
controller->loader_.dispatch([this]{
|
return;
|
||||||
if (controller->cancel_) 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);
|
auto cached = controller->node_cache_.load(uid);
|
||||||
if (cached)
|
if (cached)
|
||||||
{
|
{
|
||||||
height_data = std::move(*cached);
|
return std::move(*cached);
|
||||||
height_data_ready = true;
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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();
|
auto * out = height_data.data();
|
||||||
|
|
||||||
|
|
@ -530,7 +493,7 @@ void node_controller::node_impl::load_heights()
|
||||||
{
|
{
|
||||||
for (int j = 0; j <= i; ++j)
|
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)));
|
*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);
|
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
|
R"(#version 330
|
||||||
|
|
||||||
uniform mat4 u_transform;
|
uniform mat4 u_transform;
|
||||||
|
uniform float u_exaggeration;
|
||||||
|
|
||||||
uniform int u_N;
|
uniform int u_N;
|
||||||
uniform vec3 u_p0;
|
uniform vec3 u_p0;
|
||||||
|
|
@ -571,7 +535,7 @@ void main()
|
||||||
float t1 = float(j) / float(u_N);
|
float t1 = float(j) / float(u_N);
|
||||||
float t2 = 1.0 - t0 - t1;
|
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;
|
pos = p;
|
||||||
gl_Position = u_transform * vec4(p, 1.0);
|
gl_Position = u_transform * vec4(p, 1.0);
|
||||||
float C = 1.0;
|
float C = 1.0;
|
||||||
|
|
@ -721,8 +685,6 @@ srtm_app::srtm_app()
|
||||||
color_map_neg.clamp();
|
color_map_neg.clamp();
|
||||||
color_map_neg.linear_filter();
|
color_map_neg.linear_filter();
|
||||||
}
|
}
|
||||||
|
|
||||||
// nodes.preload(6);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void srtm_app::on_resize(int width, int height)
|
void srtm_app::on_resize(int width, int height)
|
||||||
|
|
@ -858,6 +820,7 @@ void srtm_app::present()
|
||||||
|
|
||||||
tile_close_program.bind();
|
tile_close_program.bind();
|
||||||
tile_close_program["u_transform"] = camera_transform;
|
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_N"] = static_cast<int>(node_size);
|
||||||
tile_close_program["u_light"] = light;
|
tile_close_program["u_light"] = light;
|
||||||
tile_close_program["u_colormap"] = 0;
|
tile_close_program["u_colormap"] = 0;
|
||||||
|
|
@ -865,6 +828,7 @@ void srtm_app::present()
|
||||||
tile_close_program["u_far"] = camera.far_clip;
|
tile_close_program["u_far"] = camera.far_clip;
|
||||||
tile_far_program.bind();
|
tile_far_program.bind();
|
||||||
tile_far_program["u_transform"] = camera_transform;
|
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_N"] = static_cast<int>(node_size);
|
||||||
tile_far_program["u_light"] = light;
|
tile_far_program["u_light"] = light;
|
||||||
tile_far_program["u_colormap"] = 0;
|
tile_far_program["u_colormap"] = 0;
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue