diff --git a/main/include/glga.hpp b/main/include/glga.hpp index 2aea9be..2944ce0 100644 --- a/main/include/glga.hpp +++ b/main/include/glga.hpp @@ -10,7 +10,6 @@ namespace ga { Vec(float x, float y, float z, float w) : x(x), y(y), z(z), w(w) {} - }; struct Bivec { @@ -29,11 +28,11 @@ namespace ga { namespace unit { Vec x() { return Vec(1, 0, 0, 0); }; - Vec y() { return Vec(1, 0, 0, 0); }; + Vec y() { return Vec(0, 1, 0, 0); }; - Vec z() { return Vec(1, 0, 0, 0); }; + Vec z() { return Vec(0, 0, 1, 0); }; - Vec w() { return Vec(1, 0, 0, 0); }; + Vec w() { return Vec(0, 0, 0, 1); }; Bivec xy() { return Bivec(1, 0, 0, 0, 0, 0); } @@ -46,6 +45,8 @@ namespace ga { Bivec xz() { return Bivec(0, 0, 0, 0, 1, 0); } Bivec yw() { return Bivec(0, 0, 0, 0, 0, 1); } + + Mat identity() { return Mat(x(), y(), z(), w()); } } float length2(Vec v) { @@ -93,6 +94,28 @@ namespace ga { c * v.yw); } + Vec mul(Mat m, Vec v) { + return add(add(mul(v.x, m.x), mul(v.y, m.y)), add(mul(v.z, m.z), mul(v.w, m.w))); + } + + Mat mul(Mat m, Mat n) { + return Mat( + mul(m, n.x), + mul(m, n.y), + mul(m, n.z), + mul(m, n.w) + ); + } + + Mat mul(float c, Mat m) { + return Mat( + mul(c, m.x), + mul(c, m.y), + mul(c, m.z), + mul(c, m.w) + ); + } + Vec normalize(Vec v) { return mul(1 / length(v), v); } @@ -101,21 +124,42 @@ namespace ga { return mul(1 / length(v), v); } + Vec tform(float c, Vec v) { + + } + + Vec tform(Vec u, Vec v) { + + } + + Vec tform(Bivec u, Vec v) { + + } + Mat matrix(float c) { - // c as a transformation - // scale by c - return Mat(Vec(c, 0, 0, 0), Vec(0, c, 0, 0), Vec(0, 0, c, 0), Vec(0, 0, 0, c)); + auto m = unit::identity(); + m.x = tform(c, m.x); + m.y = tform(c, m.y); + m.z = tform(c, m.z); + m.w = tform(c, m.w); + return m; } Mat matrix(Vec v) { - // v as a transformation - // reflect along v - return matrix(1); // todo reflection + auto m = unit::identity(); + m.x = tform(v, m.x); + m.y = tform(v, m.y); + m.z = tform(v, m.z); + m.w = tform(v, m.w); + return m; } - Mat rotor(Bivec v) { - // v as a transformation - // rotate along v - return matrix(1); + Mat matrix(Bivec v) { + auto m = unit::identity(); + m.x = tform(v, m.x); + m.y = tform(v, m.y); + m.z = tform(v, m.z); + m.w = tform(v, m.w); + return m; } } \ No newline at end of file diff --git a/main/shaders/main.frag b/main/shaders/main.frag index d2e268c..395796a 100644 --- a/main/shaders/main.frag +++ b/main/shaders/main.frag @@ -2,6 +2,8 @@ #define PI 3.14159 +uniform float bright; + in vec4 pos; in vec4 pos4; in vec4 pos3; @@ -11,7 +13,8 @@ out vec4 color; void main() { float light = -pos3.y / 10 + .5; - vec3 col = vec3(1); + vec3 col = vec3(bright); - color = vec4(col * light, 1); + //color = vec4(col * light, 1); + color = vec4(col, 1); } \ No newline at end of file diff --git a/main/shaders/main.geom b/main/shaders/main.geom index cede560..81d2b1e 100644 --- a/main/shaders/main.geom +++ b/main/shaders/main.geom @@ -1,6 +1,6 @@ #version 440 -#define CIRCLE_RES 64 +#define CIRCLE_RES 128 #define PI 3.14159 layout(points) in; diff --git a/main/src/main.cpp b/main/src/main.cpp index e735b61..c93f90b 100644 --- a/main/src/main.cpp +++ b/main/src/main.cpp @@ -121,13 +121,17 @@ struct HopfCircle { struct State { GLuint vao{}; GLuint vbo{}, ubo{}; + GLuint unif_bright{}; GLuint ubo_bp = 1; GLuint prog{}; std::vector circles{}; + ga::Mat rot = ga::unit::identity(); + float view = 4.f; float t = 0; + float dt = 0; void regen() { circles.clear(); @@ -136,10 +140,10 @@ struct State { const int M = 4; const float PAD = 0.0125; - for (int k = 0; k <= N; ++k) { - for (int j = 0; j <= M; ++j) { - float xi = 2 * PI * k / N; - float eta = (PI / 2 - 2 * PAD) * j / M + PAD; + for (int x = 0; x <= N; ++x) { + for (int e = 1; e < M; ++e) { + float xi = 2 * PI * x / N; + float eta = (PI / 2 - 2 * PAD) * e / M + PAD; circles.emplace_back(xi, eta); } } @@ -152,6 +156,10 @@ struct State { explicit State(GLFWwindow *window) { printf("vendor: %s\nrenderer: %s\n", glGetString(GL_VENDOR), glGetString(GL_RENDERER)); + float lw[2]; + glGetFloatv(GL_LINE_WIDTH_RANGE, lw); + printf("line width range: %.2f to %.2f\n", lw[0], lw[1]); + glGenBuffers(1, &vbo); glGenBuffers(1, &ubo); glGenVertexArrays(1, &vao); @@ -165,6 +173,8 @@ struct State { GLuint fs = util::buildShader(GL_FRAGMENT_SHADER, "fs", {"shaders/main.frag"}); prog = util::buildProgram(false, "prog", {vs, gs, fs}); + unif_bright = (GLuint) glGetUniformLocation(prog, "bright"); + glBindVertexArray(vao); glBindBuffer(GL_ARRAY_BUFFER, vbo); @@ -204,17 +214,11 @@ struct State { glBindBuffer(GL_UNIFORM_BUFFER, ubo); util::bufferData(GL_UNIFORM_BUFFER, { ga::Mat( - ga::Vec(1.f / 4 / ar, 0, 0, 0), + ga::Vec(1.f / view / ar, 0, 0, 0), ga::Vec(0, 0, 1.f / 10, 0), - ga::Vec(0, 1.f / 4, 0, 0), + ga::Vec(0, 1.f / view, 0, 0), ga::Vec(0, 0, 0, 1.f)), - - ga::Mat( - ga::Vec(c, 0, 0, s), - ga::Vec(0, c_, s_, 0), - ga::Vec(0, -s_, c_, 0), - ga::Vec(-s, 0, 0, c) - ) + rot }, GL_STREAM_DRAW); glBindBuffer(GL_UNIFORM_BUFFER, 0); } @@ -226,12 +230,20 @@ struct State { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glDepthFunc(GL_LEQUAL); + glUseProgram(prog); glBindVertexArray(vao); glEnable(GL_DEPTH_TEST); - glPointSize(5); - glLineWidth(5); + + glLineWidth(10); + glUniform1f(unif_bright, 0); glDrawArrays(GL_POINTS, 0, (unsigned) circles.size()); + + glLineWidth(1); + glUniform1f(unif_bright, 1); + glDrawArrays(GL_POINTS, 0, (unsigned) circles.size()); + glBindVertexArray(0); glUseProgram(0); @@ -239,10 +251,100 @@ struct State { glfwSwapBuffers(window); } + void on_scroll(GLFWwindow *window, double xoffset, double yoffset) { + printf("scroll %.2f %.2f\n", xoffset, yoffset); + + int xw = glfwGetKey(window, GLFW_KEY_Q); + int yw = glfwGetKey(window, GLFW_KEY_W); + int zw = glfwGetKey(window, GLFW_KEY_E); + int xy = glfwGetKey(window, GLFW_KEY_A); + int yz = glfwGetKey(window, GLFW_KEY_S); + int zx = glfwGetKey(window, GLFW_KEY_D); + + int zoom = glfwGetKey(window, GLFW_KEY_LEFT_CONTROL); + + float t = (float) yoffset * PI / 48; + float c = std::cos(t); + float s = std::sin(t); + + if (xw) { + rot = ga::mul(rot, ga::Mat( + ga::Vec(c, 0, 0, s), + ga::Vec(0, 1, 0, 0), + ga::Vec(0, 0, 1, 0), + ga::Vec(-s, 0, 0, c) + )); + } + + if (yw) { + rot = ga::mul(rot, ga::Mat( + ga::Vec(1, 0, 0, 0), + ga::Vec(0, c, 0, s), + ga::Vec(0, 0, 1, 0), + ga::Vec(0, -s, 0, c) + )); + } + + if (zw) { + rot = ga::mul(rot, ga::Mat( + ga::Vec(1, 0, 0, 0), + ga::Vec(0, 1, 0, 0), + ga::Vec(0, 0, c, s), + ga::Vec(0, 0, -s, c) + )); + } + + if (xy) { + rot = ga::mul(rot, ga::Mat( + ga::Vec(c, s, 0, 0), + ga::Vec(-s, c, 0, 0), + ga::Vec(0, 0, 1, 0), + ga::Vec(0, 0, 0, 1) + )); + } + + if (yz) { + rot = ga::mul(rot, ga::Mat( + ga::Vec(1, 0, 0, 0), + ga::Vec(0, c, s, 0), + ga::Vec(0, -s, c, 0), + ga::Vec(0, 0, 0, 1) + )); + } + + if (zx) { + rot = ga::mul(rot, ga::Mat( + ga::Vec(c, 0, -s, 0), + ga::Vec(0, 1, 0, 0), + ga::Vec(s, 0, c, 0), + ga::Vec(0, 0, 0, 1) + )); + } + + if (zoom) { + view *= 1 - t / 5; + } + + std::ofstream matfile; + matfile.open("matrix.txt"); + matfile << "vec((\n"; + matfile << "vec((" << rot.x.x << ", " << rot.x.y << ", " << rot.x.z << ", " << rot.x.w << ")),\n"; + matfile << "vec((" << rot.y.x << ", " << rot.y.y << ", " << rot.y.z << ", " << rot.y.w << ")),\n"; + matfile << "vec((" << rot.z.x << ", " << rot.z.y << ", " << rot.z.z << ", " << rot.z.w << ")),\n"; + matfile << "vec((" << rot.w.x << ", " << rot.w.y << ", " << rot.w.z << ", " << rot.w.w << ")),\n"; + matfile << ")),"; + matfile.close(); + } + void deinit(GLFWwindow *window) { } }; +void scroll_callback(GLFWwindow *window, double xoffset, double yoffset) { + auto *state = (State *) glfwGetWindowUserPointer(window); + state->on_scroll(window, xoffset, yoffset); +} + void run() { glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 4); @@ -259,6 +361,9 @@ void run() { glfwSwapInterval(0); auto state = State(window); + glfwSetWindowUserPointer(window, &state); + + glfwSetScrollCallback(window, scroll_callback); double time = glfwGetTime(); int frame = 0;