@ -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 |