Compare commits

9 Commits

Author SHA1 Message Date
2062f19631 final rotation 2019-03-29 14:06:36 -04:00
16a5e403ce matrix rotations by angle 2019-02-08 12:47:06 -05:00
f101bba5aa matrix rotations working 2019-02-07 17:39:10 -05:00
3263c7e45e torus occlusion working 2019-02-07 17:15:17 -05:00
b504bf0222 torus occlusion working 2019-02-07 17:14:23 -05:00
b274251501 add uniforms and projection 2019-02-07 13:42:00 -05:00
421caed141 line fibration working - no projection matrix 2019-02-07 12:34:28 -05:00
1bf3c556bd simplify template 2019-02-07 10:49:31 -05:00
e0ec2bf7e1 add intellij files 2019-01-13 22:36:02 -05:00
16 changed files with 442 additions and 395 deletions

4
.gitignore vendored
View File

@@ -147,6 +147,4 @@ fabric.properties
# Executables
*.exe
*.out
*.app
.idea/
*.app

3
.gitmodules vendored
View File

@@ -5,3 +5,6 @@
path = vendor/glad
url = https://github.com/Dav1dde/glad.git
branch = c
[submodule "vendor/glm"]
path = vendor/glm
url = https://github.com/g-truc/glm.git

4
.idea/encodings.xml generated Normal file
View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Encoding" addBOMForNewFiles="with NO BOM" />
</project>

2
.idea/hopf-fibration.iml generated Normal file
View File

@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="UTF-8"?>
<module classpath="CMake" type="CPP_MODULE" version="4" />

12
.idea/misc.xml generated Normal file
View File

@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CMakeWorkspace" PROJECT_DIR="$PROJECT_DIR$" />
<component name="CidrRootsConfiguration">
<sourceRoots>
<file path="$PROJECT_DIR$/main" />
</sourceRoots>
<libraryRoots>
<file path="$PROJECT_DIR$/vendor" />
</libraryRoots>
</component>
</project>

8
.idea/modules.xml generated Normal file
View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/hopf-fibration.iml" filepath="$PROJECT_DIR$/.idea/hopf-fibration.iml" />
</modules>
</component>
</project>

6
.idea/vcs.xml generated Normal file
View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>

View File

@@ -1,5 +1,5 @@
cmake_minimum_required(VERSION 3.10)
project(hopf)
project(hopf-fibration)
set(CMAKE_CXX_STANDARD 17)
@@ -11,4 +11,7 @@ option(GLFW_BUILD_EXAMPLES OFF)
option(GLFW_BUILD_TESTS OFF)
add_subdirectory(vendor/glfw)
add_subdirectory(main)
option(GLM_TEST_ENABLE OFF)
add_subdirectory(vendor/glm)
add_subdirectory(main)

View File

@@ -1,17 +1,18 @@
project(main)
add_executable(${PROJECT_NAME}
src/main.cpp)
src/main.cpp include/util.h)
target_link_libraries(${PROJECT_NAME}
glad
glm
glfw)
target_include_directories(${PROJECT_NAME}
PRIVATE include)
PRIVATE
include)
set(SHADERS
shaders/main.frag
shaders/main.vert)
add_custom_target(shaders DEPENDS ${SHADERS})

View File

