diff --git a/cosets/CMakeLists.txt b/cosets/CMakeLists.txt index c36d9be..0df1610 100644 --- a/cosets/CMakeLists.txt +++ b/cosets/CMakeLists.txt @@ -12,6 +12,7 @@ add_executable(${PROJECT_NAME} add_dependencies(cosets shaders) target_link_libraries(${PROJECT_NAME} PRIVATE glad glm glfw) +target_compile_options(${PROJECT_NAME} PRIVATE -O3) add_executable(coxeter src/coxeter.cpp) diff --git a/cosets/src/main.cpp b/cosets/src/main.cpp index 15b8336..86d02ab 100644 --- a/cosets/src/main.cpp +++ b/cosets/src/main.cpp @@ -13,14 +13,17 @@ using namespace std; class CosetsWindow : public Window { GLint program; - GLuint points_vao, edges_vao; + GLuint vert_vao, edge_vao, face_vao; GLuint verts_buf; - std::vector verts_data; + std::vector vert_data; GLuint edges_buf; std::vector edge_data; + GLuint faces_buf; + std::vector face_data; + public: void init() override { auto vs = build_shader_file( @@ -35,33 +38,47 @@ public: program = build_program("main", vs, fs); - const Mults &mults = schlafli<4>({3, 4, 3}); - verts_data = vertices<4>(mults, {10, 1, 1, 1}); - edge_data = edges<4>(mults); + const int N = 3; + const Mults &mults = schlafli({5, 3}); + vert_data = vertices(mults, {5, 1, 1}); + edge_data = edges(mults); + face_data = faces(mults); glGenBuffers(1, &verts_buf); glBindBuffer(GL_ARRAY_BUFFER, verts_buf); - glBufferData(GL_ARRAY_BUFFER, sizeof(glm::vec4) * verts_data.size(), &verts_data[0], GL_STATIC_DRAW); + glBufferData(GL_ARRAY_BUFFER, sizeof(glm::vec4) * vert_data.size(), &vert_data[0], GL_STATIC_DRAW); glGenBuffers(1, &edges_buf); glBindBuffer(GL_ARRAY_BUFFER, edges_buf); glBufferData(GL_ARRAY_BUFFER, sizeof(int) * edge_data.size(), &edge_data[0], GL_STATIC_DRAW); - glGenVertexArrays(1, &points_vao); - glBindVertexArray(points_vao); + glGenBuffers(1, &faces_buf); + glBindBuffer(GL_ARRAY_BUFFER, faces_buf); + glBufferData(GL_ARRAY_BUFFER, sizeof(int) * face_data.size(), &face_data[0], GL_STATIC_DRAW); + + glGenVertexArrays(1, &vert_vao); + glBindVertexArray(vert_vao); glBindBuffer(GL_ARRAY_BUFFER, verts_buf); glEnableVertexAttribArray(0); glVertexAttribPointer(0, 4, GL_FLOAT, false, 0, nullptr); glBindBuffer(GL_ARRAY_BUFFER, 0); - glGenVertexArrays(1, &edges_vao); - glBindVertexArray(edges_vao); + glGenVertexArrays(1, &edge_vao); + glBindVertexArray(edge_vao); glBindBuffer(GL_ARRAY_BUFFER, verts_buf); glEnableVertexAttribArray(0); glVertexAttribPointer(0, 4, GL_FLOAT, false, 0, nullptr); glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, edges_buf); + glGenVertexArrays(1, &face_vao); + glBindVertexArray(face_vao); + glBindBuffer(GL_ARRAY_BUFFER, verts_buf); + glEnableVertexAttribArray(0); + glVertexAttribPointer(0, 4, GL_FLOAT, false, 0, nullptr); + glBindBuffer(GL_ARRAY_BUFFER, 0); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, faces_buf); + glBindVertexArray(0); } @@ -90,22 +107,32 @@ public: glEnable(GL_POINT_SMOOTH); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glPointSize(10.f); + glPointSize(6.0f); + glLineWidth(3.0f); + glEnable(GL_CULL_FACE); - glBindVertexArray(points_vao); + glBindVertexArray(vert_vao); glUniform4f(0, 1, 1, 1, 1); - glDrawArrays(GL_POINTS, 0, verts_data.size()); +// glDrawArrays(GL_POINTS, 0, vert_data.size()); - glBindVertexArray(edges_vao); - glUniform4f(0, 1, 1, 0, 1); + glBindVertexArray(edge_vao); + glUniform4f(0, 1, 0, 0, 1); glDrawElements(GL_LINES, edge_data.size(), GL_UNSIGNED_INT, 0); + glBindVertexArray(face_vao); + glCullFace(GL_BACK); + glUniform4f(0, .3, .3, .3, 1); + glDrawElements(GL_TRIANGLES, face_data.size(), GL_UNSIGNED_INT, 0); + glCullFace(GL_FRONT); + glUniform4f(0, .8, .8, .8, 1); + glDrawElements(GL_TRIANGLES, face_data.size(), GL_UNSIGNED_INT, 0); + swapbuffers(); } void deinit() override { glDeleteProgram(program); - glDeleteVertexArrays(1, &points_vao); + glDeleteVertexArrays(1, &vert_vao); } }; diff --git a/cosets/src/shaders/main.vs.glsl b/cosets/src/shaders/main.vs.glsl index a9269cc..f48f250 100644 --- a/cosets/src/shaders/main.vs.glsl +++ b/cosets/src/shaders/main.vs.glsl @@ -13,7 +13,7 @@ void main(){ vec4 vert = view * pos; /* stereographic projection */ - vert = vec4(vert.xyw / (1 - vert.z), 1); + vert = vec4(vert.xyz / (1 - vert.w), 1); screen = gl_Position = proj * vert; } diff --git a/cosets/src/util/mesh.hpp b/cosets/src/util/mesh.hpp index 01a666b..07e552e 100644 --- a/cosets/src/util/mesh.hpp +++ b/cosets/src/util/mesh.hpp @@ -45,22 +45,70 @@ template std::vector edges(const Mults &mults) { std::vector res{}; - Table *verts = solve({}, mults); + Table *t_vert = solve({}, mults); - int K = 1; - for (const auto &subgens : combinations(N, K)) { - Table *edge = solve(subgens, {}, mults); + for (const auto &subgens : combinations(N, 1)) { + Table *t_edge = solve(subgens, {}, mults); - std::vector primitive = verts->apply_each(edge->words()); + std::vector edge = t_vert->apply_each(t_edge->words()); - Table *cosets = solve(subgens, mults); + Table *c_edge = solve(subgens, mults); - for (const auto &coset : cosets->words()) { - for (const auto &e : primitive) { - res.push_back(verts->apply(e, coset)); + for (const auto &coset : c_edge->words()) { + for (const auto &e : edge) { + res.push_back(t_vert->apply(e, coset)); } } } return res; } + +template +std::vector faces(const Mults &mults) { + std::vector res{}; + + Table *t_vert = solve({}, mults); + + // for each *kind* of face + for (const auto &sg_face : combinations(N, 2)) { + Table *cs_face = solve(sg_face, mults); + + // for each *kind* of edge + for (const auto &sg_edge : combinations(sg_face, 1)) { + Table *cs_edge = solve(sg_face, sg_edge, mults); + + // find the vertices of that edge + Table *t_edge = solve(sg_edge, {}, mults); + std::vector edge = t_vert->apply_each(t_edge->words()); + + // for each face + for (const auto &c_face : cs_face->words()) { + // for each edge + for (const auto &c_edge : cs_edge->words()) { + if (c_edge.empty()) { continue; } + + for (auto e : edge) { + e = t_vert->apply(e, c_edge); + e = t_vert->apply(e, c_face); + res.push_back(e); + } + res.push_back(t_vert->apply(0, c_face)); + + int s = 0; + s += c_edge.size(); + s += c_face.size(); + s += sg_edge[0]; + s += sg_face[0] + sg_face[1]; + + if (s % 2 == 0) { + std::swap(res[res.size() - 1], res[res.size() - 2]); + } + } +// break; + } + } + } + + return res; +} \ No newline at end of file diff --git a/cosets/src/util/numeric.hpp b/cosets/src/util/numeric.hpp index 064892c..7423ce0 100644 --- a/cosets/src/util/numeric.hpp +++ b/cosets/src/util/numeric.hpp @@ -77,3 +77,19 @@ std::vector> combinations(int N, int K) { return combos; } + +std::vector> combinations(std::vector N, int K) { + std::vector> inds = combinations(N.size(), K); + std::vector> res{}; + + for (const auto &combo: inds) { + std::vector vals{}; + vals.reserve(combo.size()); + for (const auto &i: combo) { + vals.push_back(N[i]); + } + res.push_back(vals); + } + + return res; +} \ No newline at end of file