/* * Copyright (C) 2023 Christopher J. Howard * * This file is part of Antkeeper source code. * * Antkeeper source code is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Antkeeper source code is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Antkeeper source code. If not, see . */ #ifndef ANTKEEPER_GL_IMAGE_HPP #define ANTKEEPER_GL_IMAGE_HPP #include #include #include #include #include #include #include namespace gl { /** * */ class image { public: /// Destructs an image. virtual ~image() = 0; image(const image&) = delete; image(image&&) = delete; image& operator=(const image&) = delete; image& operator=(image&&) = delete; /** * Reads pixel data from the image. * * @param mip_level Level-of-detail number. Level `0` is the base image level. Level `n` is the nth mipmap reduction image. * @param offset_x Texel offset in the X-direction. * @param offset_y Texel offset in the Y-direction. * @param offset_z Texel offset in the Z-direction. * @param width Width of the subimage. * @param height Height of the subimage. * @param depth Depth of the subimage. * @param format Format of the image data. * @param data Buffer into which image data will be read. * * @except std::out_of_range Image read operation mip level out of range. * @except std::invalid_argument Image read operation used unsupported format. */ void read ( std::uint32_t mip_level, std::uint32_t offset_x, std::uint32_t offset_y, std::uint32_t offset_z, std::uint32_t width, std::uint32_t height, std::uint32_t depth, gl::format format, std::span data ) const; /** * Writes pixel data to the image. * * @param mip_level Level-of-detail number. Level `0` is the base image level. Level `n` is the nth mipmap reduction image. * @param offset_x Texel offset in the X-direction. * @param offset_y Texel offset in the Y-direction. * @param offset_z Texel offset in the Z-direction. * @param width Width of the subimage. * @param height Height of the subimage. * @param depth Depth of the subimage. * @param format Format of the image data. * @param data Image data to write. * * @except std::out_of_range Image write operation mip level out of range. * @except std::invalid_argument Image write operation used unsupported format. * @except std::out_of_range Image write operation exceeded image bounds. */ void write ( std::uint32_t mip_level, std::uint32_t offset_x, std::uint32_t offset_y, std::uint32_t offset_z, std::uint32_t width, std::uint32_t height, std::uint32_t depth, gl::format format, std::span data ); /** * Copies pixel data from this image into another the image. * * @param src_mip_level Source image level-of-detail number. Level `0` is the base image level. Level `n` is the nth mipmap reduction image. * @param src_x Source image texel offset in the X-direction. * @param src_y Source image texel offset in the Y-direction. * @param src_z Source image texel offset in the Z-direction. * @param dst_image Destination image. * @param dst_mip_level Destination image level-of-detail number. Level `0` is the base image level. Level `n` is the nth mipmap reduction image. * @param dst_x Destination image texel offset in the X-direction. * @param dst_y Destination image texel offset in the Y-direction. * @param dst_z Destination image texel offset in the Z-direction. * @param width Width of the subimage to copy. * @param height Height of the subimage to copy. * @param depth Depth of the subimage to copy. */ void copy ( std::uint32_t src_mip_level, std::uint32_t src_x, std::uint32_t src_y, std::uint32_t src_z, image& dst_image, std::uint32_t dst_mip_level, std::uint32_t dst_x, std::uint32_t dst_y, std::uint32_t dst_z, std::uint32_t width, std::uint32_t height, std::uint32_t depth ) const; /** * Generates mip subimages. */ void generate_mipmaps(); /// Returns the dimensionality of the image. [[nodiscard]] inline constexpr std::uint8_t get_dimensionality() const noexcept { return m_dimensionality; } /// Returns `true` if the image is 1D, `false` otherwise. [[nodiscard]] inline constexpr bool is_1d() const noexcept { return m_dimensionality == 1; } /// Returns `true` if the image is 2D, `false` otherwise. [[nodiscard]] inline constexpr bool is_2d() const noexcept { return m_dimensionality == 2; } /// Returns `true` if the image is 3D, `false` otherwise. [[nodiscard]] inline constexpr bool is_3d() const noexcept { return m_dimensionality == 3; } /// Returns the format and type of the texel blocks contained in the image. [[nodiscard]] inline constexpr format get_format() const noexcept { return m_format; } /// Returns the dimensions of the image. [[nodiscard]] inline constexpr const std::array& get_dimensions() const noexcept { return m_dimensions; } /// Returns the number of levels of detail available for minified sampling of the image. [[nodiscard]] inline constexpr std::uint32_t get_mip_levels() const noexcept { return m_mip_levels; } /// Returns the number of layers in the image. [[nodiscard]] inline constexpr std::uint32_t get_array_layers() const noexcept { return m_array_layers; } /// Returns the image flags. [[nodiscard]] inline constexpr std::uint8_t get_flags() const noexcept { return m_flags; } /// Returns `true` if the image is cube map compatible, `false` otherwise. [[nodiscard]] inline constexpr bool is_cube_compatible() const noexcept { return m_flags & std::to_underlying(image_flag::cube_compatible); } protected: /** * Constructs an image. * * @param dimensionality Image dimensionality, on `[1, 3]`. * @param format Format and type of the texel blocks that will be contained in the image. * @param width Width of the image. * @param height Height of the image. * @param depth Depth of the image. * @param mip_levels Number of levels of detail available for minified sampling of the image. * @param array_layers Number of layers in the image. * @param flags Image flags. * * @except std::invalid_argument Image constructed with unsupported format. * @except std::invalid_argument Image dimensions must be nonzero. * @except std::invalid_argument Image mip levels must be nonzero. * @except std::out_of_range Image mip levels exceed `1 + log2(max(width, height, depth))`. * @except std::invalid_argument Image array layers must be nonzero. * @except std::invalid_argument 1D image must have a height and depth of `1`. * @except std::invalid_argument 2D image must have a depth of `1`. * @except std::invalid_argument 3D image arrays not supported. * @except std::invalid_argument Cube compatible image must be 2D. * @except std::invalid_argument Cube compatible image width and height must be equal. * @except std::invalid_argument Cube compatible image array layers must be a multiple of 6. */ image ( std::uint8_t dimensionality, gl::format format, std::uint32_t width, std::uint32_t height, std::uint32_t depth, std::uint32_t mip_levels, std::uint32_t array_layers, std::uint32_t flags ); private: unsigned int m_gl_texture_target{0}; unsigned int m_gl_texture_name{0}; std::uint8_t m_dimensionality{0}; format m_format{format::undefined}; std::array m_dimensions{0, 0, 0}; std::uint32_t m_mip_levels{0}; std::uint32_t m_array_layers{0}; std::uint8_t m_flags{0}; friend class image_view; }; /** * 1D image. */ class image_1d: public image { public: /// @copydoc image::image image_1d ( gl::format format, std::uint32_t width, std::uint32_t mip_levels = 1, std::uint32_t array_layers = 1, std::uint32_t flags = 0 ); }; /** * 2D image. */ class image_2d: public image { public: /// @copydoc image::image image_2d ( gl::format format, std::uint32_t width, std::uint32_t height, std::uint32_t mip_levels = 1, std::uint32_t array_layers = 1, std::uint32_t flags = 0 ); }; /** * 3D image. */ class image_3d: public image { public: /// @copydoc image::image image_3d ( gl::format format, std::uint32_t width, std::uint32_t height, std::uint32_t depth, std::uint32_t mip_levels = 1, std::uint32_t flags = 0 ); }; /** * Cube-compatible 2D image. */ class image_cube: public image_2d { public: /// @copydoc image_2d::image_2d image_cube ( gl::format format, std::uint32_t width, std::uint32_t mip_levels = 1, std::uint32_t array_layers = 6 ); }; } // namespace gl #endif // ANTKEEPER_GL_IMAGE_HPP