@@ -1,121 +0,0 @@
#include <math.h>
namespace ga {
struct Vec;
struct Bivec;
struct Mat;
struct Vec {
float x, y, z, w;
Vec(float x, float y, float z, float w) :
x(x), y(y), z(z), w(w) {}
};
struct Bivec {
float xy, yz, zw, wx, xz, yw;
Bivec(float xy, float yz, float zw, float wx, float xz, float yw) :
xy(xy), yz(yz), zw(zw), wx(wx), xz(xz), yw(yw) {}
};
struct Mat {
Vec x, y, z, w;
Mat(Vec x, Vec y, Vec z, Vec w) : x(x), y(y), z(z), w(w) {}
};
namespace unit {
Vec x() { return Vec(1, 0, 0, 0); };
Vec y() { return Vec(1, 0, 0, 0); };
Vec z() { return Vec(1, 0, 0, 0); };
Vec w() { return Vec(1, 0, 0, 0); };
Bivec xy() { return Bivec(1, 0, 0, 0, 0, 0); }
Bivec yz() { return Bivec(0, 1, 0, 0, 0, 0); }
Bivec zw() { return Bivec(0, 0, 1, 0, 0, 0); }
Bivec wx() { return Bivec(0, 0, 0, 1, 0, 0); }
Bivec xz() { return Bivec(0, 0, 0, 0, 1, 0); }
Bivec yw() { return Bivec(0, 0, 0, 0, 0, 1); }
}
float length2(Vec v) {
return v.x * v.x + v.y * v.y + v.z * v.z + v.w * v.w;
}
float length2(Bivec v) {
return v.xy * v.xy + v.yz * v.yz + v.zw * v.zw
+ v.wx * v.wx + v.xz * v.xz + v.yw * v.yw;
}
float length(Vec v) { return sqrt(length2(v)); }
float length(Bivec v) { return sqrt(length2(v)); }
Vec add(Vec u, Vec v) {
return Vec(u.x + v.x,
u.y + v.y,
u.z + v.z,
u.w + v.w);
}
Bivec add(Bivec u, Bivec v) {
Bivec(u.xy + v.xy,
u.yz + v.yz,
u.zw + v.zw,
u.wx + v.wx,
u.xz + v.xz,
u.yw + v.yw);
}
Vec mul(float c, Vec v) {
return Vec(c * v.x,
c * v.y,
c * v.z,
c * v.w);
}
Bivec mul(float c, Bivec v) {
Bivec(c * v.xy,
c * v.yz,
c * v.zw,
c * v.wx,
c * v.xz,
c * v.yw);
}
Vec normalize(Vec v) {
return mul(1 / length(v), v);
}
Bivec normalize(Bivec v) {
return mul(1 / length(v), 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));
}
Mat matrix(Vec v) {
// v as a transformation
// reflect along v
return matrix(1); // todo reflection
}
Mat rotor(Bivec v) {
// v as a transformation
// rotate along v
return matrix(1);
}
}

113
main/include/util.h Normal file
View File

@@ -0,0 +1,113 @@
//
// Created by allem on 2/7/2019.
//
#ifndef HOPF_FIBRATION_UTIL_H
#define HOPF_FIBRATION_UTIL_H
#include <glad/glad.h>
#include <fstream>
#include <sstream>
#include <string>
#include <vector>
namespace util {
template<typename T>
void bufferData(GLenum target, std::vector<T> data, GLenum usage) {
glBufferData(target, data.size() * sizeof(T), &data.front(), usage);
}
template<typename T>
void bufferData(GLenum target, T &data, GLenum usage) {
glBufferData(target, sizeof(T), &data, usage);
}
std::string readFile(const std::string &path) {
std::ifstream file(path);
if (!file) return std::string();
file.ignore(std::numeric_limits<std::streamsize>::max());
auto size = file.gcount();
if (size > 0x10000) return std::string();
file.clear();
file.seekg(0, std::ios_base::beg);
std::stringstream sstr;
sstr << file.rdbuf();
file.close();
return sstr.str();
}
void shaderFiles(GLuint shader, std::vector<std::string> &paths) {
std::vector<std::string> strs;
std::vector<const char *> c_strs;
for (const auto &path : paths) strs.push_back(readFile(path));
for (const auto &str:strs) c_strs.push_back(str.c_str());
glShaderSource(shader, (GLsizei) c_strs.size(), &c_strs.front(), nullptr);
}
std::string shaderInfoLog(GLuint shader) {
GLint log_len;
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &log_len);
char log[log_len];
glGetShaderInfoLog(shader, log_len, nullptr, log);
return std::string(log);
}
std::string programInfoLog(GLuint program) {
GLint log_len;
glGetProgramiv(program, GL_INFO_LOG_LENGTH, &log_len);
char log[log_len];
glGetProgramInfoLog(program, log_len, nullptr, log);
return std::string(log);
}
GLuint buildShader(GLenum kind, const std::string &name, std::vector<std::string> paths) {
GLuint shader = glCreateShader(kind);
shaderFiles(shader, paths);
glCompileShader(shader);
GLint comp;
glGetShaderiv(shader, GL_COMPILE_STATUS, &comp);
if (!comp) {
std::string log = shaderInfoLog(shader);
fprintf(stderr, "SHADER ERROR (%s):\n%s", name.c_str(), log.c_str());
glDeleteShader(shader);
return 0;
}
return shader;
}
GLuint buildProgram(bool separable, const std::string &name, std::vector<GLuint> shaders) {
GLuint program = glCreateProgram();
if (separable)
glProgramParameteri(program, GL_PROGRAM_SEPARABLE, GL_TRUE);
for (GLuint shader : shaders)
glAttachShader(program, shader);
glLinkProgram(program);
GLint link;
glGetProgramiv(program, GL_LINK_STATUS, &link);
if (!link) {
std::string log = programInfoLog(program);
fprintf(stderr, "PROGRAM ERROR (%s):\n%s", name.c_str(), log.c_str());
glDeleteProgram(program);
return 0;
}
return program;
}
}
#endif //HOPF_FIBRATION_UTIL_H

