diff --git a/libs/gfx/include/psemek/gfx/buffer.hpp b/libs/gfx/include/psemek/gfx/buffer.hpp index 023cb254..3cb3d273 100644 --- a/libs/gfx/include/psemek/gfx/buffer.hpp +++ b/libs/gfx/include/psemek/gfx/buffer.hpp @@ -10,20 +10,21 @@ namespace psemek::gfx struct buffer { buffer(); - buffer(buffer const &) = delete; buffer(buffer &&); - - buffer & operator = (buffer const &) = delete; buffer & operator = (buffer &&); - ~buffer(); + buffer(buffer const &) = delete; + buffer & operator = (buffer const &) = delete; + static buffer null(); GLuint id() const { return id_; } void bind() const; + void reset(); + void load(void const * data, std::size_t size, GLenum usage = gl::STREAM_DRAW); template @@ -41,7 +42,7 @@ namespace psemek::gfx private: GLuint id_; - explicit buffer(GLuint id); + explicit buffer(std::nullptr_t); }; } diff --git a/libs/gfx/include/psemek/gfx/framebuffer.hpp b/libs/gfx/include/psemek/gfx/framebuffer.hpp index 00174aff..e291a6a3 100644 --- a/libs/gfx/include/psemek/gfx/framebuffer.hpp +++ b/libs/gfx/include/psemek/gfx/framebuffer.hpp @@ -10,20 +10,21 @@ namespace psemek::gfx struct framebuffer { framebuffer(); - framebuffer(framebuffer const &) = delete; framebuffer(framebuffer &&); - - framebuffer & operator = (framebuffer const &) = delete; framebuffer & operator = (framebuffer &&); - ~framebuffer(); + framebuffer(framebuffer const &) = delete; + framebuffer & operator = (framebuffer const &) = delete; + static framebuffer null(); GLuint id() const { return id_; } void bind() const; + void reset(); + void color(texture_1d const & tex, int attachment = 0); void color(texture_2d const & tex, int attachment = 0); void color(texture_3d const & tex, int layer, int attachment = 0); @@ -38,7 +39,7 @@ namespace psemek::gfx private: GLuint id_; - explicit framebuffer(GLuint id); + explicit framebuffer(std::nullptr_t); }; } diff --git a/libs/gfx/include/psemek/gfx/renderbuffer.hpp b/libs/gfx/include/psemek/gfx/renderbuffer.hpp index ce91fed6..ccef0dbf 100644 --- a/libs/gfx/include/psemek/gfx/renderbuffer.hpp +++ b/libs/gfx/include/psemek/gfx/renderbuffer.hpp @@ -2,32 +2,35 @@ #include +#include + namespace psemek::gfx { struct renderbuffer { renderbuffer(); - renderbuffer(renderbuffer const &) = delete; renderbuffer(renderbuffer &&); - - renderbuffer & operator = (renderbuffer const &) = delete; renderbuffer & operator = (renderbuffer &&); - ~renderbuffer(); + renderbuffer(renderbuffer const &) = delete; + renderbuffer & operator = (renderbuffer const &) = delete; + static renderbuffer null(); GLuint id() const { return id_; } void bind() const; + void reset(); + void storage(GLenum internal_format, GLsizei width, GLsizei height); private: GLuint id_; - explicit renderbuffer(GLuint id); + explicit renderbuffer(std::nullptr_t); }; } diff --git a/libs/gfx/include/psemek/gfx/texture.hpp b/libs/gfx/include/psemek/gfx/texture.hpp index 2d8ca677..c2262a1b 100644 --- a/libs/gfx/include/psemek/gfx/texture.hpp +++ b/libs/gfx/include/psemek/gfx/texture.hpp @@ -152,6 +152,12 @@ namespace psemek::gfx using texture_2d_array = basic_texture<3, gl::TEXTURE_2D_ARRAY>; using texture_3d = basic_texture<3, gl::TEXTURE_3D>; + extern template struct basic_texture<1, gl::TEXTURE_1D>; + extern template struct basic_texture<2, gl::TEXTURE_1D_ARRAY>; + extern template struct basic_texture<2, gl::TEXTURE_2D>; + extern template struct basic_texture<3, gl::TEXTURE_2D_ARRAY>; + extern template struct basic_texture<3, gl::TEXTURE_3D>; + namespace detail { std::optional max_anisotropy(); diff --git a/libs/gfx/source/buffer.cpp b/libs/gfx/source/buffer.cpp index d8a39312..9c0873c7 100644 --- a/libs/gfx/source/buffer.cpp +++ b/libs/gfx/source/buffer.cpp @@ -9,7 +9,7 @@ namespace psemek::gfx } buffer::buffer(buffer && other) - : id_(other.id_) + : id_{other.id_} { other.id_ = 0; } @@ -18,20 +18,19 @@ namespace psemek::gfx { if (this == &other) return *this; - gl::DeleteBuffers(1, &id_); - id_ = other.id_; - other.id_ = 0; + reset(); + std::swap(id_, other.id_); return *this; } buffer::~buffer() { - gl::DeleteBuffers(1, &id_); + reset(); } buffer buffer::null() { - return buffer(0); + return buffer(nullptr); } void buffer::bind() const @@ -39,14 +38,21 @@ namespace psemek::gfx gl::BindBuffer(gl::ARRAY_BUFFER, id_); } + void buffer::reset() + { + if (id_ != 0) + gl::DeleteBuffers(1, &id_); + id_ = 0; + } + void buffer::load(void const * data, std::size_t size, GLenum usage) { bind(); gl::BufferData(gl::ARRAY_BUFFER, size, data, usage); } - buffer::buffer(GLuint id) - : id_(id) + buffer::buffer(std::nullptr_t) + : id_{0} {} } diff --git a/libs/gfx/source/framebuffer.cpp b/libs/gfx/source/framebuffer.cpp index b0a4349a..f95109d7 100644 --- a/libs/gfx/source/framebuffer.cpp +++ b/libs/gfx/source/framebuffer.cpp @@ -22,12 +22,8 @@ namespace psemek::gfx gl::GenFramebuffers(1, &id_); } - framebuffer::framebuffer(GLuint id) - : id_(id) - {} - framebuffer::framebuffer(framebuffer && other) - : id_(other.id_) + : id_{other.id_} { other.id_ = 0; } @@ -36,20 +32,19 @@ namespace psemek::gfx { if (this == &other) return *this; - gl::DeleteFramebuffers(1, &id_); - id_ = other.id_; - other.id_ = 0; + reset(); + std::swap(id_, other.id_); return *this; } framebuffer::~framebuffer() { - gl::DeleteFramebuffers(1, &id_); + reset(); } framebuffer framebuffer::null() { - return framebuffer{0}; + return framebuffer(nullptr); } void framebuffer::bind() const @@ -57,6 +52,13 @@ namespace psemek::gfx gl::BindFramebuffer(gl::DRAW_FRAMEBUFFER, id_); } + void framebuffer::reset() + { + if (id_ != 0) + gl::DeleteFramebuffers(1, &id_); + id_ = 0; + } + void framebuffer::color(texture_1d const & tex, int attachment) { bind(); @@ -110,4 +112,8 @@ namespace psemek::gfx throw std::runtime_error("Framebuffer incomplete: " + framebuffer_status_string(s)); } + framebuffer::framebuffer(std::nullptr_t) + : id_{0} + {} + } diff --git a/libs/gfx/source/renderbuffer.cpp b/libs/gfx/source/renderbuffer.cpp index 9d76edd3..16e96539 100644 --- a/libs/gfx/source/renderbuffer.cpp +++ b/libs/gfx/source/renderbuffer.cpp @@ -1,5 +1,7 @@ #include +#include + namespace psemek::gfx { @@ -9,8 +11,8 @@ namespace psemek::gfx } renderbuffer::renderbuffer(renderbuffer && other) + : id_{other.id_} { - id_ = other.id_; other.id_ = 0; } @@ -18,20 +20,19 @@ namespace psemek::gfx { if (this == &other) return *this; - gl::DeleteRenderbuffers(1, &id_); - id_ = other.id_; - other.id_ = 0; + reset(); + std::swap(id_, other.id_); return *this; } renderbuffer::~renderbuffer() { - gl::DeleteRenderbuffers(1, &id_); + reset(); } renderbuffer renderbuffer::null() { - return renderbuffer(0); + return renderbuffer(nullptr); } void renderbuffer::bind() const @@ -39,14 +40,21 @@ namespace psemek::gfx gl::BindRenderbuffer(gl::RENDERBUFFER, id_); } + void renderbuffer::reset() + { + if (id_ != 0) + gl::DeleteRenderbuffers(1, &id_); + id_ = 0; + } + void renderbuffer::storage(GLenum internal_format, GLsizei width, GLsizei height) { bind(); gl::RenderbufferStorage(gl::RENDERBUFFER, internal_format, width, height); } - renderbuffer::renderbuffer(GLuint id) - : id_(id) + renderbuffer::renderbuffer(std::nullptr_t) + : id_{0} {} } diff --git a/libs/gfx/source/texture.cpp b/libs/gfx/source/texture.cpp index 5a634997..ba9d5a23 100644 --- a/libs/gfx/source/texture.cpp +++ b/libs/gfx/source/texture.cpp @@ -1,23 +1,34 @@ #include #include -namespace psemek::gfx::detail +namespace psemek::gfx { - static std::optional get_max_anisotropy() + template struct basic_texture<1, gl::TEXTURE_1D>; + template struct basic_texture<2, gl::TEXTURE_1D_ARRAY>; + template struct basic_texture<2, gl::TEXTURE_2D>; + template struct basic_texture<3, gl::TEXTURE_2D_ARRAY>; + template struct basic_texture<3, gl::TEXTURE_3D>; + + namespace detail { - if (!gl::exts::var_EXT_texture_filter_anisotropic) return std::nullopt; - float level; - gl::GetFloatv(gl::MAX_TEXTURE_MAX_ANISOTROPY_EXT, &level); - return level; - } + static std::optional get_max_anisotropy() + { + if (!gl::exts::var_EXT_texture_filter_anisotropic) return std::nullopt; - std::optional max_anisotropy() - { - static std::optional level = get_max_anisotropy(); + float level; + gl::GetFloatv(gl::MAX_TEXTURE_MAX_ANISOTROPY_EXT, &level); + return level; + } + + std::optional max_anisotropy() + { + static std::optional level = get_max_anisotropy(); + + return level; + } - return level; } }