Tatooine
rectilinear_grid3.h
Go to the documentation of this file.
1#ifndef TATOOINE_RENDERING_INTERACTIVE_RECTILINEAR_GRID3_H
2#define TATOOINE_RENDERING_INTERACTIVE_RECTILINEAR_GRID3_H
3//==============================================================================
11//==============================================================================
13//==============================================================================
14template <typename Axis0, typename Axis1>
15struct renderer<tatooine::rectilinear_grid<Axis0, Axis1>> {
16 static constexpr std::array<std::string_view, 5> vector_component_names = {
17 "magnitude", "x", "y", "z", "w"};
19 template <typename T>
22 //============================================================================
23 struct geometry : gl::indexeddata<Vec2<GLfloat>> {
24 static auto get() -> auto& {
25 static auto instance = geometry{};
26 return instance;
27 }
28 explicit geometry() {
29 vertexbuffer().resize(8);
30 {
31 auto vb_map = vertexbuffer().wmap();
32 vb_map[0] = Vec2<GLfloat>{0, 0, 0};
33 vb_map[1] = Vec2<GLfloat>{1, 0, 0};
34 vb_map[2] = Vec2<GLfloat>{1, 1, 0};
35 vb_map[3] = Vec2<GLfloat>{0, 1, 0};
36 vb_map[4] = Vec2<GLfloat>{0, 0, 1};
37 vb_map[5] = Vec2<GLfloat>{1, 0, 1};
38 vb_map[6] = Vec2<GLfloat>{1, 1, 1};
39 vb_map[7] = Vec2<GLfloat>{0, 1, 1};
40 }
41 indexbuffer().resize(36);
42 {
43 auto data = indexbuffer().wmap();
44 // front
45 data[0] = 0;
46 data[1] = 1;
47 data[2] = 3;
48 data[3] = 1;
49 data[4] = 2;
50 data[5] = 3;
51 // right
52 data[6] = 1;
53 data[7] = 5;
54 data[8] = 3;
55 data[9] = 5;
56 data[10] = 7;
57 data[11] = 3;
58 // back
59 data[12] = 5;
60 data[13] = 6;
61 data[14] = 7;
62 data[15] = 4;
63 data[16] = 6;
64 data[17] = 5;
65 // left
66 data[18] = 0;
67 data[19] = 2;
68 data[20] = 6;
69 data[21] = 0;
70 data[22] = 6;
71 data[23] = 4;
72 // top
73 data[24] = 2;
74 data[25] = 3;
75 data[26] = 6;
76 data[27] = 3;
77 data[28] = 7;
78 data[29] = 6;
79 // bottom
80 data[30] = 0;
81 data[31] = 5;
82 data[32] = 1;
83 data[33] = 0;
84 data[34] = 4;
85 data[35] = 5;
86 }
87 }
88 };
89 //============================================================================
90 struct property_shader : gl::shader {
91 //--------------------------------------------------------------------------
92 static constexpr std::string_view vertex_shader =
93 "#version 330 core\n"
94 "layout (location = 0) in vec2 position;\n"
95 "uniform mat4 model_view_matrix;\n"
96 "uniform mat4 projection_matrix;\n"
97 "uniform vec2 extent;\n"
98 "uniform vec2 pixel_width;\n"
99 "out vec2 texcoord;\n"
100 "void main() {\n"
101 " texcoord = (position * extent + pixel_width / 2) /\n"
102 " (extent+pixel_width);\n"
103 " gl_Position = projection_matrix *\n"
104 " model_view_matrix *\n"
105 " vec4(position, 0, 1);\n"
106 "}\n";
107 //--------------------------------------------------------------------------
108 static constexpr std::string_view fragment_shader =
109 "#version 330 core\n"
110 "uniform sampler2D data;\n"
111 "uniform sampler1D color_scale;\n"
112 "uniform float min;\n"
113 "uniform float max;\n"
114 "uniform int invert_scale;\n"
115 "in vec2 texcoord;\n"
116 "out vec4 out_color;\n"
117 "void main() {\n"
118 " float scalar = texture(data, texcoord).r;\n"
119 " if (isnan(scalar)) { discard; }\n"
120 " scalar = clamp((scalar - min) / (max - min), 0, 1);\n"
121 " if (invert_scale == 1) {\n"
122 " scalar = 1 - scalar;\n"
123 " }\n"
124 " vec3 col = texture(color_scale, scalar).rgb;\n"
125 " out_color = vec4(col, 1);\n"
126 "}\n";
127 //--------------------------------------------------------------------------
128 static auto get() -> auto& {
129 static auto s = property_shader{};
130 return s;
131 }
132 //--------------------------------------------------------------------------
133 private:
134 //--------------------------------------------------------------------------
136 add_stage<gl::vertexshader>(gl::shadersource{vertex_shader});
137 add_stage<gl::fragmentshader>(gl::shadersource{fragment_shader});
138 create();
139 set_uniform("data", 0);
140 set_uniform("color_scale", 1);
141 set_projection_matrix(Mat4<GLfloat>::eye());
142 set_model_view_matrix(Mat4<GLfloat>::eye());
143 set_min(0);
144 set_max(1);
145 invert_scale(false);
146 }
147 //--------------------------------------------------------------------------
148 public:
149 //--------------------------------------------------------------------------
150 auto set_projection_matrix(Mat4<GLfloat> const& P) -> void {
151 set_uniform_mat4("projection_matrix", P.data());
152 }
153 //--------------------------------------------------------------------------
154 auto set_model_view_matrix(Mat4<GLfloat> const& MV) -> void {
155 set_uniform_mat4("model_view_matrix", MV.data());
156 }
157 //--------------------------------------------------------------------------
158 auto set_extent(Vec2<GLfloat> const& extent) -> void {
159 set_uniform_vec2("extent", extent.data());
160 }
161 //--------------------------------------------------------------------------
162 auto set_pixel_width(Vec2<GLfloat> const& pixel_width) -> void {
163 set_uniform_vec2("pixel_width", pixel_width.data());
164 }
165 //--------------------------------------------------------------------------
166 auto set_min(GLfloat const min) -> void { set_uniform("min", min); }
167 auto set_max(GLfloat const max) -> void { set_uniform("max", max); }
168 //--------------------------------------------------------------------------
169 auto invert_scale(bool const invert) -> void {
170 set_uniform("invert_scale", invert ? 1 : 0);
171 }
172 };
173 //============================================================================
175 //============================================================================
176 private:
177 struct property_settings {
178 color_scale* c = nullptr;
179 GLfloat min_scalar = std::numeric_limits<GLfloat>::max();
180 GLfloat max_scalar = -std::numeric_limits<GLfloat>::max();
181 bool scale_inverted = false;
182 };
183 bool show_grid = true;
184 bool show_property = false;
185 int line_width = 1;
186 Vec4<GLfloat> grid_color = {0, 0, 0, 1};
187 std::unordered_map<std::string, property_settings> settings;
188 std::unordered_map<std::string, std::string_view> selected_component;
189 std::string const* selected_property_name = nullptr;
190 typename renderable_type::vertex_property_t const* selected_property =
191 nullptr;
192
193 bool vector_property = false;
194
195 //gl::indexeddata<Vec2<GLfloat>> geometry;
196 //gl::tex2r32f tex;
204
205 public:
206 //============================================================================
208 init_grid_geometry(grid);
209 init_properties(grid);
210 }
211 //----------------------------------------------------------------------------
213 auto const num_vertices =
214 grid.template size<0>() * 2 + grid.template size<1>() * 2;
215 geometry.vertexbuffer().resize(num_vertices);
216 geometry.indexbuffer().resize(num_vertices);
217 {
218 auto data = geometry.vertexbuffer().wmap();
219 auto k = std::size_t{};
220 for (std::size_t i = 0; i < grid.template size<0>(); ++i) {
221 data[k++] = Vec2<GLfloat>{grid.template dimension<0>()[i],
222 grid.template dimension<1>().front()};
223 data[k++] = Vec2<GLfloat>{grid.template dimension<0>()[i],
224 grid.template dimension<1>().back()};
225 }
226 for (std::size_t i = 0; i < grid.template size<1>(); ++i) {
227 data[k++] = Vec2<GLfloat>{grid.template dimension<0>().front(),
228 grid.template dimension<1>()[i]};
229 data[k++] = Vec2<GLfloat>{grid.template dimension<0>().back(),
230 grid.template dimension<1>()[i]};
231 }
232 }
233 {
234 auto data = geometry.indexbuffer().wmap();
235 for (std::size_t i = 0; i < num_vertices; ++i) {
236 data[i] = i;
237 }
238 }
239 }
240 //----------------------------------------------------------------------------
242 tex.resize(grid.template size<0>(), grid.template size<1>());
243
244 for (auto const& [name, prop] : grid.vertex_properties()) {
245 if (prop_holds_scalar(prop)) {
246 auto min_scalar = std::numeric_limits<GLfloat>::max();
247 auto max_scalar = -std::numeric_limits<GLfloat>::max();
248 retrieve_typed_prop(prop.get(), [&](auto const& prop) {
249 using prop_type = std::decay_t<decltype(prop)>;
250 using value_type = typename prop_type::value_type;
251 if constexpr (is_arithmetic<value_type>) {
252 grid.vertices().iterate_indices([&](auto const... is) {
253 auto const p = prop.at(is...);
254 min_scalar = std::min<GLfloat>(min_scalar, p);
255 max_scalar = std::max<GLfloat>(max_scalar, p);
256 });
257 }
258 });
259 settings[name] = {&color_scale::viridis(), min_scalar, max_scalar};
260 } else if (prop_holds_vector(prop)) {
261 retrieve_typed_prop(prop.get(), [&](auto const& prop) {
262 using prop_type = std::decay_t<decltype(prop)>;
263 using value_type = typename prop_type::value_type;
264 if constexpr (static_vec<value_type>) {
265 auto constexpr num_comps = value_type::num_components();
266 auto min_scalars = std::vector<GLfloat>(
267 num_comps + 1, std::numeric_limits<GLfloat>::max());
268 auto max_scalars = std::vector<GLfloat>(
269 num_comps + 1, -std::numeric_limits<GLfloat>::max());
270 grid.vertices().iterate_indices([&](auto const... is) {
271 auto const p = prop.at(is...);
272 auto mag = typename value_type::value_type{};
273 for (std::size_t j = 0; j < num_comps; ++j) {
274 mag += p(j) * p(j);
275 min_scalars[j + 1] =
276 std::min<GLfloat>(min_scalars[j + 1], p(j));
277 max_scalars[j + 1] =
278 std::max<GLfloat>(max_scalars[j + 1], p(j));
279 }
280 mag = std::sqrt(mag);
281 min_scalars[0] = std::min<GLfloat>(min_scalars[0], mag);
282 max_scalars[0] = std::max<GLfloat>(max_scalars[0], mag);
283 });
284
285 for (std::size_t j = 0; j < num_comps + 1; ++j) {
286 settings[name + '_' + std::string{vector_component_names[j]}] = {
287 &color_scale::viridis(), min_scalars[j], max_scalars[j]};
288 }
289 selected_component[name] = vector_component_names[0];
290 }
291 });
292 }
293 }
294 }
295 //============================================================================
296 template <typename T>
297 static auto cast_prop(auto&& prop) {
298 return static_cast<typed_vertex_property_interface_t<T> const*>(prop);
299 }
300 //----------------------------------------------------------------------------
301 auto retrieve_typed_prop(auto&& prop, auto&& f) {
302 if (prop->type() == typeid(float)) {
303 f(*cast_prop<float>(prop));
304 } else if (prop->type() == typeid(double)) {
305 f(*cast_prop<double>(prop));
306 } else if (prop->type() == typeid(vec2d)) {
307 f(*cast_prop<vec2d>(prop));
308 } else if (prop->type() == typeid(vec2f)) {
309 f(*cast_prop<vec2f>(prop));
310 } else if (prop->type() == typeid(vec3d)) {
311 f(*cast_prop<vec3d>(prop));
312 } else if (prop->type() == typeid(vec3f)) {
313 f(*cast_prop<vec3f>(prop));
314 } else if (prop->type() == typeid(vec4d)) {
315 f(*cast_prop<vec4d>(prop));
316 } else if (prop->type() == typeid(vec4f)) {
317 f(*cast_prop<vec4f>(prop));
318 }
319 }
320 //----------------------------------------------------------------------------
321 auto prop_holds_scalar(auto const& prop) {
322 return prop->type() == typeid(float) || prop->type() == typeid(double);
323 }
324 //----------------------------------------------------------------------------
325 auto prop_holds_vector(auto const& prop) {
326 return prop->type() == typeid(vec2f) || prop->type() == typeid(vec2d) ||
327 prop->type() == typeid(vec3f) || prop->type() == typeid(vec3d) ||
328 prop->type() == typeid(vec4f) || prop->type() == typeid(vec4d);
329 }
330 //----------------------------------------------------------------------------
331 auto upload_data_to_texture(auto&& prop, auto&& get_data,
332 renderable_type const& grid) {
333 auto texdata = std::vector<GLfloat>{};
334 texdata.reserve(grid.vertices().size());
335
336 grid.vertices().iterate_indices(
337 [&](auto const... is) { texdata.push_back(get_data(prop, is...)); });
338 tex.upload_data(texdata, grid.template size<0>(), grid.template size<1>());
339 };
340 //----------------------------------------------------------------------------
342 retrieve_typed_prop(prop, [&](auto&& prop) {
343 using prop_type = std::decay_t<decltype(prop)>;
344 using value_type = typename prop_type::value_type;
345 if constexpr (is_arithmetic<value_type>) {
346 upload_data_to_texture(
347 prop,
348 [](auto const& prop, auto const... is) { return prop(is...); },
349 grid);
350 }
351 });
352 }
353 //----------------------------------------------------------------------------
355 retrieve_typed_prop(prop, [&](auto&& prop) {
356 using prop_type = std::decay_t<decltype(prop)>;
357 using value_type = typename prop_type::value_type;
358 if constexpr (static_vec<value_type>) {
359 upload_data_to_texture(
360 prop,
361 [](auto const& prop, auto const... is) {
362 auto mag = typename value_type::value_type{};
363 for (std::size_t j = 0; j < value_type::num_components(); ++j) {
364 mag += prop(is...)(j) * prop(is...)(j);
365 }
366 return mag / value_type::num_components();
367 },
368 grid);
369 }
370 });
371 }
372 //----------------------------------------------------------------------------
373 auto upload_x_to_texture(auto&& prop, renderable_type const& grid) {
374 retrieve_typed_prop(prop, [&](auto&& prop) {
375 using prop_type = std::decay_t<decltype(prop)>;
376 using value_type = typename prop_type::value_type;
377 if constexpr (static_vec<value_type>) {
378 upload_data_to_texture(
379 prop,
380 [](auto const& prop, auto const... is) { return prop(is...).x(); },
381 grid);
382 }
383 });
384 }
385 //----------------------------------------------------------------------------
386 auto upload_y_to_texture(auto&& prop, renderable_type const& grid) {
387 retrieve_typed_prop(prop, [&](auto&& prop) {
388 using prop_type = std::decay_t<decltype(prop)>;
389 using value_type = typename prop_type::value_type;
390 if constexpr (static_vec<value_type>) {
391 upload_data_to_texture(
392 prop,
393 [](auto const& prop, auto const... is) { return prop(is...).y(); },
394 grid);
395 }
396 });
397 }
398 //----------------------------------------------------------------------------
399 auto upload_z_to_texture(auto&& prop, renderable_type const& grid) {
400 retrieve_typed_prop(prop, [&](auto&& prop) {
401 using prop_type = std::decay_t<decltype(prop)>;
402 using value_type = typename prop_type::value_type;
403 if constexpr (static_vec<value_type>) {
404 if constexpr (value_type::num_components() > 2) {
405 upload_data_to_texture(
406 prop,
407 [](auto const& prop, auto const... is) {
408 return prop(is...).z();
409 },
410 grid);
411 }
412 }
413 });
414 }
415 //----------------------------------------------------------------------------
416 auto upload_w_to_texture(auto&& prop, renderable_type const& grid) {
417 retrieve_typed_prop(prop, [&](auto&& prop) {
418 using prop_type = std::decay_t<decltype(prop)>;
419 using value_type = typename prop_type::value_type;
420 if constexpr (static_vec<value_type>) {
421 if constexpr (value_type::num_components() > 3) {
422 upload_data_to_texture(
423 prop,
424 [](auto const& prop, auto const... is) {
425 return prop(is...).w();
426 },
427 grid);
428 }
429 }
430 });
431 }
432 //----------------------------------------------------------------------------
434 auto name = std::string{};
435 if (selected_property_name != nullptr) {
436 name = *selected_property_name;
437 if (auto c = selected_component.find(name);
438 c != end(selected_component)) {
439 name += "_";
440 name += c->second;
441 }
442 }
443 return name;
444 }
445 //----------------------------------------------------------------------------
447 if (ImGui::BeginCombo("##combo", selected_property_name != nullptr
448 ? selected_property_name->c_str()
449 : nullptr)) {
450 for (auto const& [name, prop] : grid.vertex_properties()) {
451 if (prop->type() == typeid(float) || prop->type() == typeid(double) ||
452 prop->type() == typeid(vec2f) || prop->type() == typeid(vec2d) ||
453 prop->type() == typeid(vec3f) || prop->type() == typeid(vec3d) ||
454 prop->type() == typeid(vec4f) || prop->type() == typeid(vec4d)) {
455 auto is_selected = selected_property == prop.get();
456 if (ImGui::Selectable(name.c_str(), is_selected)) {
457 selected_property = prop.get();
458 selected_property_name = &name;
459 if (prop_holds_scalar(prop)) {
460 upload_scalar_to_texture(selected_property, grid);
461 vector_property = false;
462 } else if (prop_holds_vector(prop)) {
463 upload_magnitude_to_texture(selected_property, grid);
464 vector_property = true;
465 }
466 }
467 if (is_selected) {
468 ImGui::SetItemDefaultFocus();
469 }
470 }
471 }
472 ImGui::EndCombo();
473 }
474 }
475 //----------------------------------------------------------------------------
477 if (ImGui::BeginCombo(
478 "##combo_vector_component",
479 std::string{selected_component.at(*selected_property_name)}
480 .c_str())) {
481 auto n = std::size_t{};
482 retrieve_typed_prop(selected_property, [&](auto&& prop) {
483 using prop_type = std::decay_t<decltype(prop)>;
484 using value_type = typename prop_type::value_type;
485 if constexpr (static_vec<value_type>) {
487 }
488 });
489 for (std::size_t i = 0; i < n + 1; ++i) {
490 auto const is_selected =
491 selected_component.at(*selected_property_name) ==
492 vector_component_names[i];
493 if (ImGui::Selectable(std::string{vector_component_names[i]}.c_str(),
494 is_selected)) {
495 selected_component.at(*selected_property_name) =
496 vector_component_names[i];
497 if (i == 0) {
498 upload_magnitude_to_texture(selected_property, grid);
499 } else if (i == 1) {
500 upload_x_to_texture(selected_property, grid);
501 } else if (i == 2) {
502 upload_y_to_texture(selected_property, grid);
503 } else if (i == 3) {
504 upload_z_to_texture(selected_property, grid);
505 } else if (i == 4) {
506 upload_w_to_texture(selected_property, grid);
507 }
508 }
509 }
510 ImGui::EndCombo();
511 }
512 // ImGui::DragFloat("Min", &min_scalar, 0.01f, -FLT_MAX, max_scalar,
513 // "%.06f"); ImGui::DragFloat("Max", &max_scalar, 0.01f, min_scalar,
514 // FLT_MAX, "%.06f");
515 }
516 //----------------------------------------------------------------------------
518 if (selected_property != nullptr) {
519 auto combo_pos = ImGui::GetCursorScreenPos();
520 auto& setting = settings.at(selected_settings_name());
521 if (ImGui::BeginCombo("##combocolor",
522 selected_property_name != nullptr
523 ? selected_property_name->c_str()
524 : nullptr)) {
525 ImGui::PushID("##viridis");
526 auto viridis_selected =
527 ImGui::Selectable("", setting.c == &color_scale::viridis());
528 ImGui::PopID();
529 ImGui::SameLine();
530 ImGui::Image((void*)(std::intptr_t)color_scale::viridis().tex_2d.id(),
531 ImVec2(256, 20));
532 if (viridis_selected) {
533 setting.c = &color_scale::viridis();
534 }
535
536 ImGui::PushID("##GYPi");
537 auto gypi_selected =
538 ImGui::Selectable("", setting.c == &color_scale::GYPi());
539 ImGui::PopID();
540 ImGui::SameLine();
541 ImGui::Image((void*)(std::intptr_t)color_scale::GYPi().tex_2d.id(),
542 ImVec2(256, 20));
543 if (gypi_selected) {
544 setting.c = &color_scale::GYPi();
545 }
546 ImGui::EndCombo();
547 }
548 ImGui::SameLine();
549 ImGui::Text("Invert Color");
550 ImGui::SameLine();
551 ImGui::ToggleButton("inverted", &setting.scale_inverted);
552
553 auto const backup_pos = ImGui::GetCursorScreenPos();
554 ImGuiStyle& style = ImGui::GetStyle();
555 ImGui::SetCursorScreenPos(
556 ImVec2(combo_pos.x + style.FramePadding.x, combo_pos.y));
557 ImGui::Image((void*)(std::intptr_t)setting.c->tex_2d.id(),
558 ImVec2(256, 20));
559 ImGui::SetCursorScreenPos(backup_pos);
560
561 if (ImGui::Button("Rescale")) {
562 rescale_current_property(grid);
563 }
564 }
565 }
566 //----------------------------------------------------------------------------
568 auto const name = selected_settings_name();
569 auto& setting = settings[name];
570 auto min_scalar = std::numeric_limits<GLfloat>::max();
571 auto max_scalar = -std::numeric_limits<GLfloat>::max();
572 if (prop_holds_scalar(selected_property)) {
573 retrieve_typed_prop(selected_property, [&](auto const& prop) {
574 using prop_type = std::decay_t<decltype(prop)>;
575 using value_type = typename prop_type::value_type;
576 if constexpr (is_arithmetic<value_type>) {
577 grid.vertices().iterate_indices([&](auto const... is) {
578 auto const p = prop.at(is...);
579 min_scalar = std::min<GLfloat>(min_scalar, p);
580 max_scalar = std::max<GLfloat>(max_scalar, p);
581 });
582 }
583 });
584 } else if (prop_holds_vector(selected_property)) {
585 retrieve_typed_prop(selected_property, [&](auto const& prop) {
586 using prop_type = std::decay_t<decltype(prop)>;
587 using value_type = typename prop_type::value_type;
588 if constexpr (static_vec<value_type>) {
589 auto constexpr num_comps = value_type::num_components();
590 grid.vertices().iterate_indices([&](auto const... is) {
591 auto const p = prop.at(is...);
592 if (selected_component.at(*selected_property_name) ==
593 vector_component_names[0]) {
594 auto mag = typename value_type::value_type{};
595 for (std::size_t i = 0; i < num_comps; ++i) {
596 mag += p(i) * p(i);
597 }
598 mag = std::sqrt(mag);
599 min_scalar = std::min<GLfloat>(min_scalar, mag);
600 max_scalar = std::max<GLfloat>(max_scalar, mag);
601 } else {
602 auto s = typename value_type::value_type{};
603 if (selected_component.at(*selected_property_name) ==
604 vector_component_names[1]) {
605 s = p.x();
606 } else if (selected_component.at(*selected_property_name) ==
607 vector_component_names[2]) {
608 s = p.y();
609 } else if (selected_component.at(*selected_property_name) ==
610 vector_component_names[3]) {
611 if constexpr (value_type::num_components() > 2) {
612 s = p.z();
613 }
614 } else if (selected_component.at(*selected_property_name) ==
615 vector_component_names[4]) {
616 if constexpr (value_type::num_components() > 3) {
617 s = p.w();
618 }
619 }
620 min_scalar = std::min<GLfloat>(min_scalar, s);
621 max_scalar = std::max<GLfloat>(max_scalar, s);
622 }
623 });
624 }
625 });
626 }
627 setting.min_scalar = min_scalar;
628 setting.max_scalar = max_scalar;
629 }
630 //----------------------------------------------------------------------------
632 ImGui::Text("Rectilinear Grid");
633 ImGui::Checkbox("Show Grid", &show_grid);
634 ImGui::Checkbox("Show Property", &show_property);
635 ImGui::DragInt("Line width", &line_width, 1, 1, 20);
636 ImGui::ColorEdit4("Grid Color", grid_color.data());
637 grid_property_selection(grid);
638 if (selected_property != nullptr && vector_property) {
639 vector_component_selection(grid);
640 }
641 if (selected_property != nullptr) {
642 auto& setting = settings[selected_settings_name()];
643 ImGui::DragFloat("Min", &setting.min_scalar, 0.01f, -FLT_MAX,
644 setting.max_scalar, "%.06f");
645 ImGui::DragFloat("Max", &setting.max_scalar, 0.01f, setting.min_scalar,
646 FLT_MAX, "%.06f");
647 }
648
649 color_scale_selection(grid);
650 }
651 //============================================================================
652 auto render() {
653 if (show_grid) {
654 render_grid();
655 }
656 if (show_property && selected_property != nullptr) {
657 render_property();
658 }
659 }
660 //----------------------------------------------------------------------------
661 auto update(auto const dt, renderable_type const& grid,
662 camera auto const& cam) {
663 using CamReal = typename std::decay_t<decltype(cam)>::real_type;
664 static auto constexpr cam_is_float = is_same<GLfloat, CamReal>;
665 if (show_grid) {
666 if constexpr (cam_is_float) {
667 line_shader::get().set_projection_matrix(cam.projection_matrix());
668 } else {
669 line_shader::get().set_projection_matrix(
670 Mat4<GLfloat>{cam.projection_matrix()});
671 }
672
673 if constexpr (cam_is_float) {
674 line_shader::get().set_model_view_matrix(cam.view_matrix());
675 } else {
676 line_shader::get().set_model_view_matrix(
677 Mat4<GLfloat>{cam.view_matrix()});
678 }
679 }
680 if (show_property) {
681 if constexpr (cam_is_float) {
682 property_shader::get().set_projection_matrix(cam.projection_matrix());
683 } else {
684 property_shader::get().set_projection_matrix(
685 Mat4<GLfloat>{cam.projection_matrix()});
686 }
687
688 if constexpr (cam_is_float) {
689 property_shader::get().set_model_view_matrix(
690 cam.view_matrix() *
691 translation_matrix<GLfloat>(grid.template dimension<0>().front(),
692 grid.template dimension<1>().front(),
693 0) *
694 scale_matrix<GLfloat>(grid.template extent<0>(),
695 grid.template extent<1>(), 1));
696 } else {
697 property_shader::get().set_model_view_matrix(
698 Mat4<GLfloat>{cam.view_matrix()} *
699 scale_matrix<GLfloat>(grid.template extent<0>(),
700 grid.template extent<1>(), 1) *
701 translation_matrix<GLfloat>(grid.template dimension<0>().front(),
702 grid.template dimension<1>().front(),
703 0));
704 }
705 property_shader::get().set_extent(Vec2<GLfloat>{grid.extent()});
706 property_shader::get().set_pixel_width(Vec2<GLfloat>{
707 grid.template dimension<0>()[1] - grid.template dimension<0>()[0],
708 grid.template dimension<1>()[1] - grid.template dimension<1>()[0]});
709 }
710 }
711 //----------------------------------------------------------------------------
712 auto render_grid() {
715
716 line_shader.set_color(grid_color(0), grid_color(1), grid_color(2),
717 grid_color(3));
718 gl::line_width(line_width);
719 geometry.draw_lines();
720 }
721 //----------------------------------------------------------------------------
723 property_shader::get().bind();
724 tex.bind(0);
725 if (selected_property_name != nullptr) {
726 auto const name = selected_settings_name();
727 auto& setting = settings.at(name);
728 property_shader::get().set_min(setting.min_scalar);
729 property_shader::get().set_max(setting.max_scalar);
730 property_shader::get().invert_scale(setting.scale_inverted);
731 setting.c->tex.bind(1);
732 geometry::get().draw_triangles();
733 }
734 }
735};
736//==============================================================================
737} // namespace tatooine::rendering::interactive
738//==============================================================================
739#endif
Definition: indexeddata.h:13
Definition: shader.h:24
DLL_API void bind() const
Definition: grid_edge.h:16
Definition: rectilinear_grid.h:38
Definition: camera.h:312
Definition: tensor_concepts.h:23
auto ToggleButton(const char *str_id, bool *v) -> bool
Definition: interactive.h:15
Definition: algorithm.h:6
typename get_impl< Container, I >::type get
Definition: get.h:11
typename value_type_impl< T >::type value_type
Definition: type_traits.h:280
auto end(Range &&range)
Definition: iterator_facade.h:322
constexpr auto max(A &&a, B &&b)
Definition: math.h:20
rectilinear_grid(Dimensions &&...) -> rectilinear_grid< std::decay_t< Dimensions >... >
constexpr auto min(A &&a, B &&b)
Definition: math.h:15
Definition: GYPi.h:12
Definition: viridis.h:12
static constexpr GLsizei num_components
Definition: texcomponents.h:10
Definition: shadersource.h:8
Definition: mat.h:14
static auto viridis() -> auto &
Definition: color_scale.h:82
auto set_model_view_matrix(Mat4< GLfloat > const &MV) -> void
Definition: rectilinear_grid3.h:154
auto set_pixel_width(Vec2< GLfloat > const &pixel_width) -> void
Definition: rectilinear_grid3.h:162
auto set_projection_matrix(Mat4< GLfloat > const &P) -> void
Definition: rectilinear_grid3.h:150
auto set_extent(Vec2< GLfloat > const &extent) -> void
Definition: rectilinear_grid3.h:158
auto vector_component_selection(renderable_type const &grid)
Definition: rectilinear_grid3.h:476
gl::indexeddata< vec3f > m_right_geometry
Definition: rectilinear_grid3.h:199
auto init_properties(renderable_type const &grid)
Definition: rectilinear_grid3.h:241
gl::indexeddata< vec3f > m_bottom_geometry
Definition: rectilinear_grid3.h:201
auto upload_x_to_texture(auto &&prop, renderable_type const &grid)
Definition: rectilinear_grid3.h:373
auto update(auto const dt, renderable_type const &grid, camera auto const &cam)
Definition: rectilinear_grid3.h:661
auto prop_holds_vector(auto const &prop)
Definition: rectilinear_grid3.h:325
auto grid_property_selection(renderable_type const &grid)
Definition: rectilinear_grid3.h:446
auto properties(renderable_type const &grid)
Definition: rectilinear_grid3.h:631
gl::indexeddata< vec3f > m_top_geometry
Definition: rectilinear_grid3.h:200
auto upload_scalar_to_texture(auto &&prop, renderable_type const &grid)
Definition: rectilinear_grid3.h:341
auto upload_z_to_texture(auto &&prop, renderable_type const &grid)
Definition: rectilinear_grid3.h:399
auto rescale_current_property(renderable_type const &grid)
Definition: rectilinear_grid3.h:567
auto upload_data_to_texture(auto &&prop, auto &&get_data, renderable_type const &grid)
Definition: rectilinear_grid3.h:331
auto prop_holds_scalar(auto const &prop)
Definition: rectilinear_grid3.h:321
auto retrieve_typed_prop(auto &&prop, auto &&f)
Definition: rectilinear_grid3.h:301
renderer(renderable_type const &grid)
Definition: rectilinear_grid3.h:207
auto upload_magnitude_to_texture(auto &&prop, renderable_type const &grid)
Definition: rectilinear_grid3.h:354
auto upload_w_to_texture(auto &&prop, renderable_type const &grid)
Definition: rectilinear_grid3.h:416
gl::indexeddata< vec3f > m_outer_geometry
Definition: rectilinear_grid3.h:197
auto color_scale_selection(renderable_type const &grid)
Definition: rectilinear_grid3.h:517
gl::indexeddata< vec3f > m_left_geometry
Definition: rectilinear_grid3.h:198
auto upload_y_to_texture(auto &&prop, renderable_type const &grid)
Definition: rectilinear_grid3.h:386
gl::indexeddata< vec3f > m_back_geometry
Definition: rectilinear_grid3.h:203
gl::indexeddata< vec3f > m_front_geometry
Definition: rectilinear_grid3.h:202
typename renderable_type::typed_vertex_property_interface_t< T > typed_vertex_property_interface_t
Definition: rectilinear_grid3.h:21
auto init_grid_geometry(renderable_type const &grid)
Definition: rectilinear_grid3.h:212
static auto cast_prop(auto &&prop)
Definition: rectilinear_grid3.h:297
cook_torrance_brdf_shader property_shader
Definition: unstructured_triangular_grid3.h:25
auto set_color(GLfloat r, GLfloat g, GLfloat b, GLfloat a=1) -> void
Definition: shaders.h:85
typename parent_t::template vertex_property_t< T > vertex_property_t
Definition: unstructured_grid.h:21
Definition: vec.h:12
Definition: property.h:16