diff --git a/libs/gfx/include/psemek/gfx/texture.hpp b/libs/gfx/include/psemek/gfx/texture.hpp index be7da838..3149ecdd 100644 --- a/libs/gfx/include/psemek/gfx/texture.hpp +++ b/libs/gfx/include/psemek/gfx/texture.hpp @@ -159,6 +159,49 @@ namespace psemek::gfx {} }; + struct texture_2d_multisample + { + texture_2d_multisample(); + texture_2d_multisample(texture_2d_multisample &&); + texture_2d_multisample & operator = (texture_2d_multisample &&); + ~texture_2d_multisample(); + + texture_2d_multisample(texture_2d_multisample const &) = delete; + texture_2d_multisample & operator = (texture_2d_multisample const &) = delete; + + static texture_2d_multisample null(); + + static constexpr GLenum target = gl::TEXTURE_2D_MULTISAMPLE; + + GLuint id() const { return id_; } + + explicit operator bool() const { return id() != 0; } + + void reset(); + + void bind() const; + void bind(int texture_unit) const; + + geom::vector size() const { return size_; } + + std::size_t width() const { return size_[0]; } + std::size_t height() const { return size_[1]; } + + int samples() const { return samples_; } + + void load(GLint internal_format, geom::vector const & size, int samples, bool fixed_sample_locations = true); + + template + void load(geom::vector const & size, int samples, bool fixed_sample_locations = true); + + protected: + GLuint id_ = 0; + geom::vector size_ = {0, 0}; + int samples_ = 0; + + explicit texture_2d_multisample(std::nullptr_t); + }; + struct buffer_texture { buffer_texture(); @@ -467,6 +510,12 @@ namespace psemek::gfx basic_texture::basic_texture(std::nullptr_t) {} + template + void texture_2d_multisample::load(geom::vector const & size, int samples, bool fixed_sample_locations) + { + load(pixel_traits::internal_format, size, samples, fixed_sample_locations); + } + inline buffer_texture::buffer_texture() { gl::GenTextures(1, &id_); diff --git a/libs/gfx/source/texture.cpp b/libs/gfx/source/texture.cpp index 2b66172e..a33ceb7c 100644 --- a/libs/gfx/source/texture.cpp +++ b/libs/gfx/source/texture.cpp @@ -52,4 +52,72 @@ namespace psemek::gfx return gl::TEXTURE_CUBE_MAP_POSITIVE_X + f; } + texture_2d_multisample::texture_2d_multisample() + { + gl::GenTextures(1, &id_); + } + + texture_2d_multisample::texture_2d_multisample(texture_2d_multisample && other) + : id_(other.id_) + , size_(other.size_) + , samples_(other.samples_) + { + other.id_ = 0; + other.size_ = {0, 0}; + other.samples_ = 0; + } + + texture_2d_multisample & texture_2d_multisample::operator = (texture_2d_multisample && other) + { + if (this != &other) + { + reset(); + id_ = other.id_; + size_ = other.size_; + samples_ = other.samples_; + other.id_ = 0; + other.size_ = {0, 0}; + other.samples_ = 0; + } + + return *this; + } + + texture_2d_multisample::~texture_2d_multisample() + { + reset(); + } + + texture_2d_multisample texture_2d_multisample::null() + { + return texture_2d_multisample(nullptr); + } + + void texture_2d_multisample::reset() + { + gl::DeleteTextures(1, &id_); + } + + void texture_2d_multisample::bind() const + { + gl::BindTexture(target, id_); + } + + void texture_2d_multisample::bind(int texture_unit) const + { + gl::ActiveTexture(gl::TEXTURE0 + texture_unit); + bind(); + } + + void texture_2d_multisample::load(GLint internal_format, geom::vector const & size, int samples, bool fixed_sample_locations) + { + bind(); + gl::TexImage2DMultisample(target, samples, internal_format, size[0], size[1], fixed_sample_locations ? gl::TRUE : gl::FALSE); + size_ = size; + samples_ = samples; + } + + texture_2d_multisample::texture_2d_multisample(std::nullptr_t) + {} + }