diff --git a/vis/include/cgl/buffer.hpp b/vis/include/cgl/buffer.hpp index 0cc9369..e43e14f 100644 --- a/vis/include/cgl/buffer.hpp +++ b/vis/include/cgl/buffer.hpp @@ -10,20 +10,12 @@ namespace cgl { GLuint id{}; public: + using Element = T; + Buffer() { glCreateBuffers(1, &id); } - Buffer(const T &data, GLenum usage = GL_STATIC_DRAW) - : Buffer() { - put(data, usage); - } - - Buffer(const std::vector &data, GLenum usage = GL_STATIC_DRAW) - : Buffer() { - put(data, usage); - } - Buffer(Buffer &) = delete; Buffer(Buffer &&o) noexcept { @@ -60,12 +52,5 @@ namespace cgl { std::copy(begin, end, (T*) ptr); glUnmapNamedBuffer(id); } - - void bound(GLenum target, const std::function &action) const { - glBindBuffer(target, id); - action(); - glBindBuffer(target, 0); - } }; - } diff --git a/vis/include/cgl/pipeline.hpp b/vis/include/cgl/pipeline.hpp index 209f980..f9e597c 100644 --- a/vis/include/cgl/pipeline.hpp +++ b/vis/include/cgl/pipeline.hpp @@ -83,11 +83,5 @@ namespace cgl { glUseProgramStages(id, GL_COMPUTE_SHADER_BIT, pgm); return *this; } - - void bound(const std::function &action) const { - glBindProgramPipeline(id); - action(); - glBindProgramPipeline(0); - } }; } \ No newline at end of file diff --git a/vis/include/cgl/vertexarray.hpp b/vis/include/cgl/vertexarray.hpp index e9275e7..5f64801 100644 --- a/vis/include/cgl/vertexarray.hpp +++ b/vis/include/cgl/vertexarray.hpp @@ -33,43 +33,34 @@ namespace cgl { return id; } - void bound(const std::function &action) const { - glBindVertexArray(id); - action(); - glBindVertexArray(0); - } - - template - void pointer( + void format( GLuint index, - const Buffer &buf, unsigned size, GLenum type, bool normalized = false, unsigned stride = 0 - ) const { - bound([&]() { - glEnableVertexAttribArray(index); - buf.bound(GL_ARRAY_BUFFER, [&]() { - glVertexAttribPointer(index, size, type, normalized, stride, nullptr); - }); - }); + ) { + glEnableVertexArrayAttrib(id, index); + glVertexArrayAttribFormat(id, index, size, type, normalized, stride); } - template - void ipointer( + void iformat( GLuint index, - const Buffer &buf, unsigned size, GLenum type, unsigned stride = 0 - ) const { - bound([&]() { - glEnableVertexAttribArray(index); - buf.bound(GL_ARRAY_BUFFER, [&]() { - glVertexAttribIPointer(index, size, type, stride, nullptr); - }); - }); + ) { + glEnableVertexArrayAttrib(id, index); + glVertexArrayAttribIFormat(id, index, size, type, stride); + } + + template + void vertexBuffer( + GLuint index, + Buf &buf, + unsigned offset = 0 + ) { + glVertexArrayVertexBuffer(id, index, buf, offset, sizeof(typename Buf::Element)); } }; } \ No newline at end of file diff --git a/vis/src/comps.hpp b/vis/src/comps.hpp new file mode 100644 index 0000000..838a70a --- /dev/null +++ b/vis/src/comps.hpp @@ -0,0 +1,103 @@ +#pragma once + +#include +#include +#include +#include + +#include + +#include + +#include + +#include "mirror.hpp" +#include "geometry.hpp" +#include "solver.hpp" + +#include + +namespace vis { + struct Group { + tc::Group<> group; + vec5 root; + vec3 color; + + std::vector> exclude {{0, 1, 2}}; + }; + + struct VBOs { + cgl::Buffer verts; + cgl::Buffer> ibo; + }; + + void upload_groups(entt::registry ®) { + auto view = reg.view(); + + for (auto [entity, group, vbos]: view.each()) { + auto cosets = group.group.solve(); + auto mirrors = mirror<5>(group.group); + auto corners = plane_intersections(mirrors); + + vec5 start = corners * group.root; + + tc::Path path(cosets, mirrors.colwise()); + + Eigen::Array higher(5, path.order()); + path.walk(start, Reflect(), higher.matrix().colwise().begin()); + + Eigen::Array lower = Stereo()(higher); + + vbos.verts.put(lower.colwise().begin(), lower.colwise().end()); + + // todo generate all, then mask using glMultiDraw. + const size_t N = 4; + + auto gens = generators(group.group); + auto combos = combinations(gens, N - 1); + auto inds = merge(hull(group.group, combos, group.exclude)); + + vbos.ibo.put(inds.begin(), inds.end()); + } + } + + struct SliceRenderer { + cgl::pgm::vert defer = cgl::pgm::vert(shaders::deferred_vs_glsl); + cgl::pgm::geom slice = cgl::pgm::geom(shaders::slice_gm_glsl); + cgl::pgm::frag solid = cgl::pgm::frag(shaders::solid_fs_glsl); + + cgl::pipeline pipe; + + cgl::VertexArray vao; + + SliceRenderer() { + pipe.stage(defer); + pipe.stage(slice); + pipe.stage(solid); + + vao.iformat(0, 4, GL_UNSIGNED_INT); + } + + void operator()(entt::registry ®) { + auto view = reg.view(); + + for (auto [entity, group, vbos]: view.each()) { + const size_t N = 4; + + glBindProgramPipeline(pipe); + + glProgramUniform3fv(solid, 2, 1, group.color.data()); + + glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, vbos.verts); + + vao.vertexBuffer(0, vbos.ibo); + + glBindVertexArray(vao); + glDrawArrays(GL_POINTS, 0, vbos.ibo.count()); + glBindVertexArray(0); + + glBindProgramPipeline(0); + } + } + }; +} diff --git a/vis/src/main.cpp b/vis/src/main.cpp index 0c47865..9b40f5c 100644 --- a/vis/src/main.cpp +++ b/vis/src/main.cpp @@ -7,19 +7,15 @@ #include "util.hpp" #include "mirror.hpp" -#include "solver.hpp" -#include -#include -#include -#include -#include - -#include -#include +#include "comps.hpp" #include +#ifndef NDEBUG +#include +#endif + #ifdef _WIN32 extern "C" { __attribute__((unused)) __declspec(dllexport) int NvOptimusEnablement = 0x00000001; @@ -93,10 +89,7 @@ std::vector points(const tc::Group<> &group, const C &coords) { Eigen::Array higher(5, path.order()); path.walk(start, Reflect(), higher.matrix().colwise().begin()); -// std::vector higher(path.order()); -// path.walk(start, Reflect(), higher.begin()); -// Eigen::Array4Xf lower = higher.topRows<4>().rowwise() / (1 - higher.bottomRows<1>()); Eigen::Array4Xf lower = Stereo()(higher); std::vector vec(lower.cols()); @@ -105,96 +98,6 @@ std::vector points(const tc::Group<> &group, const C &coords) { return vec; } -template -struct Prop { - cgl::VertexArray vao; - cgl::Buffer vbo; - cgl::Buffer> ibo; - - vec3 color; - - Prop() : vao(), vbo(), ibo() {} -}; - -template -struct Renderer { - std::vector> props; - - virtual void bound(const std::function &action) const = 0; - - virtual void _draw(const Prop &) const = 0; - - void render() const { - bound([&]() { - for (const auto &prop: props) { - _draw(prop); - } - }); - } -}; - -template -struct SliceProp : public Prop { - SliceProp(vec3 color) : Prop() { - this->color = color; - } - - SliceProp(SliceProp &) = delete; - - SliceProp(SliceProp &&) noexcept = default; - - template - static SliceProp build( - const tc::Group<> &g, - const C &coords, - vec3 color, - T all_sg_gens, - const std::vector> &exclude - ) { - SliceProp res(color); - - auto pts = points(g, coords); - res.vbo.put(pts.begin(), pts.end()); - auto inds = merge(hull(g, all_sg_gens, exclude)); - res.ibo.put(inds.begin(), inds.end()); - res.vao.ipointer(0, res.ibo, 4, GL_UNSIGNED_INT); - - return res; - } -}; - -template -struct SliceRenderer : public Renderer { - cgl::pgm::vert defer = cgl::pgm::vert(shaders::deferred_vs_glsl); - cgl::pgm::geom slice = cgl::pgm::geom(shaders::slice_gm_glsl); - cgl::pgm::frag solid = cgl::pgm::frag(shaders::solid_fs_glsl); - - cgl::pipeline pipe; - - SliceRenderer() { - pipe.stage(defer); - pipe.stage(slice); - pipe.stage(solid); - } - - SliceRenderer(SliceRenderer &) = delete; - - SliceRenderer(SliceRenderer &&) noexcept = default; - - void bound(const std::function &action) const override { - pipe.bound(action); - } - - void _draw(const Prop &prop) const override { - glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, prop.vbo); - glProgramUniform3fv(solid, 2, 1, prop.color.data()); -// glProgramUniform3f(solid, 2, 1.f, 1.f, 1.f); - prop.vao.bound([&]() { - glDrawArrays(GL_POINTS, 0, prop.ibo.count() * N); - }); - } -}; - void run(const std::string &config_file, GLFWwindow* window) { #ifndef NDEBUG @@ -207,34 +110,29 @@ void run(const std::string &config_file, GLFWwindow* window) { glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - SliceRenderer<4> sRen{}; + entt::registry registry; + vis::SliceRenderer renderer; State state{}; glfwSetWindowUserPointer(window, &state); - std::cout << "building..." << std::endl; - { - auto group = tc::schlafli({5, 3, 3, 2}); - auto gens = generators(group); - vec5 root; - root << 0.80, 0.09, 0.09, 0.09, 0.04; - vec3 color; - color << 0.90, 0.90, 0.90; - - std::vector> exclude{ - {0, 1, 2}, - }; - - auto combos = combinations(gens, 3); - - sRen.props.push_back(SliceProp<4>::build( - group, root, color, combos, exclude - )); - } - std::cout << "built" << std::endl; - state.dimension = 4; + { + auto entity = registry.create(); + + registry.emplace( + entity, + tc::schlafli({5, 3, 3, 2}), + vec5{0.80, 0.09, 0.09, 0.09, 0.04}, + vec3{0.90, 0.90, 0.90}, + std::vector>{{0, 1, 2}} + ); + registry.emplace(entity); + } + + vis::upload_groups(registry); + auto ubo = cgl::Buffer(); glBindBufferBase(GL_UNIFORM_BUFFER, 1, ubo); @@ -254,7 +152,7 @@ void run(const std::string &config_file, GLFWwindow* window) { glLineWidth(1.5); - sRen.render(); + renderer(registry); glfwSwapInterval(2); glfwSwapBuffers(window);