View File

@@ -1,17 +1,12 @@
#version 440
#define PI 3.14159
in vec4 pos;
in vec4 pos4;
in vec4 pos3;
layout(binding=1) uniform Unifs {
mat4 uProj;
vec4 uColor;
};
out vec4 color;
void main() {
float light = -pos3.y / 10 + .5;
vec3 col = vec3(1);
color = vec4(col * light, 1);
color = uColor;
}

View File

@@ -1,47 +0,0 @@
#version 440
#define CIRCLE_RES 64
#define PI 3.14159
layout(points) in;
layout(line_strip, max_vertices=CIRCLE_RES) out;
layout(binding=1) uniform Matrices {
mat4 proj;
mat4 model;
};
in float xi_[];
in float eta_[];
out vec4 pos;
out vec4 pos4;
out vec4 pos3;
void main(){
for(int k = 0; k <= CIRCLE_RES; k++) {
vec2 xi = vec2(xi_[0], 4 * PI * k / (CIRCLE_RES - 1));
float eta = eta_[0];
// todo parameterize the projected circle so there aren't jagged edges.
// should be smooth at <=32 segments, not just 128+
float x = cos((xi.y + xi.x) / 2) * sin(eta);
float y = sin((xi.y + xi.x) / 2) * sin(eta);
float z = cos((xi.y - xi.x) / 2) * cos(eta);
float w = sin((xi.y - xi.x) / 2) * cos(eta);
pos = vec4(x, y, z, w);
pos4 = model * pos;
pos3 = vec4(pos4.xyz / (1 - pos4.w), 1);
gl_Position = proj * pos3;
if (length(gl_Position) > 4) {
EndPrimitive();
continue;
}
EmitVertex();
}
EndPrimitive();
}

View File

@@ -1,12 +1,12 @@
#version 440
layout(location=0) in float xi;
layout(location=1) in float eta;
layout(binding=1) uniform Unifs {
mat4 uProj;
vec4 uColor;
};
out float xi_;
out float eta_;
in vec4 iPos;
void main(){
xi_ = xi;
eta_ = eta;
gl_Position = uProj * vec4(iPos.xyz, 1);
}

View File

