mirror of
https://github.com/allemangD/toddcox-visualize.git
synced 2025-11-10 12:02:47 -05:00
break render apart into multiple files
This commit is contained in:
67
vis/include/cgl/buffer.hpp
Normal file
67
vis/include/cgl/buffer.hpp
Normal file
@@ -0,0 +1,67 @@
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include <glad/glad.h>
|
||||
|
||||
namespace cgl {
|
||||
template<class T>
|
||||
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<T> &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<T> &data, GLenum usage = GL_STATIC_DRAW) {
|
||||
glNamedBufferData(id, sizeof(T) * data.size(), &data[0], usage);
|
||||
}
|
||||
|
||||
void bound(GLenum target, const std::function<void()> &action) const {
|
||||
glBindBuffer(target, id);
|
||||
action();
|
||||
glBindBuffer(target, 0);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
28
vis/include/cgl/error.hpp
Normal file
28
vis/include/cgl/error.hpp
Normal file
@@ -0,0 +1,28 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdexcept>
|
||||
|
||||
#include <glad/glad.h>
|
||||
|
||||
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) {}
|
||||
};
|
||||
}
|
||||
88
vis/include/cgl/pipeline.hpp
Normal file
88
vis/include/cgl/pipeline.hpp
Normal file
@@ -0,0 +1,88 @@
|
||||
#pragma once
|
||||
|
||||
#include <functional>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
#include <glad/glad.h>
|
||||
|
||||
#include <cgl/error.hpp>
|
||||
#include <cgl/shaderprogram.hpp>
|
||||
|
||||
#include <util.hpp>
|
||||
|
||||
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<GL_VERTEX_SHADER> &pgm) {
|
||||
glUseProgramStages(id, GL_VERTEX_SHADER_BIT, pgm);
|
||||
return *this;
|
||||
}
|
||||
|
||||
pipeline &stage(const shaderprogram<GL_TESS_CONTROL_SHADER> &pgm) {
|
||||
glUseProgramStages(id, GL_TESS_CONTROL_SHADER_BIT, pgm);
|
||||
return *this;
|
||||
}
|
||||
|
||||
pipeline &stage(const shaderprogram<GL_TESS_EVALUATION_SHADER> &pgm) {
|
||||
glUseProgramStages(id, GL_TESS_EVALUATION_SHADER_BIT, pgm);
|
||||
return *this;
|
||||
}
|
||||
|
||||
pipeline &stage(const shaderprogram<GL_GEOMETRY_SHADER> &pgm) {
|
||||
glUseProgramStages(id, GL_GEOMETRY_SHADER_BIT, pgm);
|
||||
return *this;
|
||||
}
|
||||
|
||||
pipeline &stage(const shaderprogram<GL_FRAGMENT_SHADER> &pgm) {
|
||||
glUseProgramStages(id, GL_FRAGMENT_SHADER_BIT, pgm);
|
||||
return *this;
|
||||
}
|
||||
|
||||
pipeline &stage(const shaderprogram<GL_COMPUTE_SHADER> &pgm) {
|
||||
glUseProgramStages(id, GL_COMPUTE_SHADER_BIT, pgm);
|
||||
return *this;
|
||||
}
|
||||
|
||||
void bound(const std::function<void()> &action) const {
|
||||
glBindProgramPipeline(id);
|
||||
action();
|
||||
glBindProgramPipeline(0);
|
||||
}
|
||||
};
|
||||
}
|
||||
65
vis/include/cgl/program.hpp
Normal file
65
vis/include/cgl/program.hpp
Normal file
@@ -0,0 +1,65 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
#include <glad/glad.h>
|
||||
|
||||
#include <cgl/error.hpp>
|
||||
#include <cgl/shader.hpp>
|
||||
|
||||
#include <util.hpp>
|
||||
|
||||
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<GLenum mode>
|
||||
void attach(const shader<mode> &sh) {
|
||||
glAttachShader(id, sh);
|
||||
}
|
||||
|
||||
template<GLenum mode>
|
||||
void detach(const shader<mode> &sh) {
|
||||
glDetachShader(id, sh);
|
||||
}
|
||||
|
||||
bool link() {
|
||||
glLinkProgram(id);
|
||||
return (bool) get(GL_LINK_STATUS);
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -1,355 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include <glad/glad.h>
|
||||
|
||||
namespace cgl {
|
||||
template<class T>
|
||||
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<T> &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<T> &data, GLenum usage = GL_STATIC_DRAW) {
|
||||
glNamedBufferData(id, sizeof(T) * data.size(), &data[0], usage);
|
||||
}
|
||||
|
||||
void bound(GLenum target, const std::function<void()> &action) const {
|
||||
glBindBuffer(target, id);
|
||||
action();
|
||||
glBindBuffer(target, 0);
|
||||
}
|
||||
};
|
||||
|
||||
template<GLenum mode>
|
||||
class shader {
|
||||
protected:
|
||||
GLuint id{};
|
||||
|
||||
public:
|
||||
shader() {
|
||||
id = glCreateShader(mode);
|
||||
}
|
||||
|
||||
shader(const std::string &src) : shader() {
|
||||
set_source(src);
|
||||
|
||||
if (!compile())
|
||||
throw shader_error<mode>(get_info_log());
|
||||
}
|
||||
|
||||
static shader<mode> file(const std::string &name) {
|
||||
return shader<mode>(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<GLenum mode>
|
||||
void attach(const shader<mode> &sh) {
|
||||
glAttachShader(id, sh);
|
||||
}
|
||||
|
||||
template<GLenum mode>
|
||||
void detach(const shader<mode> &sh) {
|
||||
glDetachShader(id, sh);
|
||||
}
|
||||
|
||||
bool link() {
|
||||
glLinkProgram(id);
|
||||
return (bool) get(GL_LINK_STATUS);
|
||||
}
|
||||
};
|
||||
|
||||
template<GLenum mode>
|
||||
class shaderprogram : public program {
|
||||
public:
|
||||
shaderprogram() : program() {
|
||||
glProgramParameteri(id, GL_PROGRAM_SEPARABLE, GL_TRUE);
|
||||
}
|
||||
|
||||
shaderprogram(const std::string &src) : shaderprogram() {
|
||||
shader<mode> sh(src);
|
||||
|
||||
attach(sh);
|
||||
|
||||
if (!link())
|
||||
throw shader_error<mode>(get_info_log());
|
||||
|
||||
detach(sh);
|
||||
}
|
||||
|
||||
static shaderprogram<mode> file(const std::string &name) {
|
||||
return shaderprogram<mode>(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<GL_VERTEX_SHADER> &pgm) {
|
||||
glUseProgramStages(id, GL_VERTEX_SHADER_BIT, pgm);
|
||||
return *this;
|
||||
}
|
||||
|
||||
pipeline &stage(const shaderprogram<GL_TESS_CONTROL_SHADER> &pgm) {
|
||||
glUseProgramStages(id, GL_TESS_CONTROL_SHADER_BIT, pgm);
|
||||
return *this;
|
||||
}
|
||||
|
||||
pipeline &stage(const shaderprogram<GL_TESS_EVALUATION_SHADER> &pgm) {
|
||||
glUseProgramStages(id, GL_TESS_EVALUATION_SHADER_BIT, pgm);
|
||||
return *this;
|
||||
}
|
||||
|
||||
pipeline &stage(const shaderprogram<GL_GEOMETRY_SHADER> &pgm) {
|
||||
glUseProgramStages(id, GL_GEOMETRY_SHADER_BIT, pgm);
|
||||
return *this;
|
||||
}
|
||||
|
||||
pipeline &stage(const shaderprogram<GL_FRAGMENT_SHADER> &pgm) {
|
||||
glUseProgramStages(id, GL_FRAGMENT_SHADER_BIT, pgm);
|
||||
return *this;
|
||||
}
|
||||
|
||||
pipeline &stage(const shaderprogram<GL_COMPUTE_SHADER> &pgm) {
|
||||
glUseProgramStages(id, GL_COMPUTE_SHADER_BIT, pgm);
|
||||
return *this;
|
||||
}
|
||||
|
||||
void bound(const std::function<void()> &action) const {
|
||||
glBindProgramPipeline(id);
|
||||
action();
|
||||
glBindProgramPipeline(0);
|
||||
}
|
||||
};
|
||||
|
||||
namespace sh {
|
||||
using vert = shader<GL_VERTEX_SHADER>;
|
||||
using tcs = shader<GL_TESS_CONTROL_SHADER>;
|
||||
using tes = shader<GL_TESS_EVALUATION_SHADER>;
|
||||
using geom = shader<GL_GEOMETRY_SHADER>;
|
||||
using frag = shader<GL_FRAGMENT_SHADER>;
|
||||
using comp = shader<GL_COMPUTE_SHADER>;
|
||||
}
|
||||
|
||||
namespace pgm {
|
||||
using vert = shaderprogram<GL_VERTEX_SHADER>;
|
||||
using tcs = shaderprogram<GL_TESS_CONTROL_SHADER>;
|
||||
using tes = shaderprogram<GL_TESS_EVALUATION_SHADER>;
|
||||
using geom = shaderprogram<GL_GEOMETRY_SHADER>;
|
||||
using frag = shaderprogram<GL_FRAGMENT_SHADER>;
|
||||
using comp = shaderprogram<GL_COMPUTE_SHADER>;
|
||||
}
|
||||
|
||||
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<void()> &action) const {
|
||||
glBindVertexArray(id);
|
||||
action();
|
||||
glBindVertexArray(0);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void pointer(
|
||||
GLuint index,
|
||||
const buffer<T> &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<class T>
|
||||
void ipointer(
|
||||
GLuint index,
|
||||
const buffer<T> &buf,
|
||||
unsigned size,
|
||||
GLenum type,
|
||||
unsigned stride = 0
|
||||
) const {
|
||||
bound([&]() {
|
||||
glEnableVertexAttribArray(index);
|
||||
buf.bound(GL_ARRAY_BUFFER, [&]() {
|
||||
glVertexAttribIPointer(index, size, type, stride, nullptr);
|
||||
});
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
80
vis/include/cgl/shader.hpp
Normal file
80
vis/include/cgl/shader.hpp
Normal file
@@ -0,0 +1,80 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
#include <glad/glad.h>
|
||||
|
||||
#include <cgl/error.hpp>
|
||||
|
||||
#include <util.hpp>
|
||||
|
||||
namespace cgl {
|
||||
template<GLenum mode>
|
||||
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<mode> file(const std::string &name) {
|
||||
return shader<mode>(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<GL_VERTEX_SHADER>;
|
||||
using tcs = shader<GL_TESS_CONTROL_SHADER>;
|
||||
using tes = shader<GL_TESS_EVALUATION_SHADER>;
|
||||
using geom = shader<GL_GEOMETRY_SHADER>;
|
||||
using frag = shader<GL_FRAGMENT_SHADER>;
|
||||
using comp = shader<GL_COMPUTE_SHADER>;
|
||||
}
|
||||
}
|
||||
46
vis/include/cgl/shaderprogram.hpp
Normal file
46
vis/include/cgl/shaderprogram.hpp
Normal file
@@ -0,0 +1,46 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
#include <glad/glad.h>
|
||||
|
||||
#include <cgl/error.hpp>
|
||||
#include <cgl/shader.hpp>
|
||||
#include <cgl/program.hpp>
|
||||
|
||||
#include <util.hpp>
|
||||
|
||||
namespace cgl{
|
||||
template<GLenum mode>
|
||||
class shaderprogram : public program {
|
||||
public:
|
||||
shaderprogram() : program() {
|
||||
glProgramParameteri(id, GL_PROGRAM_SEPARABLE, GL_TRUE);
|
||||
}
|
||||
|
||||
shaderprogram(const std::string &src) : shaderprogram() {
|
||||
shader<mode> sh(src);
|
||||
|
||||
attach(sh);
|
||||
|
||||
if (!link())
|
||||
throw shader_error(get_info_log());
|
||||
|
||||
detach(sh);
|
||||
}
|
||||
|
||||
static shaderprogram<mode> file(const std::string &name) {
|
||||
return shaderprogram<mode>(utilReadFile(name));
|
||||
}
|
||||
};
|
||||
|
||||
namespace pgm {
|
||||
using vert = shaderprogram<GL_VERTEX_SHADER>;
|
||||
using tcs = shaderprogram<GL_TESS_CONTROL_SHADER>;
|
||||
using tes = shaderprogram<GL_TESS_EVALUATION_SHADER>;
|
||||
using geom = shaderprogram<GL_GEOMETRY_SHADER>;
|
||||
using frag = shaderprogram<GL_FRAGMENT_SHADER>;
|
||||
using comp = shaderprogram<GL_COMPUTE_SHADER>;
|
||||
}
|
||||
}
|
||||
75
vis/include/cgl/vertexarray.hpp
Normal file
75
vis/include/cgl/vertexarray.hpp
Normal file
@@ -0,0 +1,75 @@
|
||||
#pragma once
|
||||
|
||||
#include <functional>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
#include <glad/glad.h>
|
||||
|
||||
#include <cgl/error.hpp>
|
||||
#include <cgl/buffer.hpp>
|
||||
|
||||
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<void()> &action) const {
|
||||
glBindVertexArray(id);
|
||||
action();
|
||||
glBindVertexArray(0);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void pointer(
|
||||
GLuint index,
|
||||
const buffer<T> &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<class T>
|
||||
void ipointer(
|
||||
GLuint index,
|
||||
const buffer<T> &buf,
|
||||
unsigned size,
|
||||
GLenum type,
|
||||
unsigned stride = 0
|
||||
) const {
|
||||
bound([&]() {
|
||||
glEnableVertexAttribArray(index);
|
||||
buf.bound(GL_ARRAY_BUFFER, [&]() {
|
||||
glVertexAttribIPointer(index, size, type, stride, nullptr);
|
||||
});
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -8,70 +8,6 @@
|
||||
|
||||
#include <glad/glad.h>
|
||||
|
||||
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<GLenum mode>
|
||||
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<class T, GLenum prop>
|
||||
T utilGetShader(GLuint shader) {
|
||||
GLint res;
|
||||
glGetShaderiv(shader, prop, &res);
|
||||
return static_cast<T>(res);
|
||||
}
|
||||
|
||||
#define getShaderInfoLogLength utilGetShader<size_t, GL_INFO_LOG_LENGTH>
|
||||
#define getShaderCompileStatus utilGetShader<size_t, GL_COMPILE_STATUS>
|
||||
|
||||
template<class T, GLenum prop>
|
||||
T utilGetProgram(GLuint program) {
|
||||
GLint res;
|
||||
glGetProgramiv(program, prop, &res);
|
||||
return static_cast<T>(res);
|
||||
}
|
||||
|
||||
#define getProgramInfoLogLength utilGetProgram<size_t, GL_INFO_LOG_LENGTH>
|
||||
#define getProgramLinkStatus utilGetProgram<size_t, GL_LINK_STATUS>
|
||||
|
||||
void utilShaderSource(GLuint shader, const std::vector<std::string> &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<std::string> &files) {
|
||||
std::vector<std::string> 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<GL_VERTEX_SHADER>(getShaderInfoLog(shader));
|
||||
}
|
||||
|
||||
GLuint utilLinkProgram(const std::vector<GLuint> &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<std::string> &src) {
|
||||
std::vector<const char *> 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<std::string> &files) {
|
||||
std::vector<std::string> sources(files.size());
|
||||
std::transform(files.begin(), files.end(), sources.begin(), utilReadFile);
|
||||
return utilCreateShaderProgram(type, sources);
|
||||
}
|
||||
|
||||
std::vector<GLuint> utilCreateVertexArrays(int n) {
|
||||
std::vector<GLuint> res(n);
|
||||
glCreateVertexArrays(n, &res[0]);
|
||||
return res;
|
||||
}
|
||||
|
||||
GLuint utilCreateVertexArray() {
|
||||
return utilCreateVertexArrays(1)[0];
|
||||
}
|
||||
|
||||
std::vector<GLuint> utilCreateBuffers(int n) {
|
||||
std::vector<GLuint> res(n);
|
||||
glCreateBuffers(n, &res[0]);
|
||||
return res;
|
||||
}
|
||||
|
||||
GLuint utilCreateBuffer() {
|
||||
return utilCreateBuffers(1)[0];
|
||||
}
|
||||
Reference in New Issue
Block a user