simplify template

This commit is contained in:
2019-02-07 10:49:31 -05:00
parent e0ec2bf7e1
commit 1bf3c556bd
11 changed files with 52 additions and 438 deletions

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

1
.idea/.name generated
View File

@@ -1 +0,0 @@
hopf

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);
}
}

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

@@ -0,0 +1,18 @@
//
// Created by allem on 2/7/2019.
//
#ifndef HOPF_FIBRATION_UTIL_H
#define HOPF_FIBRATION_UTIL_H
#include <cstdio>
void hello() {
printf("Hello there.\n");
}
void general() {
printf("General Kenobi.\n");
}
#endif //HOPF_FIBRATION_UTIL_H

View File

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

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 +0,0 @@
#version 440
layout(location=0) in float xi;
layout(location=1) in float eta;
out float xi_;
out float eta_;
void main(){
xi_ = xi;
eta_ = eta;
}

View File

@@ -1,254 +1,37 @@
//
// Created by allem on 2/7/2019.
//
#include <glad/glad.h>
#include <GLFW/glfw3.h>
#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
#include <cmath>
#include "glga.hpp"
#define PI 3.14159f
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;
}
}
struct HopfCircle {
float xi; // longitude
float eta; // latitude
HopfCircle(float xi, float eta) : xi(xi), eta(eta) {}
HopfCircle() : HopfCircle(0, 0) {}
};
#include <cstdlib>
#include <string>
struct State {
GLuint vao{};
GLuint vbo{}, ubo{};
GLuint ubo_bp = 1;
void deinit(GLFWwindow *window) {
GLuint prog{};
std::vector<HopfCircle> circles{};
float t = 0;
void regen() {
circles.clear();
const int N = 32;
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;
circles.emplace_back(xi, eta);
}
}
glBindBuffer(GL_ARRAY_BUFFER, vbo);
util::bufferData(GL_ARRAY_BUFFER, circles, GL_STREAM_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
}
explicit State(GLFWwindow *window) {
printf("vendor: %s\nrenderer: %s\n", glGetString(GL_VENDOR), glGetString(GL_RENDERER));
void init(GLFWwindow *window) {
glGenBuffers(1, &vbo);
glGenBuffers(1, &ubo);
glGenVertexArrays(1, &vao);
regen();
glBindBufferBase(GL_UNIFORM_BUFFER, ubo_bp, ubo);
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});
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));
}
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);
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);
}
void render(GLFWwindow *window, float dt, int frame) {
int w, h;
glfwGetFramebufferSize(window, &w, &h);
glViewport(0, 0, w, h);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glUseProgram(prog);
glBindVertexArray(vao);
glEnable(GL_DEPTH_TEST);
glPointSize(5);
glLineWidth(5);
glDrawArrays(GL_POINTS, 0, (unsigned) circles.size());
glBindVertexArray(0);
glUseProgram(0);
glFinish();
glfwSwapBuffers(window);
}
void deinit(GLFWwindow *window) {
void update(GLFWwindow *window, float dt, int frame) {
}
};
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(1280, 720, title.c_str(), nullptr, nullptr);
if (!window) {
glfwTerminate();
exit(EXIT_FAILURE);
@@ -258,7 +41,7 @@ void run() {
gladLoadGLLoader((GLADloadproc) glfwGetProcAddress);
glfwSwapInterval(0);
auto state = State(window);
state->init(window);
double time = glfwGetTime();
int frame = 0;
@@ -266,8 +49,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 +58,7 @@ void run() {
frame += 1;
}
state.deinit(window);
state->deinit(window);
glfwDestroyWindow(window);
}
@@ -285,8 +68,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