💿🐜 Antkeeper source code https://antkeeper.com
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

324 lines
9.0 KiB

/*
* 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 <http://www.gnu.org/licenses/>.
*/
#ifndef ANTKEEPER_GL_IMAGE_HPP
#define ANTKEEPER_GL_IMAGE_HPP
#include <engine/gl/format.hpp>
#include <engine/gl/image-flag.hpp>
#include <array>
#include <cstddef>
#include <cstdint>
#include <limits>
#include <span>
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<std::byte> 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<const std::byte> 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<std::uint32_t, 3>& 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<std::uint32_t, 3> 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