diff --git a/libs/gfx/include/psemek/gfx/texture.hpp b/libs/gfx/include/psemek/gfx/texture.hpp index 3d5179c8..51f354d5 100644 --- a/libs/gfx/include/psemek/gfx/texture.hpp +++ b/libs/gfx/include/psemek/gfx/texture.hpp @@ -66,7 +66,7 @@ namespace psemek::gfx void repeat(); void clamp(); - private: + protected: GLuint id_; geom::vector size_; @@ -85,6 +85,64 @@ namespace psemek::gfx extern template struct basic_texture<3, gl::TEXTURE_2D_ARRAY>; extern template struct basic_texture<3, gl::TEXTURE_3D>; + extern template struct basic_texture<2, gl::TEXTURE_CUBE_MAP>; + + struct texture_cubemap + : basic_texture<2, gl::TEXTURE_CUBE_MAP> + { + texture_cubemap() = default; + texture_cubemap(texture_cubemap &&) = default; + texture_cubemap & operator = (texture_cubemap &&) = default; + ~texture_cubemap() = default; + + texture_cubemap(texture_cubemap const &) = delete; + texture_cubemap & operator = (texture_cubemap const &) = delete; + + static texture_cubemap null() + { + return basic_texture<2, gl::TEXTURE_CUBE_MAP>::null(); + } + + static GLenum face_to_gl(int f); + + void load(int f, GLint internal_format, geom::vector const & size, GLenum format, GLenum type, const void * data); + + template + void load(int f, geom::vector const & size, Pixel const * data = nullptr) + { + using traits = pixel_traits; + load(f, traits::internal_format, size, traits::format, traits::type, data); + } + + template + void load(int f, util::array const & p) + { + geom::vector size; + for (std::size_t i = 0; i < 2; ++i) size[i] = p.dim(i); + load(f, size, p.data()); + } + + void pixels(int f, GLenum format, GLenum type, void * data) const; + + template + Pixmap pixels(int f) const + { + using traits = pixel_traits; + + std::array size; + for (std::size_t i = 0; i < 2; ++i) size[i] = size_[i]; + + Pixmap p(size); + pixels(f, traits::format, traits::type, p.data()); + return p; + } + + private: + texture_cubemap(basic_texture<2, gl::TEXTURE_CUBE_MAP> t) + : basic_texture<2, gl::TEXTURE_CUBE_MAP>(std::move(t)) + {} + }; + namespace detail { std::optional max_anisotropy(); diff --git a/libs/gfx/source/texture.cpp b/libs/gfx/source/texture.cpp index ba9d5a23..d5e73cc7 100644 --- a/libs/gfx/source/texture.cpp +++ b/libs/gfx/source/texture.cpp @@ -10,6 +10,8 @@ namespace psemek::gfx template struct basic_texture<3, gl::TEXTURE_2D_ARRAY>; template struct basic_texture<3, gl::TEXTURE_3D>; + template struct basic_texture<2, gl::TEXTURE_CUBE_MAP>; + namespace detail { @@ -31,4 +33,22 @@ namespace psemek::gfx } + void texture_cubemap::load(int f, GLint internal_format, geom::vector const & size, GLenum format, GLenum type, const void * data) + { + bind(); + gl::TexImage2D(face_to_gl(f), 0, internal_format, size[0], size[1], 0, format, type, data); + size_ = size; + } + + void texture_cubemap::pixels(int f, GLenum format, GLenum type, void * data) const + { + bind(); + gl::GetTexImage(face_to_gl(f), 0, format, type, data); + } + + GLenum texture_cubemap::face_to_gl(int f) + { + return gl::TEXTURE_CUBE_MAP_POSITIVE_X + f; + } + }