@@ -8,3 +8,10 @@ target_link_libraries(${PROJECT_NAME}
|
||||
|
||||
target_include_directories(${PROJECT_NAME}
|
||||
PRIVATE include)
|
||||
|
||||
add_custom_command(
|
||||
TARGET cosets POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_directory
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/shaders
|
||||
${CMAKE_CURRENT_BINARY_DIR}/shaders
|
||||
)
|
||||
|
||||
@@ -1,9 +1,5 @@
|
||||
#include <glad/glad.h>
|
||||
#include <GLFW/glfw3.h>
|
||||
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#include <cstdio>
|
||||
#include "util/window.hpp"
|
||||
#include "util/shader.hpp"
|
||||
|
||||
#include <glm/mat4x4.hpp>
|
||||
#include <glm/gtc/type_ptr.hpp>
|
||||
@@ -12,105 +8,6 @@
|
||||
|
||||
using namespace std;
|
||||
|
||||
GLint build_shader(GLenum type, const string &name, const string &src) {
|
||||
const char *c_str = src.c_str();
|
||||
|
||||
auto s = glCreateShader(type);
|
||||
glShaderSource(s, 1, &c_str, nullptr);
|
||||
glCompileShader(s);
|
||||
|
||||
GLint stat;
|
||||
glGetShaderiv(s, GL_COMPILE_STATUS, &stat);
|
||||
if (!stat) {
|
||||
GLint log_len;
|
||||
glGetShaderiv(s, GL_INFO_LOG_LENGTH, &log_len);
|
||||
char log[log_len];
|
||||
glGetShaderInfoLog(s, log_len, nullptr, log);
|
||||
fprintf(stderr, "SHADER LOG (%s):\n%s", name.c_str(), log);
|
||||
|
||||
glDeleteShader(s);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
GLint build_program(const string &name, GLint vs, GLint fs) {
|
||||
GLint p = glCreateProgram();
|
||||
glAttachShader(p, vs);
|
||||
glAttachShader(p, fs);
|
||||
glLinkProgram(p);
|
||||
|
||||
GLint stat;
|
||||
glGetProgramiv(p, GL_LINK_STATUS, &stat);
|
||||
if (!stat) {
|
||||
GLint log_len;
|
||||
glGetShaderiv(p, GL_INFO_LOG_LENGTH, &log_len);
|
||||
char log[log_len];
|
||||
glGetProgramInfoLog(p, log_len, nullptr, log);
|
||||
fprintf(stderr, "SHADER LOG (%s):\n%s", name.c_str(), log);
|
||||
|
||||
glDeleteProgram(p);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
class Window {
|
||||
protected:
|
||||
GLFWwindow *_window = nullptr;
|
||||
|
||||
public:
|
||||
virtual void init() {}
|
||||
|
||||
virtual void update() {}
|
||||
|
||||
virtual void render() {}
|
||||
|
||||
virtual void deinit() {}
|
||||
|
||||
void getBounds(int &width, int &height) {
|
||||
glfwGetFramebufferSize(_window, &width, &height);
|
||||
}
|
||||
|
||||
void swapbuffers() {
|
||||
glfwSwapBuffers(_window);
|
||||
}
|
||||
|
||||
void run() {
|
||||
int _gl_major = 4, _gl_minor = 0;
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, _gl_major);
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, _gl_minor);
|
||||
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
|
||||
|
||||
|
||||
_window = glfwCreateWindow(640, 480, "GLFW App", nullptr, nullptr);
|
||||
if (!_window) {
|
||||
fprintf(stderr, "Failed to create window;");
|
||||
glfwTerminate();
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
glfwMakeContextCurrent(_window);
|
||||
gladLoadGLLoader((GLADloadproc) glfwGetProcAddress);
|
||||
glfwSwapInterval(0);
|
||||
|
||||
init();
|
||||
|
||||
while (!glfwWindowShouldClose(_window)) {
|
||||
update();
|
||||
render();
|
||||
|
||||
glfwPollEvents();
|
||||
}
|
||||
|
||||
deinit();
|
||||
|
||||
glfwDestroyWindow(_window);
|
||||
}
|
||||
};
|
||||
|
||||
class CosetsWindow : public Window {
|
||||
GLint program;
|
||||
GLuint tri;
|
||||
@@ -120,38 +17,15 @@ class CosetsWindow : public Window {
|
||||
|
||||
public:
|
||||
void init() override {
|
||||
auto vs = build_shader(GL_VERTEX_SHADER, "vertex",
|
||||
"#version 400\n"
|
||||
""
|
||||
"uniform mat4 proj;"
|
||||
""
|
||||
"in vec4 pos;"
|
||||
"out vec4 v;"
|
||||
""
|
||||
"void main(){"
|
||||
" v = pos;"
|
||||
""
|
||||
" /* stereographic projection */"
|
||||
" vec4 vert = vec4(pos.xyz / (1 - pos.w), 1);"
|
||||
" gl_Position = proj * vert;"
|
||||
"}");
|
||||
auto vs = build_shader_file(
|
||||
GL_VERTEX_SHADER,
|
||||
"vertex",
|
||||
"shaders/main.vs.glsl");
|
||||
|
||||
auto fs = build_shader(GL_FRAGMENT_SHADER, "fragment",
|
||||
"#version 400\n"
|
||||
""
|
||||
"in vec4 v;"
|
||||
""
|
||||
"vec3 hsv2rgb(vec3 c)\n"
|
||||
"{\n"
|
||||
" vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);\n"
|
||||
" vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);\n"
|
||||
" return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);\n"
|
||||
"}"
|
||||
""
|
||||
"void main(){"
|
||||
" gl_FragColor = vec4(hsv2rgb(vec3(v.w, 1, 1)), 0);"
|
||||
"}"
|
||||
);
|
||||
auto fs = build_shader_file(
|
||||
GL_FRAGMENT_SHADER,
|
||||
"fragment",
|
||||
"shaders/main.fs.glsl");
|
||||
|
||||
program = build_program("main", vs, fs);
|
||||
|
||||
@@ -226,4 +100,4 @@ int main(int argc, char *argv[]) {
|
||||
|
||||
glfwTerminate();
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
13
cosets/src/shaders/main.fs.glsl
Normal file
13
cosets/src/shaders/main.fs.glsl
Normal file
@@ -0,0 +1,13 @@
|
||||
#version 400
|
||||
|
||||
in vec4 v;
|
||||
|
||||
vec3 hsv2rgb(vec3 c) {
|
||||
vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
|
||||
vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);
|
||||
return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);
|
||||
}
|
||||
|
||||
void main(){
|
||||
gl_FragColor = vec4(hsv2rgb(vec3(v.w, 1, 1)), 0);
|
||||
}
|
||||
14
cosets/src/shaders/main.vs.glsl
Normal file
14
cosets/src/shaders/main.vs.glsl
Normal file
@@ -0,0 +1,14 @@
|
||||
#version 400
|
||||
|
||||
uniform mat4 proj;
|
||||
|
||||
in vec4 pos;
|
||||
out vec4 v;
|
||||
|
||||
void main(){
|
||||
v = pos;
|
||||
|
||||
/* stereographic projection */
|
||||
vec4 vert = vec4(pos.xyz / (1 - pos.w), 1);
|
||||
gl_Position = proj * vert;
|
||||
}
|
||||
19
cosets/src/util/files.hpp
Normal file
19
cosets/src/util/files.hpp
Normal file
@@ -0,0 +1,19 @@
|
||||
#pragma once
|
||||
|
||||
#include <fstream>
|
||||
#include <string>
|
||||
#include <streambuf>
|
||||
|
||||
std::string read_all_text(const std::string &file) {
|
||||
std::ifstream f(file);
|
||||
std::string text;
|
||||
|
||||
f.seekg(0, std::ios::end);
|
||||
text.reserve(f.tellg());
|
||||
f.seekg(0, std::ios::beg);
|
||||
|
||||
text.assign((std::istreambuf_iterator<char>(f)),
|
||||
std::istreambuf_iterator<char>());
|
||||
|
||||
return text;
|
||||
}
|
||||
58
cosets/src/util/shader.hpp
Normal file
58
cosets/src/util/shader.hpp
Normal file
@@ -0,0 +1,58 @@
|
||||
#pragma once
|
||||
|
||||
#include <glad/glad.h>
|
||||
#include <string>
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
|
||||
#include "files.hpp"
|
||||
|
||||
GLint build_shader(GLenum type, const std::string &name, const std::string &src) {
|
||||
const char *c_str = src.c_str();
|
||||
|
||||
auto s = glCreateShader(type);
|
||||
glShaderSource(s, 1, &c_str, nullptr);
|
||||
glCompileShader(s);
|
||||
|
||||
GLint stat;
|
||||
glGetShaderiv(s, GL_COMPILE_STATUS, &stat);
|
||||
if (!stat) {
|
||||
GLint log_len;
|
||||
glGetShaderiv(s, GL_INFO_LOG_LENGTH, &log_len);
|
||||
char log[log_len];
|
||||
glGetShaderInfoLog(s, log_len, nullptr, log);
|
||||
fprintf(stderr, "SHADER LOG (%s):\n%s", name.c_str(), log);
|
||||
|
||||
glDeleteShader(s);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
GLint build_shader_file(GLenum type, const std::string &name, const std::string &file) {
|
||||
std::string src = read_all_text(file);
|
||||
return build_shader(type, name, src);
|
||||
}
|
||||
|
||||
GLint build_program(const std::string &name, GLint vs, GLint fs) {
|
||||
GLint p = glCreateProgram();
|
||||
glAttachShader(p, vs);
|
||||
glAttachShader(p, fs);
|
||||
glLinkProgram(p);
|
||||
|
||||
GLint stat;
|
||||
glGetProgramiv(p, GL_LINK_STATUS, &stat);
|
||||
if (!stat) {
|
||||
GLint log_len;
|
||||
glGetShaderiv(p, GL_INFO_LOG_LENGTH, &log_len);
|
||||
char log[log_len];
|
||||
glGetProgramInfoLog(p, log_len, nullptr, log);
|
||||
fprintf(stderr, "SHADER LOG (%s):\n%s", name.c_str(), log);
|
||||
|
||||
glDeleteProgram(p);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return p;
|
||||
}
|
||||
60
cosets/src/util/window.hpp
Normal file
60
cosets/src/util/window.hpp
Normal file
@@ -0,0 +1,60 @@
|
||||
#pragma once
|
||||
|
||||
#include <glad/glad.h>
|
||||
#include <GLFW/glfw3.h>
|
||||
#include <cstdlib>
|
||||
#include <cstdio>
|
||||
|
||||
class Window {
|
||||
protected:
|
||||
GLFWwindow *_window = nullptr;
|
||||
|
||||
public:
|
||||
virtual void init() {}
|
||||
|
||||
virtual void update() {}
|
||||
|
||||
virtual void render() {}
|
||||
|
||||
virtual void deinit() {}
|
||||
|
||||
void getBounds(int &width, int &height) {
|
||||
glfwGetFramebufferSize(_window, &width, &height);
|
||||
}
|
||||
|
||||
void swapbuffers() {
|
||||
glfwSwapBuffers(_window);
|
||||
}
|
||||
|
||||
void run() {
|
||||
int _gl_major = 4, _gl_minor = 0;
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, _gl_major);
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, _gl_minor);
|
||||
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
|
||||
|
||||
|
||||
_window = glfwCreateWindow(640, 480, "GLFW App", nullptr, nullptr);
|
||||
if (!_window) {
|
||||
fprintf(stderr, "Failed to create window;");
|
||||
glfwTerminate();
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
glfwMakeContextCurrent(_window);
|
||||
gladLoadGLLoader((GLADloadproc) glfwGetProcAddress);
|
||||
glfwSwapInterval(0);
|
||||
|
||||
init();
|
||||
|
||||
while (!glfwWindowShouldClose(_window)) {
|
||||
update();
|
||||
render();
|
||||
|
||||
glfwPollEvents();
|
||||
}
|
||||
|
||||
deinit();
|
||||
|
||||
glfwDestroyWindow(_window);
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user