diff --git a/framework/include/util.h b/framework/include/gl_util.h similarity index 98% rename from framework/include/util.h rename to framework/include/gl_util.h index 6b3b90d..296dbf0 100644 --- a/framework/include/util.h +++ b/framework/include/gl_util.h @@ -1,7 +1,3 @@ -#include - -#include - #ifndef GL_TEMPLATE_UTIL_H #define GL_TEMPLATE_UTIL_H diff --git a/simplex/include/mesh.h b/simplex/include/mesh.h new file mode 100644 index 0000000..392b416 --- /dev/null +++ b/simplex/include/mesh.h @@ -0,0 +1,152 @@ +#ifndef SIMPLEX_MESH_H +#define SIMPLEX_MESH_H + +#include +#include + +#include +#include + +template +struct Mesh { + std::vector verts; + std::vector inds; + + Mesh(std::vector verts, std::vector inds) + : verts(std::move(verts)), inds(std::move(inds)) {} + + unsigned size() { + return (unsigned) inds.size() / prim; + } +}; + +template +Mesh concat(Mesh m, Mesh n) { + Mesh res({}, {}); + + for (auto v: m.verts) res.verts.push_back(v); + for (auto v: n.verts) res.verts.push_back(v); + + auto off = (unsigned) m.verts.size(); + + for (auto i: m.inds) res.inds.push_back(i); + for (auto i: n.inds) res.inds.push_back(off + i); + + return res; +} + +template +Mesh transform(Mesh m, glm::mat4 mat) { + Mesh res(m.verts, m.inds); + for (auto &vert : res.verts) + vert = mat * vert; + return res; +} + +template +Mesh offset(Mesh m, glm::vec4 off) { + Mesh res(m.verts, m.inds); + for (auto &vert : res.verts) + vert += off; + return res; +} + +template +Mesh scale(Mesh m, glm::vec4 scl) { + Mesh res(m.verts, m.inds); + for (auto &vert : res.verts) + vert *= scl; + return res; +} + +template +Mesh scale(Mesh m, float scl) { + return scale(m, glm::vec4(scl)); +} + +template +Mesh pyramid(Mesh m, glm::vec4 apex) { + Mesh res(m.verts, {}); + res.verts.push_back(apex); + auto apex_ind = (unsigned) res.verts.size() - 1; + + for (int i = 0; i < m.size(); ++i) { + for (int j = 0; j < prim; ++j) { + res.inds.push_back(m.inds[i * prim + j]); + } + res.inds.push_back(apex_ind); + } + + return res; +} + +template +Mesh fill(Mesh m) { + Mesh res(m.verts, {}); + + for (int i = 0; i < m.size(); ++i) { + for (int j = 0; j < prim; ++j) { + res.inds.push_back(m.inds[i * prim + j]); + } + res.inds.push_back(0); + } + + return res; +} + +template +Mesh join(Mesh m, Mesh n) { + Mesh res({}, {}); + + for (auto v : m.verts) res.verts.push_back(v); + for (auto v : n.verts) res.verts.push_back(v); + + auto off = (unsigned) m.verts.size(); + auto size = (int) std::min(m.inds.size(), n.inds.size()); + + for (int i = 0; i < size; i += prim) { + for (int j = 0; j < prim; ++j) { + for (int x = j; x < prim; ++x) + res.inds.push_back(m.inds[i + x]); + for (int x = 0; x <= j; ++x) + res.inds.push_back(off + n.inds[i + x]); + } + } + + return res; +} + +template +Mesh joinCap(Mesh m, Mesh n) { + return concat(join(m, n), concat(fill(m), fill(n))); +} + +Mesh<4> thicken(const Mesh<3> &m, float thickness) { + return joinCap(offset(m, glm::vec4(0, 0, 0, -thickness / 2)), offset(m, glm::vec4(0, 0, 0, thickness / 2))); +} + +template +Mesh operator+(Mesh m, Mesh n) { return concat(m, n); } + +template +Mesh operator+(Mesh m, glm::vec4 off) { return offset(m, off); } + +template +Mesh operator-(Mesh m, glm::vec4 off) { return offset(m, -off); } + +template +Mesh operator*(Mesh m, glm::vec4 scl) { return scale(m, scl); } + +template +Mesh operator/(Mesh m, glm::vec4 scl) { return scale(m, 1.f / scl); } + +template +Mesh operator*(Mesh m, float scl) { return scale(m, scl); } + +template +Mesh operator/(Mesh m, float scl) { return scale(m, 1.f / scl); } + +template +Mesh operator*(glm::mat4 mat, Mesh m) { return transform(m, mat); } + +#endif //SIMPLEX_MESH_H diff --git a/simplex/include/rotor.h b/simplex/include/rotor.h index 979654b..8387281 100644 --- a/simplex/include/rotor.h +++ b/simplex/include/rotor.h @@ -4,6 +4,7 @@ #include #include #include + #include glm::mat4 rotor(glm::vec4 u, glm::vec4 v, float angle) { @@ -12,7 +13,7 @@ glm::mat4 rotor(glm::vec4 u, glm::vec4 v, float angle) { auto eu = *((Vec *) (void *) &u); auto ev = *((Vec *) (void *) &v); - auto biv = (eu ^ ev).unit() * angle; + auto biv = (eu ^ ev).unit() * angle / 2; Vec col[4] = { Vec(1, 0, 0, 0).rotate(biv), @@ -24,4 +25,16 @@ glm::mat4 rotor(glm::vec4 u, glm::vec4 v, float angle) { return glm::make_mat4((float *) col); } +glm::mat4 rot_xy(float angle) { return rotor(glm::vec4(1, 0, 0, 0), glm::vec4(0, 1, 0, 0), angle); } + +glm::mat4 rot_xz(float angle) { return rotor(glm::vec4(1, 0, 0, 0), glm::vec4(0, 0, 1, 0), angle); } + +glm::mat4 rot_xw(float angle) { return rotor(glm::vec4(1, 0, 0, 0), glm::vec4(0, 0, 0, 1), angle); } + +glm::mat4 rot_yz(float angle) { return rotor(glm::vec4(0, 1, 0, 0), glm::vec4(0, 0, 1, 0), angle); } + +glm::mat4 rot_yw(float angle) { return rotor(glm::vec4(0, 1, 0, 0), glm::vec4(0, 0, 0, 1), angle); } + +glm::mat4 rot_zw(float angle) { return rotor(glm::vec4(0, 0, 1, 0), glm::vec4(0, 0, 0, 1), angle); } + #endif //GL_TEMPLATE_ROTOR_H diff --git a/simplex/include/solids.h b/simplex/include/solids.h new file mode 100644 index 0000000..d389298 --- /dev/null +++ b/simplex/include/solids.h @@ -0,0 +1,50 @@ +#ifndef SIMPLEX_SOLIDS_H +#define SIMPLEX_SOLIDS_H + +#include "mesh.h" +#include "rotor.h" + +static auto T = (float) PI / 2; + +Mesh<2> poly(int sides) { + Mesh<2> res({}, {}); + + auto t = (float) (PI * 2 / sides); + float t0 = t / 2; + auto r = 1 / cos(t0); + + for (int i = 0; i < sides; i++) { + glm::vec2 p = r * glm::vec2(cos(t0 + t * i), sin(t0 + t * i)); + res.verts.emplace_back(p, 0, 0); + } + + for (unsigned i = 0; i < sides - 1; i++) { + res.inds.push_back(i); + res.inds.push_back(i + 1); + } + + return res; +} + +Mesh<3> cube() { + glm::vec4 off = glm::vec4(0, 0, 1, 0); + Mesh<3> face = fill(poly(4)); + Mesh<3> pair = (face + off) + (face - off); + + return pair + + rot_xz(T) * pair + + rot_yz(T) * pair; +} + +Mesh<4> tesseract() { + glm::vec4 off = glm::vec4(0, 0, 0, 1); + Mesh<4> cell = fill(cube()); + Mesh<4> pair = (cell + off) + (cell - off); + + return pair + + rot_xw(T) * pair + + rot_yw(T) * pair + + rot_zw(T) * pair; +} + +#endif //SIMPLEX_SOLIDS_H diff --git a/simplex/shaders/sect.geom b/simplex/shaders/sect.geom index ec3814f..7d15d7b 100644 --- a/simplex/shaders/sect.geom +++ b/simplex/shaders/sect.geom @@ -1,7 +1,7 @@ #version 440 core layout(points) in; -layout(triangle_strip, max_vertices=48) out; +layout(triangle_strip, max_vertices=4) out; layout(std430, binding=1) buffer Positions { vec4 verts[]; diff --git a/simplex/shaders/wire.geom b/simplex/shaders/wire.geom index 11f2f84..84d69af 100644 --- a/simplex/shaders/wire.geom +++ b/simplex/shaders/wire.geom @@ -1,7 +1,7 @@ #version 440 core layout(points) in; -layout(line_strip, max_vertices=48) out; +layout(line_strip, max_vertices=20) out; layout(std430, binding=1) buffer Positions { vec4 verts[]; diff --git a/simplex/src/main.cpp b/simplex/src/main.cpp index 520c606..22bdba6 100644 --- a/simplex/src/main.cpp +++ b/simplex/src/main.cpp @@ -1,20 +1,14 @@ +#include +#include + #include -#include +#include +#include #include "glmutil.h" +#include "mesh.h" #include "rotor.h" - -#include -#include -#include -#include - -#include -#include - -#include -#include -#include +#include "solids.h" extern "C" { __attribute__((dllexport)) DWORD NvOptimusEnablement = 0x00000001; @@ -28,64 +22,9 @@ struct Matrices { glm::mat4 proj; }; -void push_tetrahedron(std::vector *inds, const std::vector &tetra) { - for (int i = 0; i < 4; ++i) { - inds->push_back(tetra[i]); - } -} - -void push_cube(std::vector *inds, const std::vector &cube) { - push_tetrahedron(inds, {cube[0], cube[1], cube[2], cube[4]}); - push_tetrahedron(inds, {cube[1], cube[4], cube[5], cube[7]}); - push_tetrahedron(inds, {cube[1], cube[2], cube[3], cube[7]}); - push_tetrahedron(inds, {cube[2], cube[4], cube[6], cube[7]}); - push_tetrahedron(inds, {cube[1], cube[2], cube[4], cube[7]}); -} - -void push_tesseract(std::vector *inds, const std::vector &tess) { - push_cube(inds, {tess[0], tess[1], tess[2], tess[3], tess[4], tess[5], tess[6], tess[7]}); - push_cube(inds, {tess[8], tess[9], tess[10], tess[11], tess[12], tess[13], tess[14], tess[15]}); - push_cube(inds, {tess[0], tess[1], tess[2], tess[3], tess[8], tess[9], tess[10], tess[11]}); - push_cube(inds, {tess[4], tess[5], tess[6], tess[7], tess[12], tess[13], tess[14], tess[15]}); - push_cube(inds, {tess[0], tess[1], tess[4], tess[5], tess[8], tess[9], tess[12], tess[13]}); - push_cube(inds, {tess[2], tess[3], tess[6], tess[7], tess[10], tess[11], tess[14], tess[15]}); - push_cube(inds, {tess[0], tess[2], tess[4], tess[6], tess[8], tess[10], tess[12], tess[14]}); - push_cube(inds, {tess[1], tess[3], tess[5], tess[7], tess[9], tess[11], tess[13], tess[15]}); -} - -void build_tesseract(std::vector *inds, std::vector *verts, const glm::vec4 center, - const glm::vec4 size) { - const glm::vec4 rad = size / 2.f; - - std::vector new_verts = { - {center.x + size.x, center.y + size.y, center.z + size.z, center.w + size.w}, - {center.x + size.x, center.y + size.y, center.z + size.z, center.w - size.w}, - {center.x + size.x, center.y + size.y, center.z - size.z, center.w + size.w}, - {center.x + size.x, center.y + size.y, center.z - size.z, center.w - size.w}, - {center.x + size.x, center.y - size.y, center.z + size.z, center.w + size.w}, - {center.x + size.x, center.y - size.y, center.z + size.z, center.w - size.w}, - {center.x + size.x, center.y - size.y, center.z - size.z, center.w + size.w}, - {center.x + size.x, center.y - size.y, center.z - size.z, center.w - size.w}, - {center.x - size.x, center.y + size.y, center.z + size.z, center.w + size.w}, - {center.x - size.x, center.y + size.y, center.z + size.z, center.w - size.w}, - {center.x - size.x, center.y + size.y, center.z - size.z, center.w + size.w}, - {center.x - size.x, center.y + size.y, center.z - size.z, center.w - size.w}, - {center.x - size.x, center.y - size.y, center.z + size.z, center.w + size.w}, - {center.x - size.x, center.y - size.y, center.z + size.z, center.w - size.w}, - {center.x - size.x, center.y - size.y, center.z - size.z, center.w + size.w}, - {center.x - size.x, center.y - size.y, center.z - size.z, center.w - size.w}, - }; - - std::vector new_inds; - for (int i = 0; i < 16; i++) new_inds.push_back((unsigned) verts->size() + i); - for (auto vert: new_verts) verts->push_back(vert); - - push_tesseract(inds, new_inds); -} - class GLApp : public App { - std::vector cell_verts{}; - std::vector cell_elems{}; + Mesh<4> mesh = Mesh<4>({}, {}); + Matrices matrices{}; GLuint cell_array{}; @@ -100,68 +39,9 @@ class GLApp : public App { bool DRAW_WIRE = true; void init() override { - const bool CUBE = false; - const bool TESS = true; - - //region tesseract frame - if (TESS) { - build_tesseract(&cell_elems, &cell_verts, {-0.875, -0.875, -0.875, +0.00}, {0.125, 0.125, 0.125, 1.000}); - build_tesseract(&cell_elems, &cell_verts, {-0.875, -0.875, +0.875, +0.00}, {0.125, 0.125, 0.125, 1.000}); - build_tesseract(&cell_elems, &cell_verts, {-0.875, +0.875, -0.875, +0.00}, {0.125, 0.125, 0.125, 1.000}); - build_tesseract(&cell_elems, &cell_verts, {-0.875, +0.875, +0.875, +0.00}, {0.125, 0.125, 0.125, 1.000}); - build_tesseract(&cell_elems, &cell_verts, {+0.875, -0.875, -0.875, +0.00}, {0.125, 0.125, 0.125, 1.000}); - build_tesseract(&cell_elems, &cell_verts, {+0.875, -0.875, +0.875, +0.00}, {0.125, 0.125, 0.125, 1.000}); - build_tesseract(&cell_elems, &cell_verts, {+0.875, +0.875, -0.875, +0.00}, {0.125, 0.125, 0.125, 1.000}); - build_tesseract(&cell_elems, &cell_verts, {+0.875, +0.875, +0.875, +0.00}, {0.125, 0.125, 0.125, 1.000}); - - build_tesseract(&cell_elems, &cell_verts, {-0.875, -0.875, +0.00, -0.875}, {0.125, 0.125, 0.750, 0.125}); - build_tesseract(&cell_elems, &cell_verts, {-0.875, -0.875, +0.00, +0.875}, {0.125, 0.125, 0.750, 0.125}); - build_tesseract(&cell_elems, &cell_verts, {-0.875, +0.875, +0.00, -0.875}, {0.125, 0.125, 0.750, 0.125}); - build_tesseract(&cell_elems, &cell_verts, {-0.875, +0.875, +0.00, +0.875}, {0.125, 0.125, 0.750, 0.125}); - build_tesseract(&cell_elems, &cell_verts, {+0.875, -0.875, +0.00, -0.875}, {0.125, 0.125, 0.750, 0.125}); - build_tesseract(&cell_elems, &cell_verts, {+0.875, -0.875, +0.00, +0.875}, {0.125, 0.125, 0.750, 0.125}); - build_tesseract(&cell_elems, &cell_verts, {+0.875, +0.875, +0.00, -0.875}, {0.125, 0.125, 0.750, 0.125}); - build_tesseract(&cell_elems, &cell_verts, {+0.875, +0.875, +0.00, +0.875}, {0.125, 0.125, 0.750, 0.125}); - - build_tesseract(&cell_elems, &cell_verts, {-0.875, +0.00, -0.875, -0.875}, {0.125, 0.750, 0.125, 0.125}); - build_tesseract(&cell_elems, &cell_verts, {-0.875, +0.00, -0.875, +0.875}, {0.125, 0.750, 0.125, 0.125}); - build_tesseract(&cell_elems, &cell_verts, {-0.875, +0.00, +0.875, -0.875}, {0.125, 0.750, 0.125, 0.125}); - build_tesseract(&cell_elems, &cell_verts, {-0.875, +0.00, +0.875, +0.875}, {0.125, 0.750, 0.125, 0.125}); - build_tesseract(&cell_elems, &cell_verts, {+0.875, +0.00, -0.875, -0.875}, {0.125, 0.750, 0.125, 0.125}); - build_tesseract(&cell_elems, &cell_verts, {+0.875, +0.00, -0.875, +0.875}, {0.125, 0.750, 0.125, 0.125}); - build_tesseract(&cell_elems, &cell_verts, {+0.875, +0.00, +0.875, -0.875}, {0.125, 0.750, 0.125, 0.125}); - build_tesseract(&cell_elems, &cell_verts, {+0.875, +0.00, +0.875, +0.875}, {0.125, 0.750, 0.125, 0.125}); - - build_tesseract(&cell_elems, &cell_verts, {+0.00, -0.875, -0.875, -0.875}, {0.750, 0.125, 0.125, 0.125}); - build_tesseract(&cell_elems, &cell_verts, {+0.00, -0.875, -0.875, +0.875}, {0.750, 0.125, 0.125, 0.125}); - build_tesseract(&cell_elems, &cell_verts, {+0.00, -0.875, +0.875, -0.875}, {0.750, 0.125, 0.125, 0.125}); - build_tesseract(&cell_elems, &cell_verts, {+0.00, -0.875, +0.875, +0.875}, {0.750, 0.125, 0.125, 0.125}); - build_tesseract(&cell_elems, &cell_verts, {+0.00, +0.875, -0.875, -0.875}, {0.750, 0.125, 0.125, 0.125}); - build_tesseract(&cell_elems, &cell_verts, {+0.00, +0.875, -0.875, +0.875}, {0.750, 0.125, 0.125, 0.125}); - build_tesseract(&cell_elems, &cell_verts, {+0.00, +0.875, +0.875, -0.875}, {0.750, 0.125, 0.125, 0.125}); - build_tesseract(&cell_elems, &cell_verts, {+0.00, +0.875, +0.875, +0.875}, {0.750, 0.125, 0.125, 0.125}); - } - //endregion - - //region cube frame - if (CUBE) { - build_tesseract(&cell_elems, &cell_verts, {-0.875, -0.875, +0.00, +0.00}, {0.125, 0.125, 1.000, 0.125}); - build_tesseract(&cell_elems, &cell_verts, {-0.875, +0.875, +0.00, +0.00}, {0.125, 0.125, 1.000, 0.125}); - build_tesseract(&cell_elems, &cell_verts, {+0.875, -0.875, +0.00, +0.00}, {0.125, 0.125, 1.000, 0.125}); - build_tesseract(&cell_elems, &cell_verts, {+0.875, +0.875, +0.00, +0.00}, {0.125, 0.125, 1.000, 0.125}); - - build_tesseract(&cell_elems, &cell_verts, {-0.875, +0.00, -0.875, +0.00}, {0.125, 0.750, 0.125, 0.125}); - build_tesseract(&cell_elems, &cell_verts, {-0.875, +0.00, +0.875, +0.00}, {0.125, 0.750, 0.125, 0.125}); - build_tesseract(&cell_elems, &cell_verts, {+0.875, +0.00, -0.875, +0.00}, {0.125, 0.750, 0.125, 0.125}); - build_tesseract(&cell_elems, &cell_verts, {+0.875, +0.00, +0.875, +0.00}, {0.125, 0.750, 0.125, 0.125}); - - build_tesseract(&cell_elems, &cell_verts, {+0.00, -0.875, -0.875, +0.00}, {0.750, 0.125, 0.125, 0.125}); - build_tesseract(&cell_elems, &cell_verts, {+0.00, -0.875, +0.875, +0.00}, {0.750, 0.125, 0.125, 0.125}); - build_tesseract(&cell_elems, &cell_verts, {+0.00, +0.875, -0.875, +0.00}, {0.750, 0.125, 0.125, 0.125}); - build_tesseract(&cell_elems, &cell_verts, {+0.00, +0.875, +0.875, +0.00}, {0.750, 0.125, 0.125, 0.125}); - } - //endregion + mesh = tesseract(); + //region Uniforms matrices = { glm::identity(), glm::vec4(0), @@ -169,6 +49,7 @@ class GLApp : public App { glm::identity(), glm::identity(), }; + //endregion //region Shaders GLuint main_vs = util::buildShader(GL_VERTEX_SHADER, {"shaders/main.vert"}); @@ -191,12 +72,12 @@ class GLApp : public App { glGenBuffers(1, &cell_vert_buf); glBindBufferBase(GL_SHADER_STORAGE_BUFFER, verts_binding_point, cell_vert_buf); glBindBuffer(GL_SHADER_STORAGE_BUFFER, cell_vert_buf); - util::bufferData(GL_SHADER_STORAGE_BUFFER, cell_verts, GL_STATIC_DRAW); + util::bufferData(GL_SHADER_STORAGE_BUFFER, mesh.verts, GL_STATIC_DRAW); glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0); glGenBuffers(1, &cell_elem_arr_buf); glBindBuffer(GL_ARRAY_BUFFER, cell_elem_arr_buf); - util::bufferData(GL_ARRAY_BUFFER, cell_elems, GL_STATIC_DRAW); + util::bufferData(GL_ARRAY_BUFFER, mesh.inds, GL_STATIC_DRAW); glBindBuffer(GL_ARRAY_BUFFER, 0); glGenBuffers(1, &matrix_buffer); @@ -226,16 +107,14 @@ class GLApp : public App { float ratio = (float) width / height; matrices.model = glm::identity() * -// rotor(glm::vec4(1, 0, 0, 0), glm::vec4(0, 1, 0, 0), getTime() / 5) * + rotor(glm::vec4(1, 0, 0, 0), glm::vec4(0, 0, 0, 1), getTime() / 3) * + rotor(glm::vec4(0, 1, 0, 0), glm::vec4(0, 0, 1, 0), getTime() / 3) * -// rotor(glm::vec4(1, 1, 1, 0), glm::vec4(0, 0, 0, 1), 1) * -// rotor(glm::vec4(1, 0, 0, 0), glm::vec4(0, 0, 0, 1), 1) * - - rotor(glm::vec4(1, 1, 1, 0), glm::vec4(0, 0, 0, 1), getTime() / 4) * - rotor(glm::vec4(1, 0, 0, 0), glm::vec4(0, 0, 0, 1), getTime() / 5) * +// rotor(glm::vec4(1, 1, 1, 0), glm::vec4(0, 0, 0, 1), getTime() / 3) * +// rotor(glm::vec4(1, 0, 0, 0), glm::vec4(0, 0, 1, 0), getTime() / 3) * 1.f; -// matrices.offset.w = sin(getTime() / 3) * 1.8f; +// matrices.offset = glm::vec4(0,0,0,sin(getTime() / 2)); matrices.view = glm::lookAt(glm::vec3(0, 0, -4), glm::vec3(0, 0, 0), glm::vec3(0, 1, 0)); matrices.proj = glm::perspective(1.f, ratio, 0.1f, 20.0f); @@ -260,11 +139,12 @@ class GLApp : public App { glBindVertexArray(cell_array); glUseProgram(sect_prog); - glDrawArrays(GL_POINTS, 0, (GLsizei) cell_elems.size() / 4); + glDrawArrays(GL_POINTS, 0, mesh.size()); if (DRAW_WIRE) { + glClear(GL_DEPTH_BUFFER_BIT); glUseProgram(wire_prog); - glDrawArrays(GL_POINTS, 0, (GLsizei) cell_elems.size() / 4); + glDrawArrays(GL_POINTS, 0, mesh.size()); } glBindVertexArray(0);