mirror of
https://github.com/allemangD/toddcox-visualize.git
synced 2025-11-10 03:52:48 -05:00
new solver - point generation
This commit is contained in:
@@ -1,82 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <iostream>
|
||||
#include <ostream>
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
|
||||
#include <Eigen/Eigen>
|
||||
|
||||
namespace ml {
|
||||
using Matrix2Xui = Eigen::Matrix<unsigned int, 2, Eigen::Dynamic>;
|
||||
using Matrix3Xui = Eigen::Matrix<unsigned int, 3, Eigen::Dynamic>;
|
||||
using Matrix4Xui = Eigen::Matrix<unsigned int, 4, Eigen::Dynamic>;
|
||||
|
||||
template<typename PT_, typename CT_>
|
||||
class Mesh {
|
||||
public:
|
||||
using Points = PT_;
|
||||
using Cells = CT_;
|
||||
|
||||
Points points;
|
||||
Cells cells;
|
||||
|
||||
Mesh(Points points, Cells cells)
|
||||
: points(std::move(points)), cells(std::move(cells)) {}
|
||||
};
|
||||
|
||||
auto make_cube(float radius) {
|
||||
Eigen::Matrix3Xf points(3, 8);
|
||||
points.fill(radius);
|
||||
for (int i = 0; i < points.cols(); ++i) {
|
||||
for (int j = 0; j < 3; ++j) {
|
||||
if ((i >> j) & 1) {
|
||||
points(j, i) *= -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Matrix3Xui cells(3, 12);
|
||||
cells.transpose()
|
||||
<< 0b000, 0b001, 0b010, 0b001, 0b010, 0b011,
|
||||
0b100, 0b101, 0b110, 0b101, 0b110, 0b111,
|
||||
|
||||
0b000, 0b001, 0b100, 0b001, 0b100, 0b101,
|
||||
0b010, 0b011, 0b110, 0b011, 0b110, 0b111,
|
||||
|
||||
0b000, 0b010, 0b100, 0b010, 0b100, 0b110,
|
||||
0b001, 0b011, 0b101, 0b011, 0b101, 0b111;
|
||||
|
||||
return Mesh(points, cells);
|
||||
}
|
||||
|
||||
template<size_t Dim>
|
||||
auto make_cube_wire(float radius) {
|
||||
constexpr size_t NPoints = 1 << Dim;
|
||||
constexpr size_t NCells = Dim * (NPoints >> 1);
|
||||
|
||||
Eigen::Matrix<float, Dim, NPoints> points;
|
||||
points.fill(radius);
|
||||
for (int i = 0; i < points.cols(); ++i) {
|
||||
for (int j = 0; j < Dim; ++j) {
|
||||
if ((i >> j) & 1) {
|
||||
points(j, i) *= -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Eigen::Matrix<unsigned int, 2, NCells> cells;
|
||||
int k = 0;
|
||||
for (int i = 0; i < NPoints; ++i) {
|
||||
for (int j = 0; j < Dim; ++j) {
|
||||
if ((i >> j) & 1) {
|
||||
cells(0, k) = i;
|
||||
cells(1, k) = i ^ (1 << j);
|
||||
k++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Mesh(points, cells);
|
||||
}
|
||||
}
|
||||
@@ -1,68 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "meshlib.hpp"
|
||||
|
||||
#include <Eigen/Eigen>
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
namespace Eigen {
|
||||
template<class Derived>
|
||||
void to_json(nlohmann::json &json, const Eigen::PlainObjectBase<Derived> &mat) {
|
||||
using Scalar = typename Derived::Scalar;
|
||||
|
||||
auto rows = mat.rows();
|
||||
auto cols = mat.cols();
|
||||
|
||||
std::vector<Scalar> vals(mat.size());
|
||||
Map<Derived>(vals.data(), rows, cols) = mat;
|
||||
|
||||
json = {
|
||||
{"rows", rows},
|
||||
{"cols", cols},
|
||||
{"vals", vals},
|
||||
};
|
||||
}
|
||||
|
||||
template<class Derived>
|
||||
void from_json(const nlohmann::json &j, Derived &d) {
|
||||
using Scalar = typename Derived::Scalar;
|
||||
|
||||
auto rows = j["rows"].get<Index>();
|
||||
auto cols = j["cols"].get<Index>();
|
||||
auto vals = j["vals"].get<std::vector<Scalar>>();
|
||||
|
||||
d = Map<Derived>(vals.data(), rows, cols);
|
||||
}
|
||||
}
|
||||
|
||||
namespace nlohmann {
|
||||
template<typename PT_, typename CT_>
|
||||
struct adl_serializer<ml::Mesh<PT_, CT_>> {
|
||||
static void to_json(json &j, const ml::Mesh<PT_, CT_> &m) {
|
||||
j = {
|
||||
{"points", m.points},
|
||||
{"cells", m.cells},
|
||||
};
|
||||
}
|
||||
|
||||
static ml::Mesh<PT_, CT_> from_json(const json &j) {
|
||||
return ml::Mesh<PT_, CT_>(
|
||||
j["points"].get<PT_>(),
|
||||
j["cells"].get<CT_>()
|
||||
);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
namespace ml {
|
||||
template<typename PT_, typename CT_>
|
||||
void write(const ml::Mesh<PT_, CT_> &mesh, std::ostream &&out) {
|
||||
nlohmann::json json = mesh;
|
||||
nlohmann::json::to_msgpack(json, out);
|
||||
}
|
||||
|
||||
template<typename M_>
|
||||
M_ read(std::istream &&in) {
|
||||
return nlohmann::json::from_msgpack(in).get<M_>();
|
||||
}
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
#version 440
|
||||
|
||||
layout(location=1) uniform float time;
|
||||
layout(location=2) uniform mat4 proj;
|
||||
layout(location=3) uniform mat4 rot;
|
||||
layout(location=0) in vec3 pos;
|
||||
|
||||
void main() {
|
||||
mat3 rot3 = mat3(rot);
|
||||
vec3 pos3 = rot3 * pos;
|
||||
|
||||
gl_Position = proj * vec4(pos3, 1.0);
|
||||
}
|
||||
282
src/main.cpp
282
src/main.cpp
@@ -1,282 +0,0 @@
|
||||
#include <glad/glad.h>
|
||||
#include <GLFW/glfw3.h>
|
||||
#include <imgui.h>
|
||||
#include <backends/imgui_impl_glfw.h>
|
||||
#include <backends/imgui_impl_opengl3.h>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
|
||||
#include "gl/debug.hpp"
|
||||
#include "gl/buffer.hpp"
|
||||
#include "gl/shader.hpp"
|
||||
#include "gl/vertexarray.hpp"
|
||||
|
||||
#include <ml/meshlib.hpp>
|
||||
#include <ml/meshlib_json.hpp>
|
||||
|
||||
struct State {
|
||||
Eigen::Vector4f bg{0.07f, 0.09f, 0.10f, 1.00f};
|
||||
Eigen::Vector4f fg{0.71f, 0.53f, 0.94f, 1.00f};
|
||||
Eigen::Vector4f wf{0.95f, 0.95f, 0.95f, 1.00f};
|
||||
|
||||
Eigen::Vector4f R{1.00f, 0.00f, 0.00f, 1.00f};
|
||||
Eigen::Vector4f G{0.00f, 1.00f, 0.00f, 1.00f};
|
||||
Eigen::Vector4f B{0.00f, 0.00f, 1.00f, 1.00f};
|
||||
Eigen::Vector4f Y{1.20f, 1.20f, 0.00f, 1.00f};
|
||||
|
||||
Eigen::Matrix4f rot = Eigen::Matrix4f::Identity();
|
||||
|
||||
bool color_axes = false;
|
||||
};
|
||||
|
||||
Eigen::Matrix4f rotor(int u, int v, float rad) {
|
||||
Eigen::Matrix4f res = Eigen::Matrix4f::Identity();
|
||||
res(u, u) = res(v, v) = cosf(rad);
|
||||
res(u, v) = res(v, u) = sinf(rad);
|
||||
res(u, v) *= -1;
|
||||
return res;
|
||||
}
|
||||
|
||||
template<typename T_>
|
||||
T_ mix(const T_ &a, const T_ &b, const typename T_::Scalar &x) {
|
||||
return a * (1 - x) + b * x;
|
||||
}
|
||||
|
||||
void show_overlay(State &state) {
|
||||
static std::string gl_vendor = (const char *) glGetString(GL_VENDOR);
|
||||
static std::string gl_renderer = (const char *) glGetString(GL_RENDERER);
|
||||
static std::string gl_version = (const char *) glGetString(GL_VERSION);
|
||||
static std::string glsl_version = (const char *) glGetString(GL_SHADING_LANGUAGE_VERSION);
|
||||
|
||||
ImGuiWindowFlags window_flags =
|
||||
ImGuiWindowFlags_AlwaysAutoResize |
|
||||
ImGuiWindowFlags_NoSavedSettings |
|
||||
ImGuiWindowFlags_NoFocusOnAppearing |
|
||||
ImGuiWindowFlags_NoNav |
|
||||
ImGuiWindowFlags_NoBringToFrontOnFocus |
|
||||
ImGuiWindowFlags_NoMove;
|
||||
|
||||
ImGuiStyle &style = ImGui::GetStyle();
|
||||
const auto PAD = style.DisplaySafeAreaPadding;
|
||||
auto window_pos = PAD;
|
||||
|
||||
ImGui::SetNextWindowPos(window_pos, ImGuiCond_Always);
|
||||
ImGui::SetNextWindowBgAlpha(0.35f * style.Alpha);
|
||||
ImGui::SetNextWindowCollapsed(true, ImGuiCond_Appearing);
|
||||
ImGui::Begin("Graphics Information", nullptr, window_flags);
|
||||
ImGui::Text("GL Vendor | %s", gl_vendor.c_str());
|
||||
ImGui::Text("GL Renderer | %s", gl_renderer.c_str());
|
||||
ImGui::Text("GL Version | %s", gl_version.c_str());
|
||||
ImGui::Text("GLSL Version | %s", glsl_version.c_str());
|
||||
|
||||
auto v2 = ImGui::GetWindowSize();
|
||||
window_pos.y += v2.y + PAD.y;
|
||||
ImGui::End();
|
||||
|
||||
ImGui::SetNextWindowPos(window_pos, ImGuiCond_Always);
|
||||
ImGui::SetNextWindowBgAlpha(0.35f * style.Alpha);
|
||||
ImGui::Begin("Controls", nullptr, window_flags);
|
||||
|
||||
ImGuiIO &io = ImGui::GetIO();
|
||||
ImGui::Text("FPS | %.2f", io.Framerate);
|
||||
|
||||
ImGui::Separator();
|
||||
|
||||
ImGui::ColorEdit3("Background", state.bg.data(), ImGuiColorEditFlags_Float);
|
||||
ImGui::ColorEdit3("Foreground", state.fg.data(), ImGuiColorEditFlags_Float);
|
||||
ImGui::ColorEdit3("Wireframe", state.wf.data(), ImGuiColorEditFlags_Float);
|
||||
|
||||
ImGui::Checkbox("Show RGBY axis colors", &state.color_axes);
|
||||
|
||||
if (io.MouseDown[0] && !io.WantCaptureMouse) {
|
||||
Eigen::Matrix4f rot = Eigen::Matrix4f::Identity();
|
||||
Eigen::Vector2f del{io.MouseDelta.x, io.MouseDelta.y};
|
||||
del /= 200.0f;
|
||||
|
||||
if (io.KeyShift) {
|
||||
del /= 5.0f;
|
||||
}
|
||||
|
||||
if (io.KeyCtrl) {
|
||||
Eigen::Matrix4f rx = rotor(0, 3, -del.x());
|
||||
Eigen::Matrix4f ry = rotor(1, 3, del.y());
|
||||
rot = rx * ry;
|
||||
} else {
|
||||
Eigen::Matrix4f rx = rotor(0, 2, -del.x());
|
||||
Eigen::Matrix4f ry = rotor(1, 2, del.y());
|
||||
rot = rx * ry;
|
||||
}
|
||||
|
||||
state.rot = rot * state.rot;
|
||||
}
|
||||
|
||||
ImGui::End();
|
||||
}
|
||||
|
||||
void set_style() {
|
||||
ImGui::StyleColorsDark();
|
||||
|
||||
ImGuiStyle &style = ImGui::GetStyle();
|
||||
style.WindowRounding = 4;
|
||||
style.FrameRounding = 2;
|
||||
style.DisplaySafeAreaPadding.x = 10;
|
||||
style.DisplaySafeAreaPadding.y = 10;
|
||||
}
|
||||
|
||||
int run(GLFWwindow *window, ImGuiContext *context) {
|
||||
State state;
|
||||
|
||||
Buffer<GLuint> ind_buf;
|
||||
Buffer<Eigen::Vector4f> vert_buf;
|
||||
|
||||
// Buffer<GLuint> ind4d_buf;
|
||||
// Buffer<Eigen::Vector4f> vert4d_buf;
|
||||
|
||||
VertexArray<Eigen::Vector4f> vao(vert_buf);
|
||||
glVertexArrayElementBuffer(vao, ind_buf);
|
||||
|
||||
// VertexArray<Eigen::Vector4f> vao4d(vert4d_buf);
|
||||
// glVertexArrayElementBuffer(vao4d, ind4d_buf);
|
||||
|
||||
using PointsType = Eigen::Matrix<float, 4, Eigen::Dynamic>;
|
||||
using CellsType = Eigen::Matrix<unsigned, 3, Eigen::Dynamic>;
|
||||
using Mesh = ml::Mesh<PointsType, CellsType>;
|
||||
|
||||
auto mesh = ml::read<Mesh>(std::ifstream("dodeca.pak"));
|
||||
// auto mesh = ml::make_cube(0.22f);
|
||||
auto elements = (GLint) ind_buf.upload(mesh.cells.reshaped());
|
||||
vert_buf.upload(mesh.points.colwise());
|
||||
|
||||
// auto mesh4d = ml::make_cube_wire<4>(0.33f);
|
||||
// auto elements4d = (GLint) ind4d_buf.upload(mesh4d.cells.reshaped());
|
||||
// vert4d_buf.upload(mesh4d.points.colwise());
|
||||
|
||||
// VertexShader vs(std::ifstream("res/shaders/main.vert.glsl"));
|
||||
VertexShader vs4d(std::ifstream("res/shaders/4d.vert.glsl"));
|
||||
FragmentShader fs(std::ifstream("res/shaders/main.frag.glsl"));
|
||||
|
||||
Program pgm(vs4d, fs);
|
||||
// Program pgm4d(vs4d, fs);
|
||||
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
|
||||
Eigen::Projective3f proj;
|
||||
|
||||
while (!glfwWindowShouldClose(window)) {
|
||||
glfwPollEvents();
|
||||
|
||||
ImGui_ImplOpenGL3_NewFrame();
|
||||
ImGui_ImplGlfw_NewFrame();
|
||||
ImGui::NewFrame();
|
||||
show_overlay(state);
|
||||
ImGui::Render();
|
||||
|
||||
int display_w, display_h;
|
||||
glfwGetFramebufferSize(window, &display_w, &display_h);
|
||||
glViewport(0, 0, display_w, display_h);
|
||||
glClearColor(state.bg[0], state.bg[1], state.bg[2], state.bg[3]);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
auto aspect = (float) display_h / (float) display_w;
|
||||
proj = Eigen::AlignedScaling3f(aspect, 1.0, -0.6);
|
||||
|
||||
glUseProgram(pgm);
|
||||
glBindVertexArray(vao);
|
||||
glUniform4fv(0, 1, state.fg.data());
|
||||
glUniform1f(1, (GLfloat) glfwGetTime());
|
||||
glUniformMatrix4fv(2, 1, false, proj.data());
|
||||
glUniformMatrix4fv(3, 1, false, state.rot.data());
|
||||
glDrawElements(GL_TRIANGLES, elements, GL_UNSIGNED_INT, nullptr);
|
||||
glBindVertexArray(0);
|
||||
glUseProgram(0);
|
||||
|
||||
// glUseProgram(pgm4d);
|
||||
// glBindVertexArray(vao4d);
|
||||
// glUniform4fv(0, 1, state.wf.data());
|
||||
// glUniform1f(1, (GLfloat) glfwGetTime());
|
||||
// glUniformMatrix4fv(2, 1, false, proj.data());
|
||||
// glUniformMatrix4fv(3, 1, false, state.rot.data());
|
||||
//
|
||||
// if (state.color_axes) {
|
||||
// auto factor = 0.7f;
|
||||
// auto x = mix(state.wf, state.R, factor);
|
||||
// auto y = mix(state.wf, state.G, factor);
|
||||
// auto z = mix(state.wf, state.B, factor);
|
||||
// auto w = mix(state.wf, state.Y, factor);
|
||||
//
|
||||
// glUniform4fv(0, 1, x.data());
|
||||
// glDrawElementsBaseVertex(GL_LINES, 2, GL_UNSIGNED_INT, (void *) (sizeof(GLuint) * 0), 0);
|
||||
// glUniform4fv(0, 1, y.data());
|
||||
// glDrawElementsBaseVertex(GL_LINES, 2, GL_UNSIGNED_INT, (void *) (sizeof(GLuint) * 2), 0);
|
||||
// glUniform4fv(0, 1, z.data());
|
||||
// glDrawElementsBaseVertex(GL_LINES, 2, GL_UNSIGNED_INT, (void *) (sizeof(GLuint) * 8), 0);
|
||||
// glUniform4fv(0, 1, w.data());
|
||||
// glDrawElementsBaseVertex(GL_LINES, 2, GL_UNSIGNED_INT, (void *) (sizeof(GLuint) * 24), 0);
|
||||
// }
|
||||
//
|
||||
// glUniform4fv(0, 1, state.wf.data());
|
||||
// glDrawElements(GL_LINES, elements4d, GL_UNSIGNED_INT, nullptr);
|
||||
// glBindVertexArray(0);
|
||||
// glUseProgram(0);
|
||||
|
||||
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
|
||||
glfwSwapBuffers(window);
|
||||
}
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
int main() {
|
||||
if (!glfwInit()) {
|
||||
std::cerr << "GLFW:Failed initialization" << std::endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 6);
|
||||
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
|
||||
auto *window = glfwCreateWindow(1280, 720, "Cosets Visualization", nullptr, nullptr);
|
||||
if (!window) {
|
||||
std::cerr << "GLFW:Failed to create window" << std::endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
glfwMakeContextCurrent(window);
|
||||
glfwSwapInterval(1);
|
||||
gladLoadGLLoader((GLADloadproc) glfwGetProcAddress);
|
||||
|
||||
#ifndef NDEBUG
|
||||
glEnable(GL_DEBUG_OUTPUT);
|
||||
glDebugMessageCallback(log_gl_debug_callback, nullptr);
|
||||
glDebugMessageControl(
|
||||
GL_DONT_CARE, GL_DEBUG_TYPE_OTHER,
|
||||
GL_DEBUG_SEVERITY_NOTIFICATION,
|
||||
0, nullptr, GL_FALSE
|
||||
);
|
||||
#endif
|
||||
|
||||
IMGUI_CHECKVERSION();
|
||||
auto *context = ImGui::CreateContext();
|
||||
ImGui_ImplGlfw_InitForOpenGL(window, true);
|
||||
ImGui_ImplOpenGL3_Init("#version 130");
|
||||
|
||||
set_style();
|
||||
|
||||
int exit_code = EXIT_SUCCESS;
|
||||
|
||||
try {
|
||||
exit_code = run(window, context);
|
||||
} catch (const std::exception &e) {
|
||||
std::cerr << e.what() << std::endl;
|
||||
exit_code = EXIT_FAILURE;
|
||||
}
|
||||
|
||||
ImGui_ImplOpenGL3_Shutdown();
|
||||
ImGui_ImplGlfw_Shutdown();
|
||||
ImGui::DestroyContext();
|
||||
|
||||
glfwDestroyWindow(window);
|
||||
glfwTerminate();
|
||||
|
||||
return exit_code;
|
||||
}
|
||||
@@ -1,3 +1,9 @@
|
||||
add_custom_target(resources DEPENDS resources_output)
|
||||
add_custom_command(
|
||||
OUTPUT resources_output
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_CURRENT_SOURCE_DIR}/res ${CMAKE_CURRENT_BINARY_DIR}/res
|
||||
COMMENT "Copying Resources")
|
||||
|
||||
add_executable(vis
|
||||
src/main.cpp
|
||||
)
|
||||
@@ -10,3 +16,5 @@ target_link_libraries(vis
|
||||
eigen
|
||||
nlohmann_json
|
||||
)
|
||||
target_include_directories(vis PUBLIC include)
|
||||
add_dependencies(vis resources)
|
||||
|
||||
@@ -21,7 +21,7 @@ template<unsigned N>
|
||||
std::vector<vec<N>> mirror(const tc::Group &group) {
|
||||
std::vector<std::vector<float>> mirrors;
|
||||
|
||||
for (int p = 0; p < group.ngens; ++p) {
|
||||
for (int p = 0; p < group.rank; ++p) {
|
||||
std::vector<float> vp;
|
||||
for (int m = 0; m < p; ++m) {
|
||||
auto &vq = mirrors[m];
|
||||
@@ -1,5 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
#include <glad/glad.h>
|
||||
#include <fmt/core.h>
|
||||
|
||||
#include <string>
|
||||
|
||||
#ifndef NDEBUG
|
||||
|
||||
void GLAPIENTRY log_gl_debug_callback(
|
||||
15
vis/res/shaders/main.vert.glsl
Normal file
15
vis/res/shaders/main.vert.glsl
Normal file
@@ -0,0 +1,15 @@
|
||||
#version 440
|
||||
|
||||
//layout(location=1) uniform float time;
|
||||
layout(location=2) uniform mat4 proj;
|
||||
//layout(location=3) uniform mat4 rot;
|
||||
|
||||
layout(location=0) in vec4 pos;
|
||||
|
||||
void main() {
|
||||
// mat3 rot3 = mat3(rot);
|
||||
// vec3 pos3 = rot3 * pos;
|
||||
|
||||
vec3 pos3 = pos.xyz;
|
||||
gl_Position = proj * vec4(pos3, 1.0);
|
||||
}
|
||||
212
vis/src/main.cpp
212
vis/src/main.cpp
@@ -3,28 +3,193 @@
|
||||
#include <imgui.h>
|
||||
#include <backends/imgui_impl_glfw.h>
|
||||
#include <backends/imgui_impl_opengl3.h>
|
||||
|
||||
#include <fmt/core.h>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
|
||||
#include "debug.hpp"
|
||||
#include <fmt/core.h>
|
||||
#include <fmt/ranges.h>
|
||||
|
||||
int run(GLFWwindow *window, ImGuiContext *ctx) {
|
||||
glClearColor(0.1, 0.1, 0.9, 1.0);
|
||||
#include <gl/debug.hpp>
|
||||
#include <gl/buffer.hpp>
|
||||
#include <gl/shader.hpp>
|
||||
#include <gl/vertexarray.hpp>
|
||||
|
||||
#include <tc/groups.hpp>
|
||||
#include <tc/core.hpp>
|
||||
|
||||
#include <geo/mirror.hpp>
|
||||
|
||||
struct State {
|
||||
Eigen::Vector4f bg{0.169f, 0.169f, 0.169f, 1.00f};
|
||||
Eigen::Vector4f fg{0.71f, 0.53f, 0.94f, 1.00f};
|
||||
Eigen::Vector4f wf{0.95f, 0.95f, 0.95f, 1.00f};
|
||||
|
||||
Eigen::Vector4f R{1.00f, 0.00f, 0.00f, 1.00f};
|
||||
Eigen::Vector4f G{0.00f, 1.00f, 0.00f, 1.00f};
|
||||
Eigen::Vector4f B{0.00f, 0.00f, 1.00f, 1.00f};
|
||||
Eigen::Vector4f Y{1.20f, 1.20f, 0.00f, 1.00f};
|
||||
|
||||
Eigen::Matrix4f rot = Eigen::Matrix4f::Identity();
|
||||
|
||||
bool color_axes = false;
|
||||
};
|
||||
|
||||
Eigen::Matrix4f rotor(int u, int v, float rad) {
|
||||
Eigen::Matrix4f res = Eigen::Matrix4f::Identity();
|
||||
res(u, u) = res(v, v) = cosf(rad);
|
||||
res(u, v) = res(v, u) = sinf(rad);
|
||||
res(u, v) *= -1;
|
||||
return res;
|
||||
}
|
||||
|
||||
template<typename T_>
|
||||
T_ mix(const T_ &a, const T_ &b, const typename T_::Scalar &x) {
|
||||
return a * (1 - x) + b * x;
|
||||
}
|
||||
|
||||
void show_overlay(State &state) {
|
||||
static std::string gl_vendor = (const char *) glGetString(GL_VENDOR);
|
||||
static std::string gl_renderer = (const char *) glGetString(GL_RENDERER);
|
||||
static std::string gl_version = (const char *) glGetString(GL_VERSION);
|
||||
static std::string glsl_version = (const char *) glGetString(GL_SHADING_LANGUAGE_VERSION);
|
||||
|
||||
ImGuiWindowFlags window_flags =
|
||||
ImGuiWindowFlags_AlwaysAutoResize |
|
||||
ImGuiWindowFlags_NoSavedSettings |
|
||||
ImGuiWindowFlags_NoFocusOnAppearing |
|
||||
ImGuiWindowFlags_NoNav |
|
||||
ImGuiWindowFlags_NoBringToFrontOnFocus |
|
||||
ImGuiWindowFlags_NoMove;
|
||||
|
||||
ImGuiStyle &style = ImGui::GetStyle();
|
||||
const auto PAD = style.DisplaySafeAreaPadding;
|
||||
auto window_pos = PAD;
|
||||
|
||||
ImGui::SetNextWindowPos(window_pos, ImGuiCond_Always);
|
||||
ImGui::SetNextWindowBgAlpha(0.35f * style.Alpha);
|
||||
ImGui::SetNextWindowCollapsed(true, ImGuiCond_Appearing);
|
||||
ImGui::Begin("Graphics Information", nullptr, window_flags);
|
||||
ImGui::Text("GL Vendor | %s", gl_vendor.c_str());
|
||||
ImGui::Text("GL Renderer | %s", gl_renderer.c_str());
|
||||
ImGui::Text("GL Version | %s", gl_version.c_str());
|
||||
ImGui::Text("GLSL Version | %s", glsl_version.c_str());
|
||||
|
||||
auto v2 = ImGui::GetWindowSize();
|
||||
window_pos.y += v2.y + PAD.y;
|
||||
ImGui::End();
|
||||
|
||||
ImGui::SetNextWindowPos(window_pos, ImGuiCond_Always);
|
||||
ImGui::SetNextWindowBgAlpha(0.35f * style.Alpha);
|
||||
ImGui::Begin("Controls", nullptr, window_flags);
|
||||
|
||||
ImGuiIO &io = ImGui::GetIO();
|
||||
ImGui::Text("FPS | %.2f", io.Framerate);
|
||||
|
||||
ImGui::Separator();
|
||||
|
||||
ImGui::ColorEdit3("Background", state.bg.data(), ImGuiColorEditFlags_Float);
|
||||
ImGui::ColorEdit3("Foreground", state.fg.data(), ImGuiColorEditFlags_Float);
|
||||
ImGui::ColorEdit3("Wireframe", state.wf.data(), ImGuiColorEditFlags_Float);
|
||||
|
||||
ImGui::Checkbox("Show RGBY axis colors", &state.color_axes);
|
||||
|
||||
if (io.MouseDown[0] && !io.WantCaptureMouse) {
|
||||
Eigen::Matrix4f rot = Eigen::Matrix4f::Identity();
|
||||
Eigen::Vector2f del{io.MouseDelta.x, io.MouseDelta.y};
|
||||
del /= 200.0f;
|
||||
|
||||
if (io.KeyShift) {
|
||||
del /= 5.0f;
|
||||
}
|
||||
|
||||
if (io.KeyCtrl) {
|
||||
Eigen::Matrix4f rx = rotor(0, 3, -del.x());
|
||||
Eigen::Matrix4f ry = rotor(1, 3, del.y());
|
||||
rot = rx * ry;
|
||||
} else {
|
||||
Eigen::Matrix4f rx = rotor(0, 2, -del.x());
|
||||
Eigen::Matrix4f ry = rotor(1, 2, del.y());
|
||||
rot = rx * ry;
|
||||
}
|
||||
|
||||
state.rot = rot * state.rot;
|
||||
}
|
||||
|
||||
ImGui::End();
|
||||
}
|
||||
|
||||
void set_style() {
|
||||
ImGui::StyleColorsDark();
|
||||
|
||||
ImGuiStyle &style = ImGui::GetStyle();
|
||||
style.WindowRounding = 4;
|
||||
style.FrameRounding = 2;
|
||||
style.DisplaySafeAreaPadding.x = 10;
|
||||
style.DisplaySafeAreaPadding.y = 10;
|
||||
}
|
||||
|
||||
int run(GLFWwindow *window, ImGuiContext *context) {
|
||||
State state;
|
||||
|
||||
// Buffer<GLuint> ind_buf;
|
||||
Buffer<Eigen::Vector4f> vert_buf;
|
||||
|
||||
VertexArray<Eigen::Vector4f> vao(vert_buf);
|
||||
// glVertexArrayElementBuffer(vao, ind_buf);
|
||||
|
||||
tc::Group group = tc::coxeter("3 4 3");
|
||||
|
||||
auto cosets = solve(group, {}, 1000000);
|
||||
vec4 coords {1, 1, 1, 1};
|
||||
|
||||
auto mirrors = mirror<4>(group);
|
||||
|
||||
auto corners = plane_intersections(mirrors);
|
||||
auto start = barycentric(corners, coords);
|
||||
start.normalize();
|
||||
|
||||
auto points = cosets.path.walk<vec4, vec4>(start, mirrors, reflect<vec4>);
|
||||
|
||||
vert_buf.upload(points);
|
||||
|
||||
VertexShader vs(std::ifstream("res/shaders/main.vert.glsl"));
|
||||
FragmentShader fs(std::ifstream("res/shaders/main.frag.glsl"));
|
||||
|
||||
Program pgm(vs, fs);
|
||||
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glPointSize(2);
|
||||
|
||||
Eigen::Projective3f proj;
|
||||
|
||||
while (!glfwWindowShouldClose(window)) {
|
||||
glfwPollEvents();
|
||||
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
ImGui_ImplOpenGL3_NewFrame();
|
||||
ImGui_ImplGlfw_NewFrame();
|
||||
ImGui::NewFrame();
|
||||
ImGui::Begin("Hello There!", nullptr, ImGuiWindowFlags_None);
|
||||
ImGui::Text("General Kenobi.");
|
||||
ImGui::End();
|
||||
show_overlay(state);
|
||||
ImGui::Render();
|
||||
|
||||
int display_w, display_h;
|
||||
glfwGetFramebufferSize(window, &display_w, &display_h);
|
||||
glViewport(0, 0, display_w, display_h);
|
||||
glClearColor(state.bg[0], state.bg[1], state.bg[2], state.bg[3]);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
auto aspect = (float) display_h / (float) display_w;
|
||||
proj = Eigen::AlignedScaling3f(aspect, 1.0, -0.6);
|
||||
|
||||
glUseProgram(pgm);
|
||||
glBindVertexArray(vao);
|
||||
glUniform4fv(0, 1, state.fg.data());
|
||||
glUniform1f(1, (GLfloat) glfwGetTime());
|
||||
glUniformMatrix4fv(2, 1, false, proj.data());
|
||||
glUniformMatrix4fv(3, 1, false, state.rot.data());
|
||||
glDrawArrays(GL_POINTS, 0, points.size());
|
||||
glBindVertexArray(0);
|
||||
glUseProgram(0);
|
||||
|
||||
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
|
||||
glfwSwapBuffers(window);
|
||||
}
|
||||
@@ -34,21 +199,16 @@ int run(GLFWwindow *window, ImGuiContext *ctx) {
|
||||
|
||||
int main() {
|
||||
if (!glfwInit()) {
|
||||
fmt::print(stderr, "GLFW : Failed Initialization\n");
|
||||
std::cerr << "GLFW:Failed initialization" << std::endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 6);
|
||||
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
|
||||
GLFWwindow *window = glfwCreateWindow(
|
||||
1280, 720,
|
||||
"Cosets Visualization",
|
||||
nullptr, nullptr
|
||||
);
|
||||
|
||||
auto *window = glfwCreateWindow(1280, 720, "Cosets Visualization", nullptr, nullptr);
|
||||
if (!window) {
|
||||
fmt::print("GLFW : Failed to create window.\n");
|
||||
std::cerr << "GLFW:Failed to create window" << std::endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
@@ -67,17 +227,19 @@ int main() {
|
||||
#endif
|
||||
|
||||
IMGUI_CHECKVERSION();
|
||||
ImGuiContext *ctx = ImGui::CreateContext();
|
||||
auto *context = ImGui::CreateContext();
|
||||
ImGui_ImplGlfw_InitForOpenGL(window, true);
|
||||
ImGui_ImplOpenGL3_Init("#version 130");
|
||||
|
||||
int code = EXIT_SUCCESS;
|
||||
set_style();
|
||||
|
||||
int exit_code = EXIT_SUCCESS;
|
||||
|
||||
try {
|
||||
code = run(window, ctx);
|
||||
} catch (const std::exception &ex) {
|
||||
fmt::print(stderr, "{}\n", ex.what());
|
||||
code = EXIT_FAILURE;
|
||||
exit_code = run(window, context);
|
||||
} catch (const std::exception &e) {
|
||||
std::cerr << e.what() << std::endl;
|
||||
exit_code = EXIT_FAILURE;
|
||||
}
|
||||
|
||||
ImGui_ImplOpenGL3_Shutdown();
|
||||
@@ -87,5 +249,5 @@ int main() {
|
||||
glfwDestroyWindow(window);
|
||||
glfwTerminate();
|
||||
|
||||
return code;
|
||||
return exit_code;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user