From 0534c4322c6078fc7182ca8c41ef25729ee96ba8 Mon Sep 17 00:00:00 2001 From: David Allemang Date: Sun, 11 Oct 2020 18:55:43 -0400 Subject: [PATCH] Refactor Slice / SliceRenderer to be less general; get away from "prop" overhead. --- vis/CMakeLists.txt | 8 +-- vis/include/geometry.hpp | 27 ++++++++ vis/include/mirror.hpp | 27 +------- vis/include/rendering.hpp | 101 +++++++++++++++++++++-------- vis/src/{main-gui.cpp => main.cpp} | 97 ++++++--------------------- 5 files changed, 126 insertions(+), 134 deletions(-) rename vis/src/{main-gui.cpp => main.cpp} (51%) diff --git a/vis/CMakeLists.txt b/vis/CMakeLists.txt index e5b21a2..862655e 100644 --- a/vis/CMakeLists.txt +++ b/vis/CMakeLists.txt @@ -15,7 +15,7 @@ add_custom_command( add_definitions(${NANOGUI_EXTRA_DEFS}) include_directories(${NANOGUI_EXTRA_INCS}) -add_executable(vis-gui src/main-gui.cpp) -target_include_directories(vis-gui PRIVATE include) -target_link_libraries(vis-gui PRIVATE tc nanogui yaml-cpp ${NANOGUI_EXTRA_LIBS}) -add_dependencies(vis-gui shaders presets) +add_executable(vis src/main.cpp) +target_include_directories(vis PRIVATE include) +target_link_libraries(vis PRIVATE tc nanogui yaml-cpp ${NANOGUI_EXTRA_LIBS}) +add_dependencies(vis shaders presets) diff --git a/vis/include/geometry.hpp b/vis/include/geometry.hpp index 8f4f7bb..808ad2d 100644 --- a/vis/include/geometry.hpp +++ b/vis/include/geometry.hpp @@ -7,6 +7,33 @@ #include #include "combo_iterator.hpp" +template +using vec = Eigen::Matrix; +template +using mat = Eigen::Matrix; + +using vec1 = vec<1>; +using vec2 = vec<2>; +using vec3 = vec<3>; +using vec4 = vec<4>; +using vec5 = vec<5>; + +using mat1 = mat<1>; +using mat2 = mat<2>; +using mat3 = mat<3>; +using mat4 = mat<4>; +using mat5 = mat<5>; + +mat4 ortho(float left, float right, float bottom, float top, float front, float back) { + mat<4> res = mat4(); + res << + 2 / (right - left), 0, 0, -(right + left) / (right - left), + 0, 2 / (top - bottom), 0, -(top + bottom) / (top - bottom), + 0, 0, 2 / (front - back), -(front + back) / (front - back), + 0, 0, 0, 1; + return res; +} + /** * An primitive stage N indices. * @tparam N diff --git a/vis/include/mirror.hpp b/vis/include/mirror.hpp index 4affe75..7af6d15 100644 --- a/vis/include/mirror.hpp +++ b/vis/include/mirror.hpp @@ -8,22 +8,7 @@ #include -template -using vec = Eigen::Matrix; -template -using mat = Eigen::Matrix; - -using vec1 = vec<1>; -using vec2 = vec<2>; -using vec3 = vec<3>; -using vec4 = vec<4>; -using vec5 = vec<5>; - -using mat1 = mat<1>; -using mat2 = mat<2>; -using mat3 = mat<3>; -using mat4 = mat<4>; -using mat5 = mat<5>; +#include template float dot(int n, const V &a, const V &b) { @@ -143,13 +128,3 @@ mat rot(int u, int v, float theta) { res(v, v) = std::cos(theta); return res; } - -mat4 ortho(float left, float right, float bottom, float top, float front, float back) { - mat<4> res = mat4(); - res << - 2 / (right - left), 0, 0, -(right + left) / (right - left), - 0, 2 / (top - bottom), 0, -(top + bottom) / (top - bottom), - 0, 0, 2 / (front - back), -(front + back) / (front - back), - 0, 0, 0, 1; - return res; -} \ No newline at end of file diff --git a/vis/include/rendering.hpp b/vis/include/rendering.hpp index 875a268..3e0fa17 100644 --- a/vis/include/rendering.hpp +++ b/vis/include/rendering.hpp @@ -3,49 +3,98 @@ #include #include #include + #include +#include "mirror.hpp" -#include +struct Matrices { + mat4 proj = mat4::Identity(); + mat4 view = mat4::Identity(); -template -struct Prop { - cgl::VertexArray vao; - std::tuple...> vbos; + Matrices() = default; + + Matrices(mat4 proj, mat4 view) : proj(std::move(proj)), view(std::move(view)) {} + + static Matrices build(const nanogui::Screen &screen) { + auto aspect = (float) screen.width() / (float) screen.height(); + auto pheight = 1.4f; + auto pwidth = aspect * pheight; + mat4 proj = ortho(-pwidth, pwidth, -pheight, pheight, -10.0f, 10.0f); + + auto view = mat4::Identity(); + return Matrices(proj, view); + } +}; + +template +class Renderer { +public: + virtual void draw(const T &prop) const = 0; +}; + +template +class Slice { +private: + const tc::Group group; + +public: cgl::Buffer> ibo; + cgl::Buffer vbo; + cgl::VertexArray vao; + + template + Slice(const tc::Group &g, T all_sg_gens, const std::vector> &exclude) : group(g) { + ibo.put(merge(hull(g, all_sg_gens, exclude))); + vao.ipointer(0, ibo, 4, GL_UNSIGNED_INT); + } + + void setPoints(const vec5 &root, mat5 transform = mat5::Identity()) { + auto cosets = group.solve(); + auto mirrors = mirror<5>(group); + + auto corners = plane_intersections(mirrors); + auto start = barycentric(corners, root); + + auto higher = cosets.path.walk(start, mirrors, reflect); + + std::transform( + higher.begin(), higher.end(), higher.begin(), + [&](const vec5& v) { return transform * v; } + ); + + std::vector lower(higher.size()); + std::transform(higher.begin(), higher.end(), lower.begin(), stereo<4>); + + vbo.put(lower); + } }; -template -struct Renderer { - cgl::pipeline pipe; - - virtual void draw(const Prop &prop) const = 0; -}; - -template -struct SliceRenderer : public Renderer { +template +class SliceRenderer : public Renderer> { +private: cgl::pgm::vert defer = cgl::pgm::vert::file( - "shaders/slice/deferred.vs.glsl"); + "shaders/slice/deferred.vs.glsl"); cgl::pgm::geom slice = cgl::pgm::geom::file( - "shaders/slice/slice.gm.glsl"); + "shaders/slice/slice.gm.glsl"); cgl::pgm::frag solid = cgl::pgm::frag::file( - "shaders/solid.fs.glsl"); + "shaders/solid.fs.glsl"); cgl::pipeline pipe; + cgl::Buffer ubo; + +public: SliceRenderer() { pipe.stage(defer); pipe.stage(slice); pipe.stage(solid); } - void draw(const Prop &prop) const override { - pipe.bound([&]() { - glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, std::get<0>(prop.vbos)); -//// glProgramUniform3fv(solid, 2, 1, &prop.color.front()); - glProgramUniform3f(solid, 2, 1.f, 1.f, 1.f); - prop.vao.bound([&]() { - glDrawArrays(GL_POINTS, 0, prop.ibo.count() * N); - }); - }); + void draw(const Slice &prop) const { + glBindProgramPipeline(pipe); + glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, prop.vbo); + glProgramUniform3f(solid, 2, 1.f, 1.f, 1.f); + glBindVertexArray(prop.vao); + glDrawArrays(GL_POINTS, 0, prop.ibo.count() * N); } }; diff --git a/vis/src/main-gui.cpp b/vis/src/main.cpp similarity index 51% rename from vis/src/main-gui.cpp rename to vis/src/main.cpp index 99f0e6d..0ce42cb 100644 --- a/vis/src/main-gui.cpp +++ b/vis/src/main.cpp @@ -1,16 +1,3 @@ -/* - src/example4.cpp -- C++ version of an example application that shows - how to use the OpenGL widget. For a Python implementation, see - '../python/example4.py'. - - NanoGUI was developed by Wenzel Jakob . - The widget drawing code is based on the NanoVG demo application - by Mikko Mononen. - - All rights reserved. Use of this source code is governed by a - BSD-style license that can be found in the LICENSE.txt file. -*/ - #include #include #include @@ -25,35 +12,7 @@ #include #include -struct Matrices { - mat4 proj = mat4::Identity(); - mat4 view = mat4::Identity(); - - Matrices() = default; - - Matrices(mat4 proj, mat4 view) : proj(std::move(proj)), view(std::move(view)) {} - - static Matrices build(const nanogui::Screen &screen) { - auto aspect = (float) screen.width() / (float) screen.height(); - auto pheight = 1.4f; - auto pwidth = aspect * pheight; - mat4 proj = ortho(-pwidth, pwidth, -pheight, pheight, -10.0f, 10.0f); - - auto view = mat4::Identity(); - return Matrices(proj, view); - } -}; - -template -std::vector points(const tc::Group &group, const C &coords, const float time) { - auto cosets = group.solve(); - auto mirrors = mirror<5>(group); - - auto corners = plane_intersections(mirrors); - auto start = barycentric(corners, coords); - - auto higher = cosets.path.walk(start, mirrors, reflect); - +mat5 wander(float time) { mat5 r = mat5::Identity(); r *= rot<5>(0, 2, time * .21f); // r *= rot<5>(1, 4, time * .27f); @@ -62,37 +21,18 @@ std::vector points(const tc::Group &group, const C &coords, const float ti r *= rot<5>(1, 3, time * .25f); r *= rot<5>(2, 3, time * .12f); - std::transform(higher.begin(), higher.end(), higher.begin(), [&](vec5 v) { return r * v; }); - - std::vector lower(higher.size()); - std::transform(higher.begin(), higher.end(), lower.begin(), stereo<4>); - return lower; -} - -template -Prop<4, vec4> make_slice( - const tc::Group &g, - const C &coords, - vec3 color, - T all_sg_gens, - const std::vector> &exclude -) { - Prop res{}; - -// res.vbo.put(points(g, coords)); - res.ibo.put(merge(hull(g, all_sg_gens, exclude))); - res.vao.ipointer(0, res.ibo, 4, GL_UNSIGNED_INT); - - return res; + return r; } class ExampleApplication : public nanogui::Screen { public: vec5 root; - std::unique_ptr group; - std::unique_ptr> prop; + +// std::unique_ptr group; + std::unique_ptr> ren; std::unique_ptr> ubo; - std::unique_ptr> ren; + + std::unique_ptr> slice; float glfw_time = 0; float last_frame = 0; @@ -123,19 +63,19 @@ public: std::cout << utilInfo(); - std::vector symbol = {5, 3, 3, 2}; + std::vector symbol = {3, 4, 3, 2}; root << .80, .02, .02, .02, .02; - group = std::make_unique(tc::schlafli(symbol)); - auto gens = generators(*group); - std::vector> exclude = {{0, 1, 2}}; - auto combos = Combos(gens, 3); + auto group = tc::schlafli(symbol); - prop = std::make_unique>(make_slice<4>(*group, root, {}, combos, exclude)); + auto gens = generators(group); + auto combos = Combos(gens, 3); + std::vector> exclude = {{0, 1, 2}}; + + slice = std::make_unique>(group, combos, exclude); + ren = std::make_unique>(); ubo = std::make_unique>(); - - ren = std::make_unique>(); } void drawContents() override { @@ -154,16 +94,17 @@ public: last_frame = glfw_time; if (!paused) time += frame_time; - std::get<0>(prop->vbos).put(points(*group, root, time)); + auto rotation = wander(time); + slice->setPoints(root, rotation); Matrices mats = Matrices::build(*this); glBindBufferBase(GL_UNIFORM_BUFFER, 1, *ubo); ubo->put(mats); - ren->draw(*prop); + ren->draw(*slice); } }; -int main(int /* argc */, char ** /* argv */) { +int main(int argc, char ** argv) { try { nanogui::init();