mirror of
https://github.com/allemangD/toddcox-visualize.git
synced 2025-11-10 03:52:48 -05:00
Add wireframe hypercube
This commit is contained in:
@@ -13,8 +13,12 @@ namespace ml {
|
||||
using PointsType = Eigen::MatrixXf;
|
||||
using CellsType = Eigen::MatrixXi;
|
||||
|
||||
[[nodiscard]] virtual Eigen::Index dim() const = 0;
|
||||
|
||||
[[nodiscard]] virtual PointsType points() const = 0;
|
||||
|
||||
[[nodiscard]] virtual Eigen::Index rank() const = 0;
|
||||
|
||||
[[nodiscard]] virtual CellsType cells() const = 0;
|
||||
};
|
||||
|
||||
@@ -31,6 +35,10 @@ namespace ml {
|
||||
DynamicMesh(PointsType points, CellsType cells)
|
||||
: _points(std::move(points)), _cells(std::move(cells)) {}
|
||||
|
||||
Eigen::Index dim() const override {
|
||||
return _points.rows();
|
||||
}
|
||||
|
||||
[[nodiscard]] PointsType &points() {
|
||||
return _points;
|
||||
}
|
||||
@@ -39,6 +47,10 @@ namespace ml {
|
||||
return _points;
|
||||
}
|
||||
|
||||
Eigen::Index rank() const override {
|
||||
return _points.rows();
|
||||
}
|
||||
|
||||
[[nodiscard]] CellsType &cells() {
|
||||
return _cells;
|
||||
}
|
||||
@@ -55,6 +67,10 @@ namespace ml {
|
||||
explicit CubeMesh(PointsType::Scalar radius = 0.5)
|
||||
: radius(radius) {}
|
||||
|
||||
Eigen::Index dim() const override {
|
||||
return 3;
|
||||
}
|
||||
|
||||
[[nodiscard]] PointsType points() const override {
|
||||
PointsType out(3, 8);
|
||||
out.transpose() <<
|
||||
@@ -69,6 +85,10 @@ namespace ml {
|
||||
return out;
|
||||
}
|
||||
|
||||
Eigen::Index rank() const override {
|
||||
return 3;
|
||||
}
|
||||
|
||||
CellsType cells() const override {
|
||||
CellsType out(3, 12);
|
||||
out.transpose() <<
|
||||
@@ -83,4 +103,54 @@ namespace ml {
|
||||
return out;
|
||||
}
|
||||
};
|
||||
|
||||
class WireCubeMesh : public MeshBase {
|
||||
PointsType::Scalar radius;
|
||||
long _dim;
|
||||
long _npoints;
|
||||
long _nlines;
|
||||
|
||||
public:
|
||||
explicit WireCubeMesh(long dim = 3, PointsType::Scalar radius = 0.5)
|
||||
: _dim(dim), radius(radius) {
|
||||
_npoints = 1 << _dim;
|
||||
_nlines = _dim * (_npoints >> 1);
|
||||
}
|
||||
|
||||
Eigen::Index dim() const override {
|
||||
return _dim;
|
||||
}
|
||||
|
||||
[[nodiscard]] PointsType points() const override {
|
||||
PointsType out(_dim, _npoints);
|
||||
out.fill(radius);
|
||||
for (int i = 0; i < out.cols(); ++i) {
|
||||
for (int j = 0; j < _dim; ++j) {
|
||||
if ((i >> j) & 1) {
|
||||
out(j, i) *= -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
Eigen::Index rank() const override {
|
||||
return 2;
|
||||
}
|
||||
|
||||
[[nodiscard]] CellsType cells() const override {
|
||||
CellsType out(2, _nlines);
|
||||
int k = 0;
|
||||
for (int i = 0; i < _npoints; ++i) {
|
||||
for (int j = 0; j < _dim; ++j) {
|
||||
if ((i >> j) & 1) {
|
||||
out(0, k) = i;
|
||||
out(1, k) = i ^ (1 << j);
|
||||
k++;
|
||||
}
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
40
res/shaders/4d.vert.glsl
Normal file
40
res/shaders/4d.vert.glsl
Normal file
@@ -0,0 +1,40 @@
|
||||
#version 440
|
||||
|
||||
layout(location=1) uniform float time;
|
||||
layout(location=2) uniform mat4 proj;
|
||||
|
||||
layout(location=0) in vec4 pos;
|
||||
|
||||
void main() {
|
||||
float c2 = cos(time * 0.2);
|
||||
float s2 = sin(time * 0.2);
|
||||
float c3 = cos(time * 0.3);
|
||||
float s3 = sin(time * 0.3);
|
||||
float c4 = cos(time * 0.25);
|
||||
float s4 = sin(time * 0.25);
|
||||
|
||||
mat4 r1 = mat4(
|
||||
c2, -s2, 0.0, 0.0,
|
||||
s2, c2, 0.0, 0.0,
|
||||
0.0, 0.0, 1.0, 0.0,
|
||||
0.0, 0.0, 0.0, 1.0
|
||||
);
|
||||
|
||||
mat4 r2 = mat4(
|
||||
c3, 0.0, -s3, 0.0,
|
||||
0.0, 1.0, 0.0, 0.0,
|
||||
s3, 0.0, c3, 0.0,
|
||||
0.0, 0.0, 0.0, 1.0
|
||||
);
|
||||
|
||||
mat4 r3 = mat4(
|
||||
1.0, 0.0, 0.0, 0.0,
|
||||
0.0, c4, 0.0, -s4,
|
||||
0.0, 0.0, 1.0, 0.0,
|
||||
0.0, s4, 0.0, c4
|
||||
);
|
||||
|
||||
vec4 pos = r2 * r1 * r3 * pos;
|
||||
|
||||
gl_Position = proj * vec4(pos.xyz / (1 - pos.w), 1.0);
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
#version 440
|
||||
|
||||
layout(location=0) uniform vec4 ucol;
|
||||
|
||||
layout(location=0) out vec4 col;
|
||||
|
||||
void main() {
|
||||
|
||||
77
src/main.cpp
77
src/main.cpp
@@ -75,7 +75,7 @@ void set_style() {
|
||||
int run(GLFWwindow *window, ImGuiContext *context) {
|
||||
State state;
|
||||
|
||||
auto mesh = ml::CubeMesh(0.5f);
|
||||
auto mesh = ml::CubeMesh(0.25f);
|
||||
// auto mesh = ml::read("circle.pak");
|
||||
|
||||
auto dynamic = (ml::DynamicMesh) mesh;
|
||||
@@ -113,6 +113,39 @@ int run(GLFWwindow *window, ImGuiContext *context) {
|
||||
);
|
||||
glVertexArrayElementBuffer(vao, ibo);
|
||||
|
||||
auto wire_mesh = ml::WireCubeMesh(4, 0.33f);
|
||||
auto wire_dynamic = (ml::DynamicMesh) wire_mesh;
|
||||
|
||||
GLuint wire_vao;
|
||||
glCreateVertexArrays(1, &wire_vao);
|
||||
|
||||
GLuint wire_vbo;
|
||||
glCreateBuffers(1, &wire_vbo);
|
||||
|
||||
glNamedBufferData(
|
||||
wire_vbo,
|
||||
(GLsizeiptr) (point_scalar_size * wire_dynamic.points().size()),
|
||||
wire_dynamic.points().data(),
|
||||
GL_STATIC_DRAW
|
||||
);
|
||||
glEnableVertexArrayAttrib(wire_vao, 0);
|
||||
glVertexArrayVertexBuffer(wire_vao, 0,
|
||||
wire_vbo, 0,
|
||||
(GLsizeiptr) (point_scalar_size * wire_dynamic.points().rows())
|
||||
);
|
||||
glVertexArrayAttribFormat(wire_vao, 0, 4, GL_FLOAT, GL_FALSE, 0);
|
||||
|
||||
GLuint wire_ibo;
|
||||
glCreateBuffers(1, &wire_ibo);
|
||||
glGetError();
|
||||
glNamedBufferData(
|
||||
wire_ibo,
|
||||
(GLsizeiptr) (cell_scalar_size * wire_dynamic.cells().size()),
|
||||
wire_dynamic.cells().data(),
|
||||
GL_STATIC_DRAW
|
||||
);
|
||||
glVertexArrayElementBuffer(wire_vao, wire_ibo);
|
||||
|
||||
std::ifstream vs_file("res/shaders/main.vert.glsl");
|
||||
std::string vs_src(
|
||||
(std::istreambuf_iterator<char>(vs_file)),
|
||||
@@ -125,6 +158,18 @@ int run(GLFWwindow *window, ImGuiContext *context) {
|
||||
glShaderSource(vs, 1, &vs_str, nullptr);
|
||||
glCompileShader(vs);
|
||||
|
||||
std::ifstream wire_vs_file("res/shaders/4d.vert.glsl");
|
||||
std::string wire_vs_src(
|
||||
(std::istreambuf_iterator<char>(wire_vs_file)),
|
||||
std::istreambuf_iterator<char>()
|
||||
);
|
||||
wire_vs_file.close();
|
||||
const char *wire_vs_str = wire_vs_src.c_str();
|
||||
|
||||
GLuint wire_vs = glCreateShader(GL_VERTEX_SHADER);
|
||||
glShaderSource(wire_vs, 1, &wire_vs_str, nullptr);
|
||||
glCompileShader(wire_vs);
|
||||
|
||||
std::ifstream fs_file("res/shaders/main.frag.glsl");
|
||||
std::string fs_src(
|
||||
(std::istreambuf_iterator<char>(fs_file)),
|
||||
@@ -142,6 +187,11 @@ int run(GLFWwindow *window, ImGuiContext *context) {
|
||||
glAttachShader(pgm, fs);
|
||||
glLinkProgram(pgm);
|
||||
|
||||
GLuint wire_pgm = glCreateProgram();
|
||||
glAttachShader(wire_pgm, wire_vs);
|
||||
glAttachShader(wire_pgm, fs);
|
||||
glLinkProgram(wire_pgm);
|
||||
|
||||
GLint link_status;
|
||||
glGetProgramiv(pgm, GL_LINK_STATUS, &link_status);
|
||||
if (!link_status) {
|
||||
@@ -154,8 +204,16 @@ int run(GLFWwindow *window, ImGuiContext *context) {
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glGetProgramiv(wire_pgm, GL_LINK_STATUS, &link_status);
|
||||
if (!link_status) {
|
||||
std::cerr << "Wire program link failed." << std::endl;
|
||||
GLint vs_comp_status, fs_comp_status;
|
||||
glGetShaderiv(vs, GL_COMPILE_STATUS, &vs_comp_status);
|
||||
glGetShaderiv(fs, GL_COMPILE_STATUS, &fs_comp_status);
|
||||
std::cerr << "vs compiled: " << std::boolalpha << (bool) vs_comp_status << std::endl;
|
||||
std::cerr << "fs compiled: " << std::boolalpha << (bool) fs_comp_status << std::endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
|
||||
@@ -188,6 +246,15 @@ int run(GLFWwindow *window, ImGuiContext *context) {
|
||||
glBindVertexArray(0);
|
||||
glUseProgram(0);
|
||||
|
||||
glUseProgram(wire_pgm);
|
||||
glBindVertexArray(wire_vao);
|
||||
glUniform4fv(0, 1, state.fg);
|
||||
glUniform1f(1, (GLfloat) glfwGetTime());
|
||||
glUniformMatrix4fv(2, 1, false, proj.data());
|
||||
glDrawElements(GL_LINES, (GLsizei) wire_dynamic.cells().size(), GL_UNSIGNED_INT, nullptr);
|
||||
glBindVertexArray(0);
|
||||
glUseProgram(0);
|
||||
|
||||
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
|
||||
glfwSwapBuffers(window);
|
||||
}
|
||||
@@ -196,6 +263,10 @@ int run(GLFWwindow *window, ImGuiContext *context) {
|
||||
glDeleteBuffers(1, &ibo);
|
||||
glDeleteVertexArrays(1, &vao);
|
||||
|
||||
glDeleteBuffers(1, &wire_vbo);
|
||||
glDeleteBuffers(1, &wire_ibo);
|
||||
glDeleteVertexArrays(1, &wire_vao);
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user