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..37e45ee 100644 --- a/cosets/src/main.cpp +++ b/cosets/src/main.cpp @@ -13,14 +13,19 @@ 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; + + GLint u_proj, u_view, u_color; + public: void init() override { auto vs = build_shader_file( @@ -35,34 +40,58 @@ 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); + u_proj = glGetUniformLocation(program, "proj"); + u_view = glGetUniformLocation(program, "view"); + u_color = glGetUniformLocation(program, "color"); + + const int N = 3; + const Mults &mults = schlafli({5, 3}); + vert_data = vertices(mults, {10, 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); + + std::cout << "verts: " << vert_data.size() << std::endl; + std::cout << "vendor: " << glGetString(GL_VENDOR) << std::endl + << "renderer: " << glGetString(GL_RENDERER) << std::endl + << "version: " << glGetString(GL_VERSION) << std::endl + << "shading version: " << glGetString(GL_SHADING_LANGUAGE_VERSION) << std::endl; } void render() override { @@ -75,7 +104,7 @@ public: const auto ax_1 = glm::vec3(0, 0, 1); const auto ax_2 = glm::vec3(.5, 1, 0.2); const auto t = glfwGetTime(); - const auto angle = (float) t / 2; + const auto angle = (float) t / 5; const float sc = 1.5f; const float ar = (float) w / (float) h; @@ -84,28 +113,38 @@ public: const glm::mat4 view = glm::rotate(id, angle, ax_1) * glm::rotate(id, angle, ax_2); glUseProgram(program); - glUniformMatrix4fv(1, 1, false, glm::value_ptr(proj)); - glUniformMatrix4fv(2, 1, false, glm::value_ptr(view)); + glUniformMatrix4fv(u_proj, 1, false, glm::value_ptr(proj)); + glUniformMatrix4fv(u_view, 1, false, glm::value_ptr(view)); + glEnable(GL_DEPTH_TEST); glEnable(GL_POINT_SMOOTH); glEnable(GL_BLEND); + glEnable(GL_CULL_FACE); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glPointSize(10.f); - glBindVertexArray(points_vao); - glUniform4f(0, 1, 1, 1, 1); - glDrawArrays(GL_POINTS, 0, verts_data.size()); + glPointSize(10.0f); + glLineWidth(5.0f); - glBindVertexArray(edges_vao); - glUniform4f(0, 1, 1, 0, 1); + glBindVertexArray(vert_vao); + glUniform4f(u_color, 1, 0, 0, 1); + glDrawArrays(GL_POINTS, 0, vert_data.size()); + + glBindVertexArray(edge_vao); + glUniform4f(u_color, 1, 0, 0, 1); glDrawElements(GL_LINES, edge_data.size(), GL_UNSIGNED_INT, 0); + glBindVertexArray(face_vao); + glCullFace(GL_BACK); + glUniform4f(u_color, 1, 1, 1, 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.fs.glsl b/cosets/src/shaders/main.fs.glsl index 3bb6869..6fb0d0d 100644 --- a/cosets/src/shaders/main.fs.glsl +++ b/cosets/src/shaders/main.fs.glsl @@ -1,4 +1,4 @@ -#version 440 core +#version 400 core uniform vec4 color; diff --git a/cosets/src/shaders/main.vs.glsl b/cosets/src/shaders/main.vs.glsl index a9269cc..da10d0a 100644 --- a/cosets/src/shaders/main.vs.glsl +++ b/cosets/src/shaders/main.vs.glsl @@ -1,4 +1,4 @@ -#version 440 core +#version 400 core uniform mat4 proj; uniform mat4 view; @@ -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..f534ce9 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)); + + if (c_edge.size() & 1u) + std::swap(res[res.size() - 1], res[res.size() - 2]); + + unsigned ro_si1 = (sg_face[0] + sg_face[1]); + unsigned flag = sg_edge[0] == sg_face[0]; + unsigned n_mirrors = c_face.size(); + + if ((n_mirrors + flag + ro_si1) & 1u) { + std::swap(res[res.size() - 1], res[res.size() - 2]); + } + } + } + } + } + + 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 diff --git a/cosets/src/util/window.hpp b/cosets/src/util/window.hpp index 49dc274..2fb9634 100644 --- a/cosets/src/util/window.hpp +++ b/cosets/src/util/window.hpp @@ -34,7 +34,7 @@ public: glfwWindowHint(GLFW_ALPHA_BITS, 8); - _window = glfwCreateWindow(640, 480, "GLFW App", nullptr, nullptr); + _window = glfwCreateWindow(1920, 1080, "GLFW App", nullptr, nullptr); if (!_window) { fprintf(stderr, "Failed to create window;"); glfwTerminate();