@ -0,0 +1,41 @@ | |||
/* | |||
* Copyright (C) 2021 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/>. | |||
*/ | |||
#include "gl/texture-1d.hpp" | |||
namespace gl { | |||
texture_1d::texture_1d(std::uint16_t width, gl::pixel_type type, gl::pixel_format format, gl::color_space color_space, const void* data): | |||
texture(width, type, format, color_space, data) | |||
{} | |||
texture_1d::~texture_1d() | |||
{} | |||
void texture_1d::resize(std::uint16_t width, gl::pixel_type type, gl::pixel_format format, gl::color_space color_space, const void* data) | |||
{ | |||
texture::resize(width, type, format, color_space, data); | |||
} | |||
void texture_1d::set_wrapping(gl::texture_wrapping wrap_s) | |||
{ | |||
texture::set_wrapping(wrap_s); | |||
} | |||
} // namespace gl |
@ -0,0 +1,48 @@ | |||
/* | |||
* Copyright (C) 2021 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_TEXTURE_1D_HPP | |||
#define ANTKEEPER_GL_TEXTURE_1D_HPP | |||
#include "gl/texture.hpp" | |||
namespace gl { | |||
/** | |||
* A 1D texture which can be uploaded to shaders via shader inputs. | |||
*/ | |||
class texture_1d: public texture | |||
{ | |||
public: | |||
/// @copydoc texture::texture(std::uint16_t, gl::pixel_type, gl::pixel_format, gl::color_space, const void*) | |||
texture_1d(std::uint16_t width, gl::pixel_type type = gl::pixel_type::uint_8, gl::pixel_format format = gl::pixel_format::rgba, gl::color_space color_space = gl::color_space::linear, const void* data = nullptr); | |||
/// Destructs a 1D texture. | |||
virtual ~texture_1d(); | |||
/// @copydoc texture::resize(std::uint16_t, gl::pixel_type, gl::pixel_format, gl::color_space, const void*) | |||
virtual void resize(std::uint16_t width, gl::pixel_type type, gl::pixel_format format, gl::color_space color_space, const void* data); | |||
/// @copydoc texture::set_wrapping(gl::texture_wrapping) | |||
virtual void set_wrapping(gl::texture_wrapping wrap_s); | |||
}; | |||
} // namespace gl | |||
#endif // ANTKEEPER_GL_TEXTURE_1D_HPP |
@ -0,0 +1,41 @@ | |||
/* | |||
* Copyright (C) 2021 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/>. | |||
*/ | |||
#include "gl/texture-3d.hpp" | |||
namespace gl { | |||
texture_3d::texture_3d(std::uint16_t width, std::uint16_t height, std::uint16_t depth, gl::pixel_type type, gl::pixel_format format, gl::color_space color_space, const void* data): | |||
texture(width, height, depth, type, format, color_space, data) | |||
{} | |||
texture_3d::~texture_3d() | |||
{} | |||
void texture_3d::resize(std::uint16_t width, std::uint16_t height, std::uint16_t depth, gl::pixel_type type, gl::pixel_format format, gl::color_space color_space, const void* data) | |||
{ | |||
texture::resize(width, height, depth, type, format, color_space, data); | |||
} | |||
void texture_3d::set_wrapping(gl::texture_wrapping wrap_s, texture_wrapping wrap_t, texture_wrapping wrap_r) | |||
{ | |||
texture::set_wrapping(wrap_s, wrap_t, wrap_r); | |||
} | |||
} // namespace gl |
@ -0,0 +1,48 @@ | |||
/* | |||
* Copyright (C) 2021 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_TEXTURE_3D_HPP | |||
#define ANTKEEPER_GL_TEXTURE_3D_HPP | |||
#include "gl/texture.hpp" | |||
namespace gl { | |||
/** | |||
* A 3D texture which can be uploaded to shaders via shader inputs. | |||
*/ | |||
class texture_3d: public texture | |||
{ | |||
public: | |||
/// @copydoc texture::texture(std::uint16_t, std::uint16_t, std::uint16_t, gl::pixel_type, gl::pixel_format, gl::color_space, const void*) | |||
texture_3d(std::uint16_t width, std::uint16_t height, std::uint16_t depth, gl::pixel_type type = gl::pixel_type::uint_8, gl::pixel_format format = gl::pixel_format::rgba, gl::color_space color_space = gl::color_space::linear, const void* data = nullptr); | |||
/// Destructs a 3D texture. | |||
virtual ~texture_3d(); | |||
/// @copydoc texture::resize(std::uint16_t, std::uint16_t, std::uint16_t, gl::pixel_type, gl::pixel_format, gl::color_space, const void*) | |||
virtual void resize(std::uint16_t width, std::uint16_t height, std::uint16_t depth, gl::pixel_type type, gl::pixel_format format, gl::color_space color_space, const void* data); | |||
/// @copydoc texture::set_wrapping(gl::texture_wrapping, gl::texture_wrapping, gl::texture_wrapping) | |||
virtual void set_wrapping(gl::texture_wrapping wrap_s, texture_wrapping wrap_t, texture_wrapping wrap_r); | |||
}; | |||
} // namespace gl | |||
#endif // ANTKEEPER_GL_TEXTURE_3D_HPP |
@ -0,0 +1,267 @@ | |||
/* | |||
* Copyright (C) 2021 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/>. | |||
*/ | |||
#include "gl/texture.hpp" | |||
#include "gl/texture-wrapping.hpp" | |||
#include "gl/texture-filter.hpp" | |||
#include <glad/glad.h> | |||
#include <algorithm> | |||
namespace gl { | |||
static constexpr GLenum pixel_format_lut[] = | |||
{ | |||
GL_DEPTH_COMPONENT, | |||
GL_DEPTH_STENCIL, | |||
GL_RED, | |||
GL_RG, | |||
GL_RGB, | |||
GL_BGR, | |||
GL_RGBA, | |||
GL_BGRA | |||
}; | |||
static constexpr GLenum pixel_type_lut[] = | |||
{ | |||
GL_BYTE, | |||
GL_UNSIGNED_BYTE, | |||
GL_SHORT, | |||
GL_UNSIGNED_SHORT, | |||
GL_INT, | |||
GL_UNSIGNED_INT, | |||
GL_HALF_FLOAT, | |||
GL_FLOAT | |||
}; | |||
static constexpr GLenum linear_internal_format_lut[][8] = | |||
{ | |||
{GL_NONE, GL_NONE, GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT32, GL_DEPTH_COMPONENT32, GL_NONE, GL_DEPTH_COMPONENT32F}, | |||
// Note: GL_DEPTH32F_STENCIL8 is actually a 64-bit format, 32 depth bits, 8 stencil bits, and 24 alignment bits. | |||
{GL_NONE, GL_NONE, GL_NONE, GL_NONE, GL_DEPTH24_STENCIL8, GL_DEPTH24_STENCIL8, GL_NONE, GL_DEPTH32F_STENCIL8}, | |||
{GL_R8, GL_R8, GL_R16, GL_R16, GL_R32F, GL_R32F, GL_R16F, GL_R32F}, | |||
{GL_RG8, GL_RG8, GL_RG16, GL_RG16, GL_RG32F, GL_RG32F, GL_RG16F, GL_RG32F}, | |||
{GL_RGB8, GL_RGB8, GL_RGB16, GL_RGB16, GL_RGB32F, GL_RGB32F, GL_RGB16F, GL_RGB32F}, | |||
{GL_RGB8, GL_RGB8, GL_RGB16, GL_RGB16, GL_RGB32F, GL_RGB32F, GL_RGB16F, GL_RGB32F}, | |||
{GL_RGBA8, GL_RGBA8, GL_RGBA16, GL_RGBA16, GL_RGBA32F, GL_RGBA32F, GL_RGBA16F, GL_RGBA32F}, | |||
{GL_RGBA8, GL_RGBA8, GL_RGBA16, GL_RGBA16, GL_RGBA32F, GL_RGBA32F, GL_RGBA16F, GL_RGBA32F} | |||
}; | |||
static constexpr GLenum srgb_internal_format_lut[][8] = | |||
{ | |||
{GL_NONE, GL_NONE, GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT32, GL_DEPTH_COMPONENT32, GL_NONE, GL_DEPTH_COMPONENT32F}, | |||
{GL_NONE, GL_NONE, GL_NONE, GL_NONE, GL_DEPTH24_STENCIL8, GL_DEPTH24_STENCIL8, GL_NONE, GL_DEPTH32F_STENCIL8}, | |||
{GL_SRGB8, GL_SRGB8, GL_R16, GL_R16, GL_R32F, GL_R32F, GL_R16F, GL_R32F}, | |||
{GL_SRGB8, GL_SRGB8, GL_RG16, GL_RG16, GL_RG32F, GL_RG32F, GL_RG16F, GL_RG32F}, | |||
{GL_SRGB8, GL_SRGB8, GL_RGB16, GL_RGB16, GL_RGB32F, GL_RGB32F, GL_RGB16F, GL_RGB32F}, | |||
{GL_SRGB8, GL_SRGB8, GL_RGB16, GL_RGB16, GL_RGB32F, GL_RGB32F, GL_RGB16F, GL_RGB32F}, | |||
{GL_SRGB8_ALPHA8, GL_SRGB8_ALPHA8, GL_RGBA16, GL_RGBA16, GL_RGBA32F, GL_RGBA32F, GL_RGBA16F, GL_RGBA32F}, | |||
{GL_SRGB8_ALPHA8, GL_SRGB8_ALPHA8, GL_RGBA16, GL_RGBA16, GL_RGBA32F, GL_RGBA32F, GL_RGBA16F, GL_RGBA32F} | |||
}; | |||
static constexpr GLint swizzle_mask_lut[][4] = | |||
{ | |||
{GL_RED, GL_RED, GL_RED, GL_ONE}, | |||
{GL_RED, GL_GREEN, GL_ZERO, GL_ONE}, | |||
{GL_RED, GL_RED, GL_RED, GL_ONE}, | |||
{GL_RED, GL_RED, GL_RED, GL_GREEN}, | |||
{GL_RED, GL_GREEN, GL_BLUE, GL_ONE}, | |||
{GL_RED, GL_GREEN, GL_BLUE, GL_ONE}, | |||
{GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA}, | |||
{GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA} | |||
}; | |||
static constexpr GLenum wrapping_lut[] = | |||
{ | |||
GL_CLAMP_TO_BORDER, | |||
GL_CLAMP_TO_EDGE, | |||
GL_REPEAT, | |||
GL_MIRRORED_REPEAT | |||
}; | |||
static constexpr GLenum min_filter_lut[] = | |||
{ | |||
GL_NEAREST, | |||
GL_LINEAR, | |||
GL_NEAREST_MIPMAP_NEAREST, | |||
GL_LINEAR_MIPMAP_NEAREST, | |||
GL_NEAREST_MIPMAP_LINEAR, | |||
GL_LINEAR_MIPMAP_LINEAR | |||
}; | |||
static constexpr GLenum mag_filter_lut[] = | |||
{ | |||
GL_NEAREST, | |||
GL_LINEAR | |||
}; | |||
texture::texture(std::uint16_t width, std::uint16_t height, std::uint16_t depth, gl::pixel_type type, gl::pixel_format format, gl::color_space color_space, const void* data): | |||
gl_texture_target((depth) ? GL_TEXTURE_3D : (height) ? GL_TEXTURE_2D : GL_TEXTURE_1D), | |||
gl_texture_id(0), | |||
dimensions({0, 0, 0}), | |||
wrapping({texture_wrapping::repeat, texture_wrapping::repeat, texture_wrapping::repeat}), | |||
filters({texture_min_filter::linear_mipmap_linear, texture_mag_filter::linear}), | |||
max_anisotropy(0.0f) | |||
{ | |||
glGenTextures(1, &gl_texture_id); | |||
resize(width, height, depth, type, format, color_space, data); | |||
set_wrapping(wrapping[0], wrapping[1], wrapping[2]); | |||
set_filters(std::get<0>(filters), std::get<1>(filters)); | |||
set_max_anisotropy(max_anisotropy); | |||
} | |||
texture::texture(std::uint16_t width, std::uint16_t height, gl::pixel_type type, gl::pixel_format format, gl::color_space color_space, const void* data): | |||
texture(width, height, 0, type, format, color_space, data) | |||
{} | |||
texture::texture(std::uint16_t width, gl::pixel_type type, gl::pixel_format format, gl::color_space color_space, const void* data): | |||
texture(width, 0, 0, type, format, color_space, data) | |||
{} | |||
texture::~texture() | |||
{ | |||
glDeleteTextures(1, &gl_texture_id); | |||
} | |||
void texture::set_filters(texture_min_filter min_filter, texture_mag_filter mag_filter) | |||
{ | |||
filters = {min_filter, mag_filter}; | |||
GLenum gl_min_filter = min_filter_lut[static_cast<std::size_t>(min_filter)]; | |||
GLenum gl_mag_filter = mag_filter_lut[static_cast<std::size_t>(mag_filter)]; | |||
glBindTexture(gl_texture_target, gl_texture_id); | |||
glTexParameteri(gl_texture_target, GL_TEXTURE_MIN_FILTER, gl_min_filter); | |||
glTexParameteri(gl_texture_target, GL_TEXTURE_MAG_FILTER, gl_mag_filter); | |||
} | |||
void texture::set_max_anisotropy(float anisotropy) | |||
{ | |||
max_anisotropy = std::max<float>(0.0f, std::min<float>(1.0f, anisotropy)); | |||
// Get the maximum supported anisotropy value | |||
float gl_max_texture_max_anisotropy; | |||
glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &gl_max_texture_max_anisotropy); | |||
// Lerp between 1.0 and GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT | |||
float gl_max_anisotropy = 1.0f + max_anisotropy * (gl_max_texture_max_anisotropy - 1.0f); | |||
glBindTexture(gl_texture_target, gl_texture_id); | |||
glTexParameterf(gl_texture_target, GL_TEXTURE_MAX_ANISOTROPY_EXT, gl_max_anisotropy); | |||
} | |||
void texture::set_wrapping(gl::texture_wrapping wrap_s, gl::texture_wrapping wrap_t, gl::texture_wrapping wrap_r) | |||
{ | |||
wrapping = {wrap_s, wrap_t, wrap_r}; | |||
GLenum gl_wrap_s = wrapping_lut[static_cast<std::size_t>(wrap_s)]; | |||
GLenum gl_wrap_t = wrapping_lut[static_cast<std::size_t>(wrap_t)]; | |||
GLenum gl_wrap_r = wrapping_lut[static_cast<std::size_t>(wrap_r)]; | |||
glBindTexture(gl_texture_target, gl_texture_id); | |||
glTexParameteri(gl_texture_target, GL_TEXTURE_WRAP_S, gl_wrap_s); | |||
glTexParameteri(gl_texture_target, GL_TEXTURE_WRAP_T, gl_wrap_t); | |||
glTexParameteri(gl_texture_target, GL_TEXTURE_WRAP_R, gl_wrap_r); | |||
} | |||
void texture::set_wrapping(gl::texture_wrapping wrap_s, gl::texture_wrapping wrap_t) | |||
{ | |||
std::get<0>(wrapping) = wrap_s; | |||
std::get<1>(wrapping) = wrap_t; | |||
GLenum gl_wrap_s = wrapping_lut[static_cast<std::size_t>(wrap_s)]; | |||
GLenum gl_wrap_t = wrapping_lut[static_cast<std::size_t>(wrap_t)]; | |||
glBindTexture(gl_texture_target, gl_texture_id); | |||
glTexParameteri(gl_texture_target, GL_TEXTURE_WRAP_S, gl_wrap_s); | |||
glTexParameteri(gl_texture_target, GL_TEXTURE_WRAP_T, gl_wrap_t); | |||
} | |||
void texture::set_wrapping(gl::texture_wrapping wrap_s) | |||
{ | |||
std::get<0>(wrapping) = wrap_s; | |||
GLenum gl_wrap_s = wrapping_lut[static_cast<std::size_t>(wrap_s)]; | |||
glBindTexture(gl_texture_target, gl_texture_id); | |||
glTexParameteri(gl_texture_target, GL_TEXTURE_WRAP_S, gl_wrap_s); | |||
} | |||
void texture::resize(std::uint16_t width, std::uint16_t height, std::uint16_t depth, gl::pixel_type type, gl::pixel_format format, gl::color_space color_space, const void* data) | |||
{ | |||
dimensions = {width, height, depth}; | |||
pixel_type = type; | |||
pixel_format = format; | |||
this->color_space = color_space; | |||
GLenum gl_internal_format; | |||
if (color_space == gl::color_space::srgb) | |||
{ | |||
gl_internal_format = srgb_internal_format_lut[static_cast<std::size_t>(format)][static_cast<std::size_t>(type)]; | |||
} | |||
else | |||
{ | |||
gl_internal_format = linear_internal_format_lut[static_cast<std::size_t>(format)][static_cast<std::size_t>(type)]; | |||
} | |||
GLenum gl_format = pixel_format_lut[static_cast<std::size_t>(format)]; | |||
const GLint* gl_swizzle_mask = swizzle_mask_lut[static_cast<std::size_t>(format)]; | |||
GLenum gl_type = pixel_type_lut[static_cast<std::size_t>(type)]; | |||
// Special cases for depth + stencil pixel formats | |||
if (gl_internal_format == GL_DEPTH24_STENCIL8) | |||
gl_type = GL_UNSIGNED_INT_24_8; | |||
else if (gl_internal_format == GL_DEPTH32F_STENCIL8) | |||
gl_type = GL_FLOAT_32_UNSIGNED_INT_24_8_REV; | |||
glPixelStorei(GL_PACK_ALIGNMENT, 1); | |||
glPixelStorei(GL_UNPACK_ALIGNMENT, 1); | |||
glBindTexture(gl_texture_target, gl_texture_id); | |||
if (depth) | |||
glTexImage3D(gl_texture_target, 0, gl_internal_format, width, height, depth, 0, gl_format, gl_type, data); | |||
else if (height) | |||
glTexImage2D(gl_texture_target, 0, gl_internal_format, width, height, 0, gl_format, gl_type, data); | |||
else if (width) | |||
glTexImage1D(gl_texture_target, 0, gl_internal_format, width, 0, gl_format, gl_type, data); | |||
glGenerateMipmap(gl_texture_target); | |||
glTexParameteriv(gl_texture_target, GL_TEXTURE_SWIZZLE_RGBA, gl_swizzle_mask); | |||
/// TODO: remove this | |||
if (format == pixel_format::d) | |||
{ | |||
glTexParameteri(gl_texture_target, GL_TEXTURE_COMPARE_FUNC, GL_LESS); | |||
glTexParameteri(gl_texture_target, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE); | |||
} | |||
} | |||
void texture::resize(std::uint16_t width, std::uint16_t height, gl::pixel_type type, gl::pixel_format format, gl::color_space color_space, const void* data) | |||
{ | |||
resize(width, height, 0, type, format, color_space, data); | |||
} | |||
void texture::resize(std::uint16_t width, gl::pixel_type type, gl::pixel_format format, gl::color_space color_space, const void* data) | |||
{ | |||
resize(width, 0, 0, type, format, color_space, data); | |||
} | |||
} // namespace gl |
@ -0,0 +1,212 @@ | |||
/* | |||
* Copyright (C) 2021 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_TEXTURE_HPP | |||
#define ANTKEEPER_GL_TEXTURE_HPP | |||
#include "gl/color-space.hpp" | |||
#include "gl/pixel-format.hpp" | |||
#include "gl/pixel-type.hpp" | |||
#include "gl/texture-filter.hpp" | |||
#include "gl/texture-wrapping.hpp" | |||
#include <array> | |||
#include <cstdint> | |||
#include <tuple> | |||
namespace gl { | |||
class framebuffer; | |||
class shader_input; | |||
/** | |||
* Abstract base class for 1D, 2D, 3D, and cube textures which can be uploaded to shaders via shader inputs. | |||
*/ | |||
class texture | |||
{ | |||
public: | |||
/** | |||
* Constructs a texture. | |||
* | |||
* @param width Texture width, in pixels. | |||
* @param height Texture height, in pixels. For 2D or 3D textures. | |||
* @param depth Texture depth, in pixels. For 3D textures only. | |||
* @param type Pixel component data type. | |||
* @param format Pixel format. | |||
* @param color_space Color space of the pixel data. | |||
* @param data Pointer to pixel data. | |||
* | |||
* @warning If the sRGB color space is specified, pixel data will be stored internally as 8 bits per channel, and automatically converted to linear space before reading. | |||
*/ | |||
/// @{ | |||
texture(std::uint16_t width, std::uint16_t height, std::uint16_t depth, gl::pixel_type type = gl::pixel_type::uint_8, gl::pixel_format format = gl::pixel_format::rgba, gl::color_space color_space = gl::color_space::linear, const void* data = nullptr); | |||
texture(std::uint16_t width, std::uint16_t height, gl::pixel_type type = gl::pixel_type::uint_8, gl::pixel_format format = gl::pixel_format::rgba, gl::color_space color_space = gl::color_space::linear, const void* data = nullptr); | |||
texture(std::uint16_t width, gl::pixel_type type = gl::pixel_type::uint_8, gl::pixel_format format = gl::pixel_format::rgba, gl::color_space color_space = gl::color_space::linear, const void* data = nullptr); | |||
/// @} | |||
/** | |||
* Destructs a texture. | |||
*/ | |||
virtual ~texture() = 0; | |||
/** | |||
* Sets the texture filtering modes. | |||
* | |||
* @param min_filter Texture minification filter mode. | |||
* @param mag_filter Texture magnification filter mode. | |||
*/ | |||
void set_filters(texture_min_filter min_filter, texture_mag_filter mag_filter); | |||
/** | |||
* Sets the maximum anisotropy. | |||
* | |||
* @param level Max anisotropy on `[0.0, 1.0]`, with `0.0` indicating normal filtering, and `1.0` indicating maximum anisotropic filtering. | |||
*/ | |||
void set_max_anisotropy(float anisotropy); | |||
/// Returns the dimensions of the texture, in pixels. | |||
const std::array<std::uint16_t, 3>& get_dimensions() const; | |||
/// Returns the width of the texture, in pixels. | |||
const std::uint16_t& get_width() const; | |||
/// Returns the height of the texture, in pixels. | |||
const std::uint16_t& get_height() const; | |||
/// Returns the depth of the texture, in pixels. | |||
const std::uint16_t& get_depth() const; | |||
/// Returns the pixel type enumeration. | |||
const pixel_type& get_pixel_type() const; | |||
/// Returns the pixel format enumeration. | |||
const pixel_format& get_pixel_format() const; | |||
/// Returns the color space enumeration. | |||
const color_space& get_color_space() const; | |||
/// Returns the wrapping modes of the texture. | |||
const std::array<texture_wrapping, 3>& get_wrapping() const; | |||
/// Returns the filtering modes of the texture. | |||
const std::tuple<texture_min_filter, texture_mag_filter>& get_filters() const; | |||
/// Returns the maximum anisotropy. | |||
float get_max_anisotropy() const; | |||
protected: | |||
/** | |||
* Sets the texture wrapping modes. | |||
* | |||
* @param wrap_s Wrapping mode for s-coordinates. | |||
* @param wrap_t Wrapping mode for t-coordinates. | |||
* @param wrap_r Wrapping mode for r-coordinates. | |||
*/ | |||
/// @{ | |||
virtual void set_wrapping(gl::texture_wrapping wrap_s, gl::texture_wrapping wrap_t, gl::texture_wrapping wrap_r); | |||
virtual void set_wrapping(gl::texture_wrapping wrap_s, gl::texture_wrapping wrap_t); | |||
virtual void set_wrapping(gl::texture_wrapping wrap_s); | |||
/// @} | |||
/** | |||
* Resizes the texture. | |||
* | |||
* @param width Texture width, in pixels. | |||
* @param height Texture height, in pixels. For 2D or 3D textures. | |||
* @param depth Texture depth, in pixels. For 3D textures only. | |||
* @param type Pixel component data type. | |||
* @param format Pixel format. | |||
* @param color_space Color space of the pixel data. | |||
* @param data Pointer to pixel data. | |||
* | |||
* @warning If the sRGB color space is specified, pixel data will be stored internally as 8 bits per channel, and automatically converted to linear space before reading. | |||
*/ | |||
/// @{ | |||
virtual void resize(std::uint16_t width, std::uint16_t height, std::uint16_t depth, gl::pixel_type type, gl::pixel_format format, gl::color_space color_space, const void* data); | |||
virtual void resize(std::uint16_t width, std::uint16_t height, gl::pixel_type type, gl::pixel_format format, gl::color_space color_space, const void* data); | |||
virtual void resize(std::uint16_t width, gl::pixel_type type, gl::pixel_format format, gl::color_space color_space, const void* data); | |||
/// @} | |||
private: | |||
friend class framebuffer; | |||
friend class shader_input; | |||
unsigned int gl_texture_target; | |||
unsigned int gl_texture_id; | |||
std::array<std::uint16_t, 3> dimensions; | |||
gl::pixel_type pixel_type; | |||
gl::pixel_format pixel_format; | |||
gl::color_space color_space; | |||
std::array<texture_wrapping, 3> wrapping; | |||
std::tuple<texture_min_filter, texture_mag_filter> filters; | |||
float max_anisotropy; | |||
}; | |||
inline const std::array<std::uint16_t, 3>& texture::get_dimensions() const | |||
{ | |||
return dimensions; | |||
} | |||
inline const std::uint16_t& texture::get_width() const | |||
{ | |||
return dimensions[0]; | |||
} | |||
inline const std::uint16_t& texture::get_height() const | |||
{ | |||
return dimensions[1]; | |||
} | |||
inline const std::uint16_t& texture::get_depth() const | |||
{ | |||
return dimensions[2]; | |||
} | |||
inline const pixel_type& texture::get_pixel_type() const | |||
{ | |||
return pixel_type; | |||
} | |||
inline const pixel_format& texture::get_pixel_format() const | |||
{ | |||
return pixel_format; | |||
} | |||
inline const color_space& texture::get_color_space() const | |||
{ | |||
return color_space; | |||
} | |||
inline const std::array<texture_wrapping, 3>& texture::get_wrapping() const | |||
{ | |||
return wrapping; | |||
} | |||
inline const std::tuple<texture_min_filter, texture_mag_filter>& texture::get_filters() const | |||
{ | |||
return filters; | |||
} | |||
inline float texture::get_max_anisotropy() const | |||
{ | |||
return max_anisotropy; | |||
} | |||
} // namespace gl | |||
#endif // ANTKEEPER_GL_TEXTURE_HPP |