@@ -1,254 +1,319 @@
//
// Created by allem on 2/7/2019.
//
#include <glad/glad.h>
#include <GLFW/glfw3.h>
#include <iostream>
#include <fstream>
#include <sstream>
#define GLM_FORCE_SWIZZLE
#define GLM_ENABLE_EXPERIMENTAL
#include <glm/glm.hpp>
#include <glm/gtx/string_cast.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <cstdlib>
#include <math.h>
#include <string>
#include <vector>
#include <cmath>
#include "glga.hpp"
#include "util.h"
#define PI 3.14159f
#define RES_MAJOR 512
#define RES_MINOR 8
namespace util {
template<typename T>
void bufferData(GLenum target, std::vector<T> data, GLenum usage) {
glBufferData(target, data.size() * sizeof(T), &data.front(), usage);
}
template<typename T>
void bufferData(GLenum target, T &data, GLenum usage) {
glBufferData(target, sizeof(T), &data, usage);
}
#define Z_RADIUS 10.f
std::string readFile(const std::string &path) {
std::ifstream file(path);
if (!file) return std::string();
#define PI (float) (M_PI)
file.ignore(std::numeric_limits<std::streamsize>::max());
auto size = file.gcount();
if (size > 0x10000) return std::string();
file.clear();
file.seekg(0, std::ios_base::beg);
std::stringstream sstr;
sstr << file.rdbuf();
file.close();
return sstr.str();
}
void shaderFiles(GLuint shader, std::vector<std::string> &paths) {
std::vector<std::string> strs;
std::vector<const char *> c_strs;
for (const auto &path : paths) strs.push_back(readFile(path));
for (const auto &str:strs) c_strs.push_back(str.c_str());
glShaderSource(shader, (GLsizei) c_strs.size(), &c_strs.front(), nullptr);
}
std::string shaderInfoLog(GLuint shader) {
GLint log_len;
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &log_len);
char log[log_len];
glGetShaderInfoLog(shader, log_len, nullptr, log);
return std::string(log);
}
std::string programInfoLog(GLuint program) {
GLint log_len;
glGetProgramiv(program, GL_INFO_LOG_LENGTH, &log_len);
char log[log_len];
glGetProgramInfoLog(program, log_len, nullptr, log);
return std::string(log);
}
GLuint buildShader(GLenum kind, const std::string &name, std::vector<std::string> paths) {
GLuint shader = glCreateShader(kind);
shaderFiles(shader, paths);
glCompileShader(shader);
GLint comp;
glGetShaderiv(shader, GL_COMPILE_STATUS, &comp);
if (!comp) {
std::string log = shaderInfoLog(shader);
fprintf(stderr, "SHADER ERROR (%s):\n%s", name.c_str(), log.c_str());
glDeleteShader(shader);
return 0;
}
return shader;
}
GLuint buildProgram(bool separable, const std::string &name, std::vector<GLuint> shaders) {
GLuint program = glCreateProgram();
if (separable)
glProgramParameteri(program, GL_PROGRAM_SEPARABLE, GL_TRUE);
for (GLuint shader : shaders)
glAttachShader(program, shader);
glLinkProgram(program);
GLint link;
glGetProgramiv(program, GL_LINK_STATUS, &link);
if (!link) {
std::string log = programInfoLog(program);
fprintf(stderr, "PROGRAM ERROR (%s):\n%s", name.c_str(), log.c_str());
glDeleteProgram(program);
return 0;
}
return program;
}
}
struct HopfCircle {
float xi; // longitude
float eta; // latitude
HopfCircle(float xi, float eta) : xi(xi), eta(eta) {}
HopfCircle() : HopfCircle(0, 0) {}
struct Unifs {
glm::mat4 proj = glm::identity<glm::mat4>();
glm::vec4 color = glm::vec4(1);
};
struct State {
GLuint vao{};
GLuint vbo{}, ubo{};
GLuint ubo_bp = 1;
GLuint vao_wide{};
GLuint vbo_wide{};
GLuint ibo_wide{};
GLuint vao_thin{};
GLuint vbo_thin{};
GLuint ibo_thin{};
GLuint ubo{};
GLuint prog{};
const GLuint UNIF_BINDING_POINT = 1;
std::vector<HopfCircle> circles{};
std::vector<glm::vec4> verts_wide{};
std::vector<unsigned> inds_wide{};
float t = 0;
std::vector<glm::vec4> verts_thin{};
std::vector<unsigned> inds_thin{};
void regen() {
circles.clear();
Unifs unifs;
const int N = 32;
const int M = 4;
const float PAD = 0.0125;
glm::vec4 hopf(float xi, float nu, float eta) {
return glm::vec4( // todo find parameterization given quaternion
cos((nu + xi) / 2) * sin(eta),
sin((nu + xi) / 2) * sin(eta),
cos((nu - xi) / 2) * cos(eta),
sin((nu - xi) / 2) * cos(eta)
);
}
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;
circles.emplace_back(xi, eta);
glm::vec3 stereo(float xi, float nu, float eta) {
auto h = hopf(xi, nu, eta);
float xw = 0.8;
float yw = -0.1;
float zw = 2.5;
float xy = 0.0;
float yz = 0.5;
float zx = 0.0;
auto r = glm::mat4(
glm::vec4(cos(xw), 0, 0, sin(xw)),
glm::vec4(0, 1, 0, 0),
glm::vec4(0, 0, 1, 0),
glm::vec4(-sin(xw), 0, 0, cos(xw))
) * glm::mat4(
glm::vec4(1, 0, 0, 0),
glm::vec4(0, cos(yw), 0, sin(yw)),
glm::vec4(0, 0, 1, 0),
glm::vec4(0, -sin(yw), 0, cos(yw))
) * glm::mat4(
glm::vec4(1, 0, 0, 0),
glm::vec4(0, 1, 0, 0),
glm::vec4(0, 0, cos(zw), sin(zw)),
glm::vec4(0, 0, -sin(zw), cos(zw))
) * glm::mat4(
glm::vec4(cos(xy), sin(xy), 0, 0),
glm::vec4(-sin(xy), cos(xy), 0, 0),
glm::vec4(0, 0, 1, 0),
glm::vec4(0, 0, 0, 1)
) * glm::mat4(
glm::vec4(1, 0, 0, 0),
glm::vec4(0, cos(yz), sin(yz), 0),
glm::vec4(0, -sin(yz), cos(yz), 0),
glm::vec4(0, 0, 0, 1)
) * glm::mat4(
glm::vec4(cos(zx), 0, -sin(zx), 0),
glm::vec4(0, 1, 0, 0),
glm::vec4(sin(zx), 0, cos(zx), 0),
glm::vec4(0, 0, 0, 1)
);
auto rot = r;
h = rot * h;
auto s = h.xyz() / (1 - h.w);
s /= 2;
return s;
}
void
add_ring(std::vector<glm::vec4> &dest_verts, std::vector<unsigned> &dest_inds, float xi, float eta, float rad) {
std::vector<glm::vec3> circle;
std::vector<glm::vec3> torus;
std::vector<unsigned> ind;
for (unsigned i = 0; i < RES_MAJOR; ++i) {
auto nu = 4 * PI * i / RES_MAJOR;
auto v = stereo(xi, nu, eta);
circle.push_back(v);
}
auto center = glm::vec3(0);
for (auto v : circle) center += v;
center /= (float) RES_MAJOR;
auto A = stereo(xi, 0 * PI, eta);
auto B = stereo(xi, 1 * PI, eta);
auto normal = glm::normalize(cross(A - center, B - center));
for (unsigned i = 0; i < circle.size(); ++i) {
auto v = circle[i];
auto b1 = normal;
auto b2 = glm::normalize(v - center);
for (int j = 0; j < RES_MINOR; ++j) {
auto theta = 2 * PI * j / RES_MINOR;
auto p = v + (cos(theta) * b1 + sin(theta) * b2) * rad;
ind.push_back(i * RES_MINOR + j);
ind.push_back((i + 1) * RES_MINOR + j);
ind.push_back(i * RES_MINOR + (j + 1) % RES_MINOR);
ind.push_back((i + 1) * RES_MINOR + j);
ind.push_back((i + 1) * RES_MINOR + (j + 1) % RES_MINOR);
ind.push_back(i * RES_MINOR + (j + 1) % RES_MINOR);
torus.push_back(p);
}
}
glBindBuffer(GL_ARRAY_BUFFER, vbo);
util::bufferData(GL_ARRAY_BUFFER, circles, GL_STREAM_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
auto offset = (unsigned) dest_verts.size();
for (auto v : torus)
dest_verts.emplace_back(v, 1);
for (auto i : ind)
dest_inds.push_back(offset + i % (RES_MAJOR * RES_MINOR));
}
explicit State(GLFWwindow *window) {
printf("vendor: %s\nrenderer: %s\n", glGetString(GL_VENDOR), glGetString(GL_RENDERER));
void updateUnifs() {
glBindBuffer(GL_UNIFORM_BUFFER, ubo);
util::bufferData(GL_UNIFORM_BUFFER, unifs, GL_STREAM_DRAW);
glBindBuffer(GL_UNIFORM_BUFFER, 0);
}
glGenBuffers(1, &vbo);
glGenBuffers(1, &ubo);
glGenVertexArrays(1, &vao);
void regen() {
printf("generating\n");
verts_wide.clear();
verts_thin.clear();
inds_wide.clear();
inds_thin.clear();
const float XI_R = 28;
const float ETA_R = 5;
const float ETA_BUF = 0;
for (int i = 0; i < XI_R; ++i) {
float xi = 2 * PI * i / XI_R;
for (int j = 1; j <= ETA_R - 1; ++j) {
float eta = ETA_BUF + (PI / 2 - 2 * ETA_BUF) * j / ETA_R;
add_ring(verts_wide, inds_wide, xi, eta, .015);
add_ring(verts_thin, inds_thin, xi, eta, .004);
}
}
add_ring(verts_wide, inds_wide, .001f, .0f, .015);
add_ring(verts_thin, inds_thin, .001f, .0f, .008);
add_ring(verts_wide, inds_wide, .001f, PI / 2 - .0f, .015);
add_ring(verts_thin, inds_thin, .001f, PI / 2 - .0f, .008);
glBindBuffer(GL_ARRAY_BUFFER, vbo_thin);
util::bufferData(GL_ARRAY_BUFFER, verts_thin, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo_thin);
util::bufferData(GL_ELEMENT_ARRAY_BUFFER, inds_thin, GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glBindBuffer(GL_ARRAY_BUFFER, vbo_wide);
util::bufferData(GL_ARRAY_BUFFER, verts_wide, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo_wide);
util::bufferData(GL_ELEMENT_ARRAY_BUFFER, inds_wide, GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
}
void init(GLFWwindow *window) {
GLuint vs = util::buildShader(GL_VERTEX_SHADER, "vs", {"shaders/main.vert"});
GLuint fs = util::buildShader(GL_FRAGMENT_SHADER, "fs", {"shaders/main.frag"});
prog = util::buildProgram(false, "prog", {vs, fs});
glGenBuffers(1, &vbo_wide);
glGenBuffers(1, &ibo_wide);
glGenBuffers(1, &vbo_thin);
glGenBuffers(1, &ibo_thin);
regen();
glBindBufferBase(GL_UNIFORM_BUFFER, ubo_bp, ubo);
GLint pos = glGetAttribLocation(prog, "iPos");
GLuint vs = util::buildShader(GL_VERTEX_SHADER, "vs", {"shaders/main.vert"});
GLuint gs = util::buildShader(GL_GEOMETRY_SHADER, "gs", {"shaders/main.geom"});
GLuint fs = util::buildShader(GL_FRAGMENT_SHADER, "fs", {"shaders/main.frag"});
prog = util::buildProgram(false, "prog", {vs, gs, fs});
glGenBuffers(1, &ubo);
glBindBufferBase(GL_UNIFORM_BUFFER, UNIF_BINDING_POINT, ubo);
updateUnifs();
glBindVertexArray(vao);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
auto xi = glGetAttribLocation(prog, "xi");
if (xi >= 0) {
glEnableVertexAttribArray((unsigned) xi);
glVertexAttribPointer((unsigned) xi, 1, GL_FLOAT, GL_FALSE,
sizeof(HopfCircle),
(void *) offsetof(HopfCircle, xi));
glGenVertexArrays(1, &vao_wide);
glBindVertexArray(vao_wide);
if (pos >= 0) {
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, vbo_wide);
glVertexAttribPointer((GLuint) pos, 4, GL_FLOAT, GL_FALSE, sizeof(glm::vec4), nullptr);
glBindBuffer(GL_ARRAY_BUFFER, 0);
}
auto eta = glGetAttribLocation(prog, "eta");
if (eta >= 0) {
glEnableVertexAttribArray((unsigned) eta);
glVertexAttribPointer((unsigned) eta, 1, GL_FLOAT, GL_FALSE,
sizeof(HopfCircle),
(void *) offsetof(HopfCircle, eta));
}
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo_wide);
glBindVertexArray(0);
}
void update(GLFWwindow *window, float dt, int frame) {
int w, h;
glfwGetFramebufferSize(window, &w, &h);
auto ar = (float) w / h;
t += dt;
float c = std::cos(t / 8);
float s = std::sin(t / 8);
float c_ = std::cos(3.f / 8);
float s_ = std::sin(3.f / 8);
glBindBuffer(GL_UNIFORM_BUFFER, ubo);
util::bufferData<ga::Mat>(GL_UNIFORM_BUFFER, {
ga::Mat(
ga::Vec(1.f / 4 / ar, 0, 0, 0),
ga::Vec(0, 0, 1.f / 10, 0),
ga::Vec(0, 1.f / 4, 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)
)
}, GL_STREAM_DRAW);
glBindBuffer(GL_UNIFORM_BUFFER, 0);
glGenVertexArrays(1, &vao_thin);
glBindVertexArray(vao_thin);
if (pos >= 0) {
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, vbo_thin);
glVertexAttribPointer((GLuint) pos, 4, GL_FLOAT, GL_FALSE, sizeof(glm::vec4), nullptr);
glBindBuffer(GL_ARRAY_BUFFER, 0);
}
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo_thin);
glBindVertexArray(0);
}
void render(GLFWwindow *window, float dt, int frame) {
int w, h;
glfwGetFramebufferSize(window, &w, &h);
glViewport(0, 0, w, h);
glClearColor(1, 1, 1, 1);
unifs.color = glm::vec4(0, 0, 0, 1);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glClear(GL_DEPTH_BUFFER_BIT);
glUseProgram(prog);
glBindVertexArray(vao);
glBindVertexArray(vao_wide);
glEnable(GL_DEPTH_TEST);
glPointSize(5);
glLineWidth(5);
glDrawArrays(GL_POINTS, 0, (unsigned) circles.size());
glBindVertexArray(0);
glUseProgram(0);
glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);
updateUnifs();
glUseProgram(prog);
glDrawElements(GL_TRIANGLES, (GLsizei) inds_wide.size(), GL_UNSIGNED_INT, 0);
glClear(GL_COLOR_BUFFER_BIT);
glBindVertexArray(vao_thin);
glEnable(GL_DEPTH_TEST);
glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);
updateUnifs();
glUseProgram(prog);
glDrawElements(GL_TRIANGLES, (GLsizei) inds_thin.size(), GL_UNSIGNED_INT, 0);
glFinish();
glfwSwapBuffers(window);
}
void deinit(GLFWwindow *window) {
void update(GLFWwindow *window, float dt, int frame) {
int w, h;
glfwGetFramebufferSize(window, &w, &h);
float ar = (float) w / (float) h;
unifs.proj = glm::ortho(-ar, ar, -1.f, 1.f, -Z_RADIUS, Z_RADIUS);
}
void deinit(GLFWwindow *window) {
}
};
void run() {
void run(State *state, const std::string &title) {
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 4);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
auto window = glfwCreateWindow(1280, 720, "Hopf Fibration", nullptr, nullptr);
auto window = glfwCreateWindow(3840, 1249, title.c_str(), nullptr, nullptr);
if (!window) {
glfwTerminate();
exit(EXIT_FAILURE);
@@ -258,7 +323,8 @@ void run() {
gladLoadGLLoader((GLADloadproc) glfwGetProcAddress);
glfwSwapInterval(0);
auto state = State(window);
glfwSetWindowUserPointer(window, state);
state->init(window);
double time = glfwGetTime();
int frame = 0;
@@ -266,8 +332,8 @@ void run() {
double time_ = glfwGetTime();
auto dt = (float) (time_ - time);
state.update(window, dt, frame);
state.render(window, dt, frame);
state->update(window, dt, frame);
state->render(window, dt, frame);
glfwPollEvents();
@@ -275,7 +341,7 @@ void run() {
frame += 1;
}
state.deinit(window);
state->deinit(window);
glfwDestroyWindow(window);
}
@@ -285,8 +351,11 @@ int main() {
return EXIT_FAILURE;
}
run();
auto *state = new State();
run(state, "Hopf Fibration");
delete state;
glfwTerminate();
return EXIT_SUCCESS;
}
}

1
vendor/glm vendored Submodule

Submodule vendor/glm added at 7590260cf8