diff --git a/vis/include/cgl/buffer.hpp b/vis/include/cgl/buffer.hpp new file mode 100644 index 0000000..e69a9f2 --- /dev/null +++ b/vis/include/cgl/buffer.hpp @@ -0,0 +1,67 @@ +#pragma once + +#include + +#include + +namespace cgl { + template + class buffer { + GLuint id{}; + + public: + buffer() { + glCreateBuffers(1, &id); + } + + buffer(const T &data, GLenum usage = GL_STATIC_DRAW) + : buffer() { + put(data, usage); + } + + buffer(const std::vector &data, GLenum usage = GL_STATIC_DRAW) + : buffer() { + put(data, usage); + } + + buffer(buffer &) = delete; + + buffer(buffer &&o) noexcept { + id = std::exchange(o.id, 0); + }; + + ~buffer() { + glDeleteBuffers(1, &id); + id = 0; + } + + operator GLuint() const { + return id; + } + + [[nodiscard]] size_t size() const { + GLint res; + glGetNamedBufferParameteriv(id, GL_BUFFER_SIZE, &res); + return (size_t) res; + } + + [[nodiscard]] size_t count() const { + return size() / sizeof(T); + } + + void put(const T &data, GLenum usage = GL_STATIC_DRAW) { + glNamedBufferData(id, sizeof(T), &data, usage); + } + + void put(const std::vector &data, GLenum usage = GL_STATIC_DRAW) { + glNamedBufferData(id, sizeof(T) * data.size(), &data[0], usage); + } + + void bound(GLenum target, const std::function &action) const { + glBindBuffer(target, id); + action(); + glBindBuffer(target, 0); + } + }; + +} diff --git a/vis/include/cgl/error.hpp b/vis/include/cgl/error.hpp new file mode 100644 index 0000000..48840b4 --- /dev/null +++ b/vis/include/cgl/error.hpp @@ -0,0 +1,28 @@ +#pragma once + +#include + +#include + +namespace cgl { + class gl_error : public std::domain_error { + public: + explicit gl_error(const std::string &arg) : domain_error(arg) {} + + explicit gl_error(const char *string) : domain_error(string) {} + }; + + class shader_error : public gl_error { + public: + explicit shader_error(const std::string &arg) : gl_error(arg) {} + + explicit shader_error(const char *string) : gl_error(string) {} + }; + + class program_error : public gl_error { + public: + explicit program_error(const std::string &arg) : gl_error(arg) {} + + explicit program_error(const char *string) : gl_error(string) {} + }; +} \ No newline at end of file diff --git a/vis/include/cgl/pipeline.hpp b/vis/include/cgl/pipeline.hpp new file mode 100644 index 0000000..c9d9105 --- /dev/null +++ b/vis/include/cgl/pipeline.hpp @@ -0,0 +1,88 @@ +#pragma once + +#include +#include +#include + +#include + +#include +#include + +#include + +namespace cgl{ + class pipeline { + protected: + GLuint id{}; + + public: + pipeline() { + glCreateProgramPipelines(1, &id); + } + + pipeline(pipeline &) = delete; + + pipeline(pipeline &&o) noexcept { + id = std::exchange(o.id, 0); + } + + ~pipeline() { + glDeleteProgramPipelines(1, &id); + id = 0; + } + + operator GLuint() const { + return id; + } + + [[nodiscard]] int get(GLenum pname) const { + GLint res; + glGetProgramPipelineiv(id, pname, &res); + return (int) res; + } + + [[nodiscard]] std::string get_info_log() const { + auto len = (size_t) get(GL_INFO_LOG_LENGTH); + char buffer[len]; + glGetProgramPipelineInfoLog(id, len, nullptr, buffer); + return std::string(buffer); + } + + pipeline &stage(const shaderprogram &pgm) { + glUseProgramStages(id, GL_VERTEX_SHADER_BIT, pgm); + return *this; + } + + pipeline &stage(const shaderprogram &pgm) { + glUseProgramStages(id, GL_TESS_CONTROL_SHADER_BIT, pgm); + return *this; + } + + pipeline &stage(const shaderprogram &pgm) { + glUseProgramStages(id, GL_TESS_EVALUATION_SHADER_BIT, pgm); + return *this; + } + + pipeline &stage(const shaderprogram &pgm) { + glUseProgramStages(id, GL_GEOMETRY_SHADER_BIT, pgm); + return *this; + } + + pipeline &stage(const shaderprogram &pgm) { + glUseProgramStages(id, GL_FRAGMENT_SHADER_BIT, pgm); + return *this; + } + + pipeline &stage(const shaderprogram &pgm) { + glUseProgramStages(id, GL_COMPUTE_SHADER_BIT, pgm); + return *this; + } + + void bound(const std::function &action) const { + glBindProgramPipeline(id); + action(); + glBindProgramPipeline(0); + } + }; +} \ No newline at end of file diff --git a/vis/include/cgl/program.hpp b/vis/include/cgl/program.hpp new file mode 100644 index 0000000..c9aa3a4 --- /dev/null +++ b/vis/include/cgl/program.hpp @@ -0,0 +1,65 @@ +#pragma once + +#include +#include + +#include + +#include +#include + +#include + +namespace cgl { + class program { + protected: + GLuint id{}; + + public: + program() { + id = glCreateProgram(); + } + + program(program &) = delete; + + program(program &&o) noexcept { + id = std::exchange(o.id, 0); + }; + + ~program() { + glDeleteProgram(id); + } + + operator GLuint() const { + return id; + } + + [[nodiscard]] int get(GLenum pname) const { + GLint res; + glGetProgramiv(id, pname, &res); + return (int) res; + } + + [[nodiscard]] std::string get_info_log() const { + auto len = (size_t) get(GL_INFO_LOG_LENGTH); + char buffer[len]; + glGetProgramInfoLog(id, len, nullptr, buffer); + return std::string(buffer); + } + + template + void attach(const shader &sh) { + glAttachShader(id, sh); + } + + template + void detach(const shader &sh) { + glDetachShader(id, sh); + } + + bool link() { + glLinkProgram(id); + return (bool) get(GL_LINK_STATUS); + } + }; +} \ No newline at end of file diff --git a/vis/include/cgl/render.hpp b/vis/include/cgl/render.hpp deleted file mode 100644 index 37d20dc..0000000 --- a/vis/include/cgl/render.hpp +++ /dev/null @@ -1,355 +0,0 @@ -#pragma once - -#include - -#include - -namespace cgl { - template - class buffer { - GLuint id{}; - - public: - buffer() { - glCreateBuffers(1, &id); - } - - buffer(const T &data, GLenum usage = GL_STATIC_DRAW) - : buffer() { - put(data, usage); - } - - buffer(const std::vector &data, GLenum usage = GL_STATIC_DRAW) - : buffer() { - put(data, usage); - } - - buffer(buffer &) = delete; - - buffer(buffer &&o) noexcept { - id = std::exchange(o.id, 0); - }; - - ~buffer() { - glDeleteBuffers(1, &id); - id = 0; - } - - operator GLuint() const { - return id; - } - - [[nodiscard]] size_t size() const { - GLint res; - glGetNamedBufferParameteriv(id, GL_BUFFER_SIZE, &res); - return (size_t) res; - } - - [[nodiscard]] size_t count() const { - return size() / sizeof(T); - } - - void put(const T &data, GLenum usage = GL_STATIC_DRAW) { - glNamedBufferData(id, sizeof(T), &data, usage); - } - - void put(const std::vector &data, GLenum usage = GL_STATIC_DRAW) { - glNamedBufferData(id, sizeof(T) * data.size(), &data[0], usage); - } - - void bound(GLenum target, const std::function &action) const { - glBindBuffer(target, id); - action(); - glBindBuffer(target, 0); - } - }; - - template - class shader { - protected: - GLuint id{}; - - public: - shader() { - id = glCreateShader(mode); - } - - shader(const std::string &src) : shader() { - set_source(src); - - if (!compile()) - throw shader_error(get_info_log()); - } - - static shader file(const std::string &name) { - return shader(utilReadFile(name)); - } - - shader(shader &) = delete; - - shader(shader &&o) noexcept { - id = std::exchange(o.id, 0); - }; - - ~shader() { - glDeleteShader(id); - } - - operator GLuint() const { - return id; - } - - [[nodiscard]] int get(GLenum pname) const { - GLint res; - glGetShaderiv(id, pname, &res); - return (int) res; - } - - [[nodiscard]] std::string get_info_log() const { - auto len = (size_t) get(GL_INFO_LOG_LENGTH); - char buffer[len]; - glGetShaderInfoLog(id, len, nullptr, buffer); - return std::string(buffer); - } - - void set_source(const std::string &src) { - const char *c_src = src.c_str(); - glShaderSource(id, 1, &c_src, nullptr); - } - - bool compile() { - glCompileShader(id); - return (bool) get(GL_COMPILE_STATUS); - } - }; - - class program { - protected: - GLuint id{}; - - public: - program() { - id = glCreateProgram(); - } - - program(program &) = delete; - - program(program &&o) noexcept { - id = std::exchange(o.id, 0); - }; - - ~program() { - glDeleteProgram(id); - } - - operator GLuint() const { - return id; - } - - [[nodiscard]] int get(GLenum pname) const { - GLint res; - glGetProgramiv(id, pname, &res); - return (int) res; - } - - [[nodiscard]] std::string get_info_log() const { - auto len = (size_t) get(GL_INFO_LOG_LENGTH); - char buffer[len]; - glGetProgramInfoLog(id, len, nullptr, buffer); - return std::string(buffer); - } - - template - void attach(const shader &sh) { - glAttachShader(id, sh); - } - - template - void detach(const shader &sh) { - glDetachShader(id, sh); - } - - bool link() { - glLinkProgram(id); - return (bool) get(GL_LINK_STATUS); - } - }; - - template - class shaderprogram : public program { - public: - shaderprogram() : program() { - glProgramParameteri(id, GL_PROGRAM_SEPARABLE, GL_TRUE); - } - - shaderprogram(const std::string &src) : shaderprogram() { - shader sh(src); - - attach(sh); - - if (!link()) - throw shader_error(get_info_log()); - - detach(sh); - } - - static shaderprogram file(const std::string &name) { - return shaderprogram(utilReadFile(name)); - } - }; - - class pipeline { - protected: - GLuint id{}; - - public: - pipeline() { - glCreateProgramPipelines(1, &id); - } - - pipeline(pipeline &) = delete; - - pipeline(pipeline &&o) noexcept { - id = std::exchange(o.id, 0); - } - - ~pipeline() { - glDeleteProgramPipelines(1, &id); - id = 0; - } - - operator GLuint() const { - return id; - } - - [[nodiscard]] int get(GLenum pname) const { - GLint res; - glGetProgramPipelineiv(id, pname, &res); - return (int) res; - } - - [[nodiscard]] std::string get_info_log() const { - auto len = (size_t) get(GL_INFO_LOG_LENGTH); - char buffer[len]; - glGetProgramPipelineInfoLog(id, len, nullptr, buffer); - return std::string(buffer); - } - - pipeline &stage(const shaderprogram &pgm) { - glUseProgramStages(id, GL_VERTEX_SHADER_BIT, pgm); - return *this; - } - - pipeline &stage(const shaderprogram &pgm) { - glUseProgramStages(id, GL_TESS_CONTROL_SHADER_BIT, pgm); - return *this; - } - - pipeline &stage(const shaderprogram &pgm) { - glUseProgramStages(id, GL_TESS_EVALUATION_SHADER_BIT, pgm); - return *this; - } - - pipeline &stage(const shaderprogram &pgm) { - glUseProgramStages(id, GL_GEOMETRY_SHADER_BIT, pgm); - return *this; - } - - pipeline &stage(const shaderprogram &pgm) { - glUseProgramStages(id, GL_FRAGMENT_SHADER_BIT, pgm); - return *this; - } - - pipeline &stage(const shaderprogram &pgm) { - glUseProgramStages(id, GL_COMPUTE_SHADER_BIT, pgm); - return *this; - } - - void bound(const std::function &action) const { - glBindProgramPipeline(id); - action(); - glBindProgramPipeline(0); - } - }; - - namespace sh { - using vert = shader; - using tcs = shader; - using tes = shader; - using geom = shader; - using frag = shader; - using comp = shader; - } - - namespace pgm { - using vert = shaderprogram; - using tcs = shaderprogram; - using tes = shaderprogram; - using geom = shaderprogram; - using frag = shaderprogram; - using comp = shaderprogram; - } - - class vertexarray { - GLuint id{}; - - public: - vertexarray() { - glCreateVertexArrays(1, &id); - } - - vertexarray(vertexarray &) = delete; - - vertexarray(vertexarray &&o) noexcept { - id = std::exchange(o.id, 0); - } - - ~vertexarray() { - glDeleteVertexArrays(1, &id); - id = 0; - } - - operator GLuint() const { - return id; - } - - void bound(const std::function &action) const { - glBindVertexArray(id); - action(); - glBindVertexArray(0); - } - - template - void pointer( - GLuint index, - const buffer &buf, - unsigned size, - GLenum type, - bool normalized = false, - unsigned stride = 0 - ) const { - bound([&]() { - glEnableVertexAttribArray(index); - buf.bound(GL_ARRAY_BUFFER, [&]() { - glVertexAttribPointer(index, size, type, normalized, stride, nullptr); - }); - }); - } - - template - void ipointer( - GLuint index, - const buffer &buf, - unsigned size, - GLenum type, - unsigned stride = 0 - ) const { - bound([&]() { - glEnableVertexAttribArray(index); - buf.bound(GL_ARRAY_BUFFER, [&]() { - glVertexAttribIPointer(index, size, type, stride, nullptr); - }); - }); - } - }; -} diff --git a/vis/include/cgl/shader.hpp b/vis/include/cgl/shader.hpp new file mode 100644 index 0000000..bce89a0 --- /dev/null +++ b/vis/include/cgl/shader.hpp @@ -0,0 +1,80 @@ +#pragma once + +#include +#include + +#include + +#include + +#include + +namespace cgl { + template + class shader { + protected: + GLuint id{}; + + public: + shader() { + id = glCreateShader(mode); + } + + shader(const std::string &src) : shader() { + set_source(src); + + if (!compile()) + throw shader_error(get_info_log()); + } + + static shader file(const std::string &name) { + return shader(utilReadFile(name)); + } + + shader(shader &) = delete; + + shader(shader &&o) noexcept { + id = std::exchange(o.id, 0); + }; + + ~shader() { + glDeleteShader(id); + } + + operator GLuint() const { + return id; + } + + [[nodiscard]] int get(GLenum pname) const { + GLint res; + glGetShaderiv(id, pname, &res); + return (int) res; + } + + [[nodiscard]] std::string get_info_log() const { + auto len = (size_t) get(GL_INFO_LOG_LENGTH); + char buffer[len]; + glGetShaderInfoLog(id, len, nullptr, buffer); + return std::string(buffer); + } + + void set_source(const std::string &src) { + const char *c_src = src.c_str(); + glShaderSource(id, 1, &c_src, nullptr); + } + + bool compile() { + glCompileShader(id); + return (bool) get(GL_COMPILE_STATUS); + } + }; + + namespace sh { + using vert = shader; + using tcs = shader; + using tes = shader; + using geom = shader; + using frag = shader; + using comp = shader; + } +} diff --git a/vis/include/cgl/shaderprogram.hpp b/vis/include/cgl/shaderprogram.hpp new file mode 100644 index 0000000..3aacf9f --- /dev/null +++ b/vis/include/cgl/shaderprogram.hpp @@ -0,0 +1,46 @@ +#pragma once + +#include +#include + +#include + +#include +#include +#include + +#include + +namespace cgl{ + template + class shaderprogram : public program { + public: + shaderprogram() : program() { + glProgramParameteri(id, GL_PROGRAM_SEPARABLE, GL_TRUE); + } + + shaderprogram(const std::string &src) : shaderprogram() { + shader sh(src); + + attach(sh); + + if (!link()) + throw shader_error(get_info_log()); + + detach(sh); + } + + static shaderprogram file(const std::string &name) { + return shaderprogram(utilReadFile(name)); + } + }; + + namespace pgm { + using vert = shaderprogram; + using tcs = shaderprogram; + using tes = shaderprogram; + using geom = shaderprogram; + using frag = shaderprogram; + using comp = shaderprogram; + } +} \ No newline at end of file diff --git a/vis/include/cgl/vertexarray.hpp b/vis/include/cgl/vertexarray.hpp new file mode 100644 index 0000000..fa00b2e --- /dev/null +++ b/vis/include/cgl/vertexarray.hpp @@ -0,0 +1,75 @@ +#pragma once + +#include +#include +#include + +#include + +#include +#include + +namespace cgl { + class vertexarray { + GLuint id{}; + + public: + vertexarray() { + glCreateVertexArrays(1, &id); + } + + vertexarray(vertexarray &) = delete; + + vertexarray(vertexarray &&o) noexcept { + id = std::exchange(o.id, 0); + } + + ~vertexarray() { + glDeleteVertexArrays(1, &id); + id = 0; + } + + operator GLuint() const { + return id; + } + + void bound(const std::function &action) const { + glBindVertexArray(id); + action(); + glBindVertexArray(0); + } + + template + void pointer( + GLuint index, + const buffer &buf, + unsigned size, + GLenum type, + bool normalized = false, + unsigned stride = 0 + ) const { + bound([&]() { + glEnableVertexAttribArray(index); + buf.bound(GL_ARRAY_BUFFER, [&]() { + glVertexAttribPointer(index, size, type, normalized, stride, nullptr); + }); + }); + } + + template + void ipointer( + GLuint index, + const buffer &buf, + unsigned size, + GLenum type, + unsigned stride = 0 + ) const { + bound([&]() { + glEnableVertexAttribArray(index); + buf.bound(GL_ARRAY_BUFFER, [&]() { + glVertexAttribIPointer(index, size, type, stride, nullptr); + }); + }); + } + }; +} \ No newline at end of file diff --git a/vis/include/util.hpp b/vis/include/util.hpp index e4a1807..efef3a7 100644 --- a/vis/include/util.hpp +++ b/vis/include/util.hpp @@ -8,70 +8,6 @@ #include -class gl_error : public std::domain_error { -public: - explicit gl_error(const std::string &arg) : domain_error(arg) {} - - explicit gl_error(const char *string) : domain_error(string) {} -}; - -template -class shader_error : public gl_error { -public: - explicit shader_error(const std::string &arg) : gl_error(arg) {} - - explicit shader_error(const char *string) : gl_error(string) {} -}; - -class program_error : public gl_error { -public: - explicit program_error(const std::string &arg) : gl_error(arg) {} - - explicit program_error(const char *string) : gl_error(string) {} -}; - -template -T utilGetShader(GLuint shader) { - GLint res; - glGetShaderiv(shader, prop, &res); - return static_cast(res); -} - -#define getShaderInfoLogLength utilGetShader -#define getShaderCompileStatus utilGetShader - -template -T utilGetProgram(GLuint program) { - GLint res; - glGetProgramiv(program, prop, &res); - return static_cast(res); -} - -#define getProgramInfoLogLength utilGetProgram -#define getProgramLinkStatus utilGetProgram - -void utilShaderSource(GLuint shader, const std::vector &sources) { - char const *ptrs[sources.size()]; - for (size_t i = 0; i < sources.size(); ++i) { - ptrs[i] = sources[i].c_str(); - } - glShaderSource(shader, sources.size(), ptrs, nullptr); -} - -std::string getShaderInfoLog(GLuint shader) { - int len = getShaderInfoLogLength(shader); - char buffer[len]; - glGetShaderInfoLog(shader, len, nullptr, buffer); - return std::string(buffer); -} - -std::string getProgramInfoLog(GLuint program) { - int len = getProgramInfoLogLength(program); - char buffer[len]; - glGetProgramInfoLog(program, len, nullptr, buffer); - return std::string(buffer); -} - std::string utilInfo() { std::stringstream ss; ss @@ -93,70 +29,3 @@ std::string utilReadFile(const std::string &filename) { } throw std::system_error(errno, std::generic_category()); } - -GLuint utilCompileFiles(const GLenum type, const std::vector &files) { - std::vector sources; - sources.reserve(files.size()); - for (const auto &file : files) { - sources.push_back(utilReadFile(file)); - } - - GLuint shader = glCreateShader(type); - utilShaderSource(shader, sources); - glCompileShader(shader); - - if (getShaderCompileStatus(shader)) return shader; - - throw shader_error(getShaderInfoLog(shader)); -} - -GLuint utilLinkProgram(const std::vector &shaders) { - GLuint program = glCreateProgram(); - for (const auto &shader : shaders) { - glAttachShader(program, shader); - } - glLinkProgram(program); - - if (getProgramLinkStatus(program)) return program; - - throw program_error(getProgramInfoLog(program)); -} - -GLuint utilCreateShaderProgram(GLenum type, const std::vector &src) { - std::vector c_str(src.size()); - std::transform(src.begin(), src.end(), c_str.begin(), [](auto &str) { - return str.c_str(); - }); - - GLuint program = glCreateShaderProgramv(type, src.size(), &c_str[0]); - - if (getProgramLinkStatus(program)) return program; - - throw program_error(getProgramInfoLog(program)); -} - -GLuint utilCreateShaderProgramFile(GLenum type, const std::vector &files) { - std::vector sources(files.size()); - std::transform(files.begin(), files.end(), sources.begin(), utilReadFile); - return utilCreateShaderProgram(type, sources); -} - -std::vector utilCreateVertexArrays(int n) { - std::vector res(n); - glCreateVertexArrays(n, &res[0]); - return res; -} - -GLuint utilCreateVertexArray() { - return utilCreateVertexArrays(1)[0]; -} - -std::vector utilCreateBuffers(int n) { - std::vector res(n); - glCreateBuffers(n, &res[0]); - return res; -} - -GLuint utilCreateBuffer() { - return utilCreateBuffers(1)[0]; -} \ No newline at end of file diff --git a/vis/src/main.cpp b/vis/src/main.cpp index 11099d8..5e817dd 100644 --- a/vis/src/main.cpp +++ b/vis/src/main.cpp @@ -11,7 +11,9 @@ #include "mirror.hpp" #include "geometry.hpp" -#include +#include +#include +#include #ifdef _WIN32 extern "C" {