655 lines
26 KiB
C++
Executable File
655 lines
26 KiB
C++
Executable File
// =====================================================================================================================
|
|
// glw, an open-source library that wraps OpenGL structures into classes.
|
|
// Copyright (C) 2024 Medusa Slockbower
|
|
//
|
|
// This program 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.
|
|
//
|
|
// This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
|
|
// =====================================================================================================================
|
|
|
|
#ifndef GLW_TEXTURE_H
|
|
#define GLW_TEXTURE_H
|
|
|
|
#include <glm/common.hpp>
|
|
#include <glm/exponential.hpp>
|
|
|
|
#include "common.h"
|
|
|
|
#include <glm/vec2.hpp>
|
|
#include <glm/vec3.hpp>
|
|
#include <glm/vec4.hpp>
|
|
|
|
#include <open-cpp-utils/template_utils.h>
|
|
|
|
namespace ocu = open_cpp_utils;
|
|
|
|
namespace glw
|
|
{
|
|
|
|
// =====================================================================================================================
|
|
// Definitions
|
|
// =====================================================================================================================
|
|
|
|
|
|
using swizzle_t = glm::vec<4, enum_t>;
|
|
using wrapping_t = glm::vec<3, enum_t>;
|
|
|
|
// Enums ---------------------------------------------------------------------------------------------------------------
|
|
|
|
enum texture_type : enum_t
|
|
{
|
|
texture1D = GL_TEXTURE_1D
|
|
, texture1DArray = GL_TEXTURE_1D_ARRAY
|
|
|
|
, texture2D = GL_TEXTURE_2D
|
|
, textureRect = GL_TEXTURE_RECTANGLE
|
|
, texture2DArray = GL_TEXTURE_2D_ARRAY
|
|
, texture2DMS = GL_TEXTURE_2D_MULTISAMPLE
|
|
, texture2DMSArray = GL_TEXTURE_2D_MULTISAMPLE_ARRAY
|
|
|
|
, textureCubemap = GL_TEXTURE_CUBE_MAP
|
|
, textureCubemapArray = GL_TEXTURE_CUBE_MAP_ARRAY
|
|
|
|
, texture3D = GL_TEXTURE_3D
|
|
};
|
|
|
|
enum texture_param : enum_t
|
|
{
|
|
depth_stencil_mode = GL_DEPTH_STENCIL_TEXTURE_MODE
|
|
|
|
, base_mip_level = GL_TEXTURE_BASE_LEVEL
|
|
, max_mip_level = GL_TEXTURE_MAX_LEVEL
|
|
|
|
, compare_mode = GL_TEXTURE_COMPARE_MODE
|
|
, compare_func = GL_TEXTURE_COMPARE_FUNC
|
|
|
|
, lod_min = GL_TEXTURE_MIN_LOD
|
|
, lod_max = GL_TEXTURE_MAX_LOD
|
|
, lod_bias = GL_TEXTURE_LOD_BIAS
|
|
|
|
, min_filter = GL_TEXTURE_MIN_FILTER
|
|
, mag_filter = GL_TEXTURE_MAG_FILTER
|
|
|
|
, swizzle = GL_TEXTURE_SWIZZLE_RGBA
|
|
, swizzle_r = GL_TEXTURE_SWIZZLE_R
|
|
, swizzle_g = GL_TEXTURE_SWIZZLE_G
|
|
, swizzle_b = GL_TEXTURE_SWIZZLE_B
|
|
, swizzle_a = GL_TEXTURE_SWIZZLE_A
|
|
|
|
, wrap_s = GL_TEXTURE_WRAP_S
|
|
, wrap_t = GL_TEXTURE_WRAP_T
|
|
, wrap_r = GL_TEXTURE_WRAP_R
|
|
, border = GL_TEXTURE_BORDER_COLOR
|
|
};
|
|
|
|
enum filtering : enum_t
|
|
{
|
|
nearest = GL_NEAREST
|
|
, linear = GL_LINEAR
|
|
, point = GL_NEAREST_MIPMAP_NEAREST
|
|
, bilinear = GL_LINEAR_MIPMAP_NEAREST
|
|
, trilinear = GL_LINEAR_MIPMAP_LINEAR
|
|
};
|
|
|
|
enum wrapping : enum_t
|
|
{
|
|
clamp = GL_CLAMP_TO_EDGE
|
|
, clamp_to_border = GL_CLAMP_TO_BORDER
|
|
, mirrored = GL_MIRRORED_REPEAT
|
|
, repeate = GL_REPEAT
|
|
, mirrored_clamp = GL_MIRROR_CLAMP_TO_EDGE
|
|
};
|
|
|
|
enum swizzle : enum_t
|
|
{
|
|
red = GL_TEXTURE_SWIZZLE_R
|
|
, green = GL_TEXTURE_SWIZZLE_G
|
|
, blue = GL_TEXTURE_SWIZZLE_B
|
|
, alpha = GL_TEXTURE_SWIZZLE_A
|
|
};
|
|
|
|
|
|
template<enum_t T_, enum_t PF_>
|
|
class texture
|
|
{
|
|
// Constants ===========================================================================================================
|
|
|
|
public:
|
|
inline static constexpr enum_t type = T_;
|
|
inline static constexpr enum_t format = PF_;
|
|
|
|
inline static constexpr struct type_traits
|
|
{
|
|
static constexpr enum_t type = T_;
|
|
static constexpr enum_t format = PF_;
|
|
static constexpr bool layered = contains_enum<type, texture1DArray,texture2DArray,texture2DMSArray,textureCubemap,textureCubemapArray,texture3D>{};
|
|
} traits {};
|
|
|
|
|
|
// Functions ===========================================================================================================
|
|
|
|
private:
|
|
void get_current_params_();
|
|
|
|
// Constructors --------------------------------------------------------------------------------------------------------
|
|
|
|
public:
|
|
texture(size_t size);
|
|
texture(glm::ivec2 size);
|
|
texture(glm::ivec2 size, size_t samples);
|
|
texture(glm::ivec3 size);
|
|
texture(glm::ivec3 size, size_t samples);
|
|
|
|
texture(texture&& move);
|
|
|
|
~texture();
|
|
|
|
inline constexpr enum_t get_type() const { return type; }
|
|
inline constexpr enum_t get_format() const { return format; }
|
|
|
|
// Handle --------------------------------------------------------------------------------------------------------------
|
|
|
|
/**
|
|
* \brief ONLY USE THIS IF YOU KNOW WHAT YOU ARE DOING
|
|
* \return The OpenGL name for the texture
|
|
*/
|
|
handle_t handle() { return handle_; }
|
|
|
|
|
|
// Capacity ------------------------------------------------------------------------------------------------------------
|
|
|
|
size_t size() const requires(contains_enum<type, texture1D>::value) { return size_.x; }
|
|
glm::ivec2 size() const requires(contains_enum<type, texture1DArray, texture2D, texture2DMS, textureCubemap>::value) { return size_; }
|
|
glm::ivec3 size() const requires(contains_enum<type, texture2DArray, texture2DMSArray, textureCubemapArray>::value) { return size_; }
|
|
|
|
void resize(size_t size);
|
|
void resize(glm::ivec2 size);
|
|
void resize(glm::ivec2 size, size_t samples);
|
|
void resize(glm::ivec3 size);
|
|
void resize(glm::ivec3 size, size_t samples);
|
|
|
|
size_t num_samples() const { return samples_; }
|
|
|
|
// Modifiers -----------------------------------------------------------------------------------------------------------
|
|
|
|
void upload(const void* pixels, size_t size, index_t offset = 0, index_t level = 0, enum_t layout = r_i, enum_t type = uint8)
|
|
requires(contains_enum<texture::type, texture1D>::value)
|
|
{
|
|
glTextureSubImage1D(handle_, level, offset, size, layout, type, pixels);
|
|
glGenerateTextureMipmap(handle_);
|
|
}
|
|
|
|
void upload(const void* pixels, glm::ivec2 size, glm::ivec2 offset = glm::ivec2(0), index_t level = 0, enum_t layout = r_i, enum_t type = uint8)
|
|
requires(contains_enum<texture::type, texture1DArray, texture2D, textureCubemap>::value)
|
|
{
|
|
glTextureSubImage2D(handle_, level, offset.x, offset.y, size.x, size.y, layout, type, pixels);
|
|
}
|
|
|
|
void upload(const void* pixels, glm::ivec3 size, glm::ivec3 offset = glm::ivec3(0), index_t level = 0, enum_t layout = r_i, enum_t type = uint8)
|
|
requires(contains_enum<texture::type, texture2DArray, textureCubemapArray, texture3D>::value)
|
|
{
|
|
glTextureSubImage3D(handle_, level, offset.x, offset.y, offset.x, size.x, size.y, size.z, layout, type, pixels);
|
|
}
|
|
|
|
void clear(size_t size = -1, index_t offset = 0, index_t level = 0, const void* data = nullptr, enum_t layout = r_i, enum_t type = uint8)
|
|
{
|
|
static_assert(contains_enum<texture::type, texture1D>::value);
|
|
|
|
size = size < 0 ? size_.x - offset : size;
|
|
glClearTexSubImage(handle_, level, offset, 0, 0, size, 1, 1, layout, type, data);
|
|
}
|
|
|
|
void clear(glm::ivec2 size = glm::ivec2(-1), glm::ivec2 offset = glm::ivec2(0), index_t level = 0, const void* data = nullptr, enum_t layout = r_i, enum_t type = uint8)
|
|
{
|
|
static_assert(contains_enum<texture::type, texture1DArray, texture2D, textureCubemap>::value);
|
|
|
|
size.x = size.x < 0 ? size_.x - offset.x : size.x;
|
|
size.y = size.y < 0 ? size_.y - offset.y : size.y;
|
|
glClearTexSubImage(handle_, level, offset.x, offset.y, 0, size.x, size.y, 1, layout, type, data);
|
|
}
|
|
|
|
void clear(glm::ivec3 size = glm::ivec3(-1), glm::ivec3 offset = glm::ivec3(0), index_t level = 0, const void* data = nullptr, enum_t layout = r_i, enum_t type = uint8)
|
|
{
|
|
static_assert(contains_enum<texture::type, texture1DArray, texture2D, textureCubemap>::value);
|
|
size.x = size.x < 0 ? size_.x - offset.x : size.x;
|
|
size.y = size.y < 0 ? size_.y - offset.y : size.y;
|
|
size.z = size.z < 0 ? size_.z - offset.z : size.z;
|
|
glClearTexSubImage(handle_, level, offset.x, offset.y, offset.z, size.x, size.y, size.z, layout, type, data);
|
|
}
|
|
|
|
template<enum_t OT_, enum_t OPF_>
|
|
void copy(const texture<OT_, OPF_>& src, size_t size = -1,
|
|
offset_t src_offset = 0, index_t src_level = 0,
|
|
offset_t dst_offset = 0, index_t dst_level = 0)
|
|
{
|
|
using otexture = texture<OT_, OPF_>;
|
|
static_assert(contains_enum<type, texture1D>::value && type == otexture::type);
|
|
size = size < 0 ? src.size_.x - src_offset : size;
|
|
|
|
glCopyImageSubData(
|
|
src.handle_, otexture::type, src_level, src_offset, 0, 0,
|
|
handle_, type, dst_level, dst_offset, 0, 0,
|
|
size, 0, 0
|
|
);
|
|
}
|
|
|
|
template<enum_t OT_, enum_t OPF_>
|
|
void copy(const texture<OT_, OPF_>& src, glm::ivec2 size = glm::ivec2(-1),
|
|
glm::ivec2 src_offset = glm::ivec2(0), index_t src_level = 0,
|
|
glm::ivec2 dst_offset = glm::ivec2(0), index_t dst_level = 0)
|
|
{
|
|
using otexture = texture<OT_, OPF_>;
|
|
static_assert(contains_enum<type, texture1DArray, texture2D, textureCubemap>::value && type == otexture::type);
|
|
size.x = size.x < 0 ? src.size_.x - src_offset.x : size.x;
|
|
size.y = size.y < 0 ? src.size_.y - src_offset.y : size.y;
|
|
|
|
glCopyImageSubData(
|
|
src.handle_, otexture::type, src_level, src_offset.x, src_offset.y, 0,
|
|
handle_, type, dst_level, dst_offset.x, dst_offset.y, 0,
|
|
size.x, size.y, 0
|
|
);
|
|
}
|
|
|
|
template<enum_t OT_, enum_t OPF_>
|
|
void copy(const texture<OT_, OPF_>& src, glm::ivec3 size = glm::ivec3(-1),
|
|
glm::ivec3 src_offset = glm::ivec3(0), index_t src_level = 0,
|
|
glm::ivec3 dst_offset = glm::ivec3(0), index_t dst_level = 0)
|
|
{
|
|
using otexture = texture<OT_, OPF_>;
|
|
static_assert(contains_enum<type, texture1DArray, texture2D, textureCubemap>::value && type == otexture::type);
|
|
size.x = size.x < 0 ? src.size_.x - src_offset.x : size.x;
|
|
size.y = size.y < 0 ? src.size_.y - src_offset.y : size.y;
|
|
size.z = size.z < 0 ? src.size_.z - src_offset.z : size.z;
|
|
|
|
glCopyImageSubData(
|
|
src.handle_, otexture::type, src_level, src_offset.x, src_offset.y, src_offset.z,
|
|
handle_, type, dst_level, dst_offset.x, dst_offset.y, dst_offset.z,
|
|
size.x, size.y, size.z
|
|
);
|
|
}
|
|
|
|
|
|
// Binding -------------------------------------------------------------------------------------------------------------
|
|
|
|
void bind(location_t loc)
|
|
{
|
|
glActiveTexture(GL_TEXTURE0 + loc);
|
|
glBindTexture(type, handle_);
|
|
}
|
|
|
|
void bind_image(location_t loc, enum_t access)
|
|
{
|
|
glBindImageTexture(loc, handle_, 0, traits.layered, 0, access, format);
|
|
}
|
|
|
|
void bind_image(location_t loc, index_t level, bool layered, index_t layer, enum_t access, enum_t format)
|
|
{
|
|
glBindImageTexture(loc, handle_, level, layered, layer, access, format);
|
|
}
|
|
|
|
|
|
// Depth / Stencil -----------------------------------------------------------------------------------------------------
|
|
|
|
void set_ds_mode(enum_t mode) { glTextureParameteri(handle_, GL_DEPTH_STENCIL_TEXTURE_MODE, depth_stencil_mode_ = mode); }
|
|
enum_t get_ds_mode() const { return depth_stencil_mode_; }
|
|
|
|
void set_compare_mode(enum_t mode) { glTextureParameteri(handle_, GL_TEXTURE_COMPARE_MODE, compare_mode_ = mode); }
|
|
enum_t get_compare_mode() const { return compare_mode_; }
|
|
|
|
void set_compare_func(enum_t func) { glTextureParameteri(handle_, GL_TEXTURE_COMPARE_FUNC, compare_func_ = func); }
|
|
enum_t get_compare_func() const { return compare_func_; }
|
|
|
|
void set_comparison(enum_t mode, enum_t func) { set_compare_mode(mode); set_compare_func(func); }
|
|
|
|
|
|
// Mip Mapping ---------------------------------------------------------------------------------------------------------
|
|
|
|
// TODO: Fix bug from optimization in resize, might be better to make a "rebuild" function
|
|
void set_num_mip_levels(size_t value)
|
|
requires(contains_enum<type, texture1D>::value)
|
|
{ mip_levels_ = value; resize(size_.x); }
|
|
|
|
void set_num_mip_levels(size_t value)
|
|
requires(contains_enum<type, texture1DArray, texture2D, textureCubemap>::value)
|
|
{ mip_levels_ = value; resize(size_.x, size_.y); }
|
|
|
|
void set_num_mip_levels(size_t value)
|
|
requires(contains_enum<type, texture2DArray, textureCubemapArray, texture3D>::value)
|
|
{ mip_levels_ = value; resize(size_.x, size_.y, size_.z); }
|
|
|
|
size_t get_num_mip_levels() const { return mip_levels_; }
|
|
|
|
void set_base_mip_level(size_t value) { glTextureParameteri(handle_, GL_TEXTURE_BASE_LEVEL, base_mip_level_ = value); }
|
|
size_t get_base_mip_level() const { return base_mip_level_; }
|
|
|
|
void set_max_mip_level(size_t value) { glTextureParameteri(handle_, GL_TEXTURE_MAX_LEVEL, max_mip_level_ = value); }
|
|
size_t get_max_mip_level() const { return max_mip_level_; }
|
|
|
|
void set_lod_min(float value) { glTextureParameterf(handle_, GL_TEXTURE_MIN_LOD, lod_min_ = value); }
|
|
float get_lod_min() const { return lod_min_; }
|
|
|
|
void set_lod_max(float value) { glTextureParameterf(handle_, GL_TEXTURE_MAX_LOD, lod_max_ = value); }
|
|
float get_lod_max() const { return lod_max_; }
|
|
|
|
void set_lod_range(float min, float max) { set_lod_min(min); set_lod_max(max); }
|
|
|
|
void set_lod_bias(float value) { glTextureParameterf(handle_, GL_TEXTURE_LOD_BIAS, lod_bias_ = value); }
|
|
float get_lod_bias() const { return lod_bias_; }
|
|
|
|
void generate_mipmaps() { glGenerateTextureMipmap(handle_); }
|
|
|
|
|
|
// Filtering -----------------------------------------------------------------------------------------------------------
|
|
|
|
void set_min_filter(enum_t value) { glTextureParameteri(handle_, GL_TEXTURE_MIN_FILTER, min_filter_ = value); }
|
|
enum_t get_min_filter() const { return min_filter_; }
|
|
|
|
void set_mag_filter(enum_t value) { glTextureParameteri(handle_, GL_TEXTURE_MAG_FILTER, mag_filter_ = value); }
|
|
enum_t get_mag_filter() const { return mag_filter_; }
|
|
|
|
|
|
// Swizzling -----------------------------------------------------------------------------------------------------------
|
|
|
|
void set_swizzle_r(enum_t swizzle) { glTextureParameteri(handle_, GL_TEXTURE_SWIZZLE_R, swizzle_.r = swizzle); }
|
|
enum_t get_swizzle_r() const { return swizzle_.r; }
|
|
|
|
void set_swizzle_g(enum_t swizzle) { glTextureParameteri(handle_, GL_TEXTURE_SWIZZLE_G, swizzle_.g = swizzle); }
|
|
enum_t get_swizzle_g() const { return swizzle_.g; }
|
|
|
|
void set_swizzle_b(enum_t swizzle) { glTextureParameteri(handle_, GL_TEXTURE_SWIZZLE_B, swizzle_.b = swizzle); }
|
|
enum_t get_swizzle_b() const { return swizzle_.b; }
|
|
|
|
void set_swizzle_a(enum_t swizzle) { glTextureParameteri(handle_, GL_TEXTURE_SWIZZLE_A, swizzle_.a = swizzle); }
|
|
enum_t get_swizzle_a() const { return swizzle_.a; }
|
|
|
|
void set_swizzle(const swizzle_t& swizzle) { glTextureParameterIuiv(handle_, GL_TEXTURE_SWIZZLE_RGBA, &(swizzle_ = swizzle).x); }
|
|
const swizzle_t& get_swizzle() const { return swizzle_; }
|
|
|
|
|
|
// Wrapping ------------------------------------------------------------------------------------------------------------
|
|
|
|
void set_wrapping_s(enum_t value) { glTextureParameteri(handle_, GL_TEXTURE_WRAP_S, wrapping_.x = value); }
|
|
enum_t get_wrapping_s() const { return wrapping_.x; }
|
|
|
|
void set_wrapping_t(enum_t value) { glTextureParameteri(handle_, GL_TEXTURE_WRAP_T, wrapping_.y = value); }
|
|
enum_t get_wrapping_t() const { return wrapping_.y; }
|
|
|
|
void set_wrapping_r(enum_t value) { glTextureParameteri(handle_, GL_TEXTURE_WRAP_R, wrapping_.z = value); }
|
|
enum_t get_wrapping_r() const { return wrapping_.z; }
|
|
|
|
void set_wrapping(const wrapping_t& value)
|
|
{
|
|
glTextureParameteri(handle_, GL_TEXTURE_WRAP_S, wrapping_.x = value.x);
|
|
glTextureParameteri(handle_, GL_TEXTURE_WRAP_T, wrapping_.y = value.y);
|
|
glTextureParameteri(handle_, GL_TEXTURE_WRAP_R, wrapping_.z = value.z);
|
|
}
|
|
|
|
const wrapping_t& get_wrapping() const { return wrapping_; }
|
|
|
|
void set_border_color(const glm::vec4& value) { glTextureParameterfv(handle_, GL_TEXTURE_BORDER_COLOR, &(border_color_ = value).x); }
|
|
const glm::vec4& get_border_color() const { return border_color_; }
|
|
|
|
// Variables ===========================================================================================================
|
|
|
|
private:
|
|
handle_t handle_;
|
|
glm::ivec3 size_;
|
|
size_t samples_, mip_levels_;
|
|
|
|
enum_t depth_stencil_mode_;
|
|
size_t base_mip_level_, max_mip_level_;
|
|
glm::vec4 border_color_;
|
|
enum_t compare_mode_, compare_func_;
|
|
float lod_min_, lod_max_, lod_bias_;
|
|
enum_t min_filter_, mag_filter_;
|
|
swizzle_t swizzle_;
|
|
wrapping_t wrapping_;
|
|
};
|
|
|
|
template<enum_t T_, enum_t PF_>
|
|
void texture<T_, PF_>::get_current_params_()
|
|
{
|
|
glGetTextureParameterIuiv(handle_, GL_DEPTH_STENCIL_TEXTURE_MODE, &depth_stencil_mode_);
|
|
glGetTextureParameteriv(handle_, GL_TEXTURE_BASE_LEVEL, &base_mip_level_);
|
|
glGetTextureParameteriv(handle_, GL_TEXTURE_MAX_LEVEL, &max_mip_level_);
|
|
|
|
glGetTextureParameterfv(handle_, GL_TEXTURE_BORDER_COLOR, &border_color_.x);
|
|
|
|
glGetTextureParameterIuiv(handle_, GL_TEXTURE_COMPARE_MODE, &compare_mode_);
|
|
glGetTextureParameterIuiv(handle_, GL_TEXTURE_COMPARE_FUNC, &compare_func_);
|
|
|
|
glGetTextureParameterfv(handle_, GL_TEXTURE_MIN_LOD, &lod_min_);
|
|
glGetTextureParameterfv(handle_, GL_TEXTURE_MAX_LOD, &lod_max_);
|
|
glGetTextureParameterfv(handle_, GL_TEXTURE_LOD_BIAS, &lod_bias_);
|
|
|
|
glGetTextureParameterIuiv(handle_, GL_TEXTURE_MIN_FILTER, &min_filter_);
|
|
glGetTextureParameterIuiv(handle_, GL_TEXTURE_MAG_FILTER, &mag_filter_);
|
|
|
|
glGetTextureParameterIuiv(handle_, GL_TEXTURE_SWIZZLE_RGBA, &swizzle_.x);
|
|
glGetTextureParameterIuiv(handle_, GL_TEXTURE_WRAP_S, &wrapping_.x);
|
|
glGetTextureParameterIuiv(handle_, GL_TEXTURE_WRAP_T, &wrapping_.y);
|
|
glGetTextureParameterIuiv(handle_, GL_TEXTURE_WRAP_R, &wrapping_.z);
|
|
}
|
|
|
|
template<enum_t T_, enum_t PF_>
|
|
texture<T_, PF_>::texture(size_t size)
|
|
: handle_(NULL)
|
|
, size_(size, size, size)
|
|
, samples_(1), mip_levels_(0)
|
|
, depth_stencil_mode_()
|
|
, base_mip_level_(), max_mip_level_()
|
|
, border_color_()
|
|
, compare_mode_(), compare_func_()
|
|
, lod_min_(), lod_max_(), lod_bias_()
|
|
, min_filter_(), mag_filter_()
|
|
, swizzle_(), wrapping_()
|
|
{
|
|
static_assert(contains_enum<type, texture1D>::value);
|
|
|
|
mip_levels_ = static_cast<size_t>(glm::log2(static_cast<float>(size)));
|
|
mip_levels_ = std::max(mip_levels_ - 6, 1);
|
|
|
|
glCreateTextures(type, 1, &handle_);
|
|
glTextureStorage1D(handle_, mip_levels_, format, size);
|
|
|
|
get_current_params_();
|
|
}
|
|
|
|
template<enum_t T_, enum_t PF_>
|
|
texture<T_, PF_>::texture(glm::ivec2 size)
|
|
: handle_(NULL)
|
|
, size_(size, 1)
|
|
, samples_(1), mip_levels_(0)
|
|
, depth_stencil_mode_()
|
|
, base_mip_level_(), max_mip_level_()
|
|
, border_color_()
|
|
, compare_mode_(), compare_func_()
|
|
, lod_min_(), lod_max_(), lod_bias_()
|
|
, min_filter_(), mag_filter_()
|
|
, swizzle_(), wrapping_()
|
|
{
|
|
static_assert(contains_enum<type, texture1DArray, texture2D, textureCubemap>::value);
|
|
|
|
mip_levels_ = static_cast<size_t>(glm::log2(static_cast<float>(min(size.x, size.y))));
|
|
mip_levels_ = std::max(mip_levels_ - 6, 1);
|
|
|
|
glCreateTextures(type, 1, &handle_);
|
|
glTextureStorage2D(handle_, mip_levels_, format, size.x, size.y);
|
|
|
|
get_current_params_();
|
|
}
|
|
|
|
template<enum_t T_, enum_t PF_>
|
|
texture<T_, PF_>::texture(glm::ivec2 size, size_t samples)
|
|
: handle_(NULL)
|
|
, size_(size, 1)
|
|
, samples_(samples), mip_levels_(0)
|
|
, depth_stencil_mode_()
|
|
, base_mip_level_(), max_mip_level_()
|
|
, border_color_()
|
|
, compare_mode_(), compare_func_()
|
|
, lod_min_(), lod_max_(), lod_bias_()
|
|
, min_filter_(), mag_filter_()
|
|
, swizzle_(), wrapping_()
|
|
{
|
|
static_assert(contains_enum<type, texture2DMS>::value);
|
|
|
|
glCreateTextures(type, 1, &handle_);
|
|
glTextureStorage2DMultisample(handle_, samples, format, size.x, size.y, true);
|
|
|
|
get_current_params_();
|
|
}
|
|
|
|
template<enum_t T_, enum_t PF_>
|
|
texture<T_, PF_>::texture(glm::ivec3 size)
|
|
: handle_(NULL)
|
|
, size_(size)
|
|
, samples_(1), mip_levels_(0)
|
|
, depth_stencil_mode_()
|
|
, base_mip_level_(), max_mip_level_()
|
|
, border_color_()
|
|
, compare_mode_(), compare_func_()
|
|
, lod_min_(), lod_max_(), lod_bias_()
|
|
, min_filter_(), mag_filter_()
|
|
, swizzle_(), wrapping_()
|
|
{
|
|
static_assert(contains_enum<type, texture2DArray, textureCubemapArray, texture3D>::value);
|
|
|
|
mip_levels_ = static_cast<size_t>(glm::log2(static_cast<float>(min(size.x, size.y, size.z))));
|
|
mip_levels_ = std::max(mip_levels_ - 6, 1);
|
|
|
|
glCreateTextures(type, 1, &handle_);
|
|
glTextureStorage3D(handle_, mip_levels_, format, size.x, size.y, size.z);
|
|
|
|
get_current_params_();
|
|
}
|
|
|
|
template<enum_t T_, enum_t PF_>
|
|
texture<T_, PF_>::texture(glm::ivec3 size, size_t samples)
|
|
: handle_(NULL)
|
|
, size_(size)
|
|
, samples_(samples), mip_levels_(0)
|
|
, depth_stencil_mode_()
|
|
, base_mip_level_(), max_mip_level_()
|
|
, border_color_()
|
|
, compare_mode_(), compare_func_()
|
|
, lod_min_(), lod_max_(), lod_bias_()
|
|
, min_filter_(), mag_filter_()
|
|
, swizzle_(), wrapping_()
|
|
{
|
|
static_assert(contains_enum<type, texture2DMSArray>::value);
|
|
|
|
glCreateTextures(type, 1, &handle_);
|
|
glTextureStorage3DMultisample(handle_, samples, format, size.x, size.y, size.z, true);
|
|
|
|
get_current_params_();
|
|
}
|
|
|
|
template<enum_t T_, enum_t PF_>
|
|
texture<T_, PF_>::texture(texture&& move)
|
|
: handle_(move.handle_)
|
|
, size_(move.size_)
|
|
, samples_(move.samples_)
|
|
, mip_levels_(move.mip_levels_)
|
|
, depth_stencil_mode_(move.depth_stencil_mode_)
|
|
, base_mip_level_(move.base_mip_level_)
|
|
, max_mip_level_(move.max_mip_level_)
|
|
, border_color_(move.border_color_)
|
|
, compare_mode_(move.compare_mode_)
|
|
, compare_func_(move.compare_func_)
|
|
, lod_min_(move.lod_min_)
|
|
, lod_max_(move.lod_max_)
|
|
, lod_bias_(move.lod_bias_)
|
|
, min_filter_(move.min_filter_)
|
|
, mag_filter_(move.mag_filter_)
|
|
, swizzle_(move.swizzle_)
|
|
, wrapping_(move.wrapping_)
|
|
|
|
{
|
|
move.handle_ = 0;
|
|
}
|
|
|
|
template<enum_t T_, enum_t PF_>
|
|
texture<T_, PF_>::~texture()
|
|
{
|
|
if(handle_) glDeleteTextures(1, &handle_);
|
|
}
|
|
|
|
template<enum_t T_, enum_t PF_>
|
|
void texture<T_, PF_>::resize(size_t size)
|
|
{
|
|
static_assert(contains_enum<type, texture1D>::value);
|
|
|
|
if(size == size_.x) return;
|
|
|
|
glDeleteTextures(1, &handle_);
|
|
glCreateTextures(type, 1, &handle_);
|
|
glTextureStorage1D(handle_, mip_levels_, format, size);
|
|
size_ = glm::ivec3(size, 1, 1);
|
|
}
|
|
|
|
template<enum_t T_, enum_t PF_>
|
|
void texture<T_, PF_>::resize(glm::ivec2 size)
|
|
{
|
|
static_assert(contains_enum<type, texture1DArray, texture2D, textureRect, textureCubemap>::value);
|
|
|
|
if(size.x == size_.x && size.y == size_.y) return;
|
|
|
|
glDeleteTextures(1, &handle_);
|
|
glCreateTextures(type, 1, &handle_);
|
|
glTextureStorage2D(handle_, mip_levels_, format, size.x, size.y);
|
|
size_ = glm::ivec3(size, 1);
|
|
}
|
|
|
|
template<enum_t T_, enum_t PF_>
|
|
void texture<T_, PF_>::resize(glm::ivec2 size, size_t samples)
|
|
{
|
|
static_assert(contains_enum<type, texture2DMS>::value);
|
|
|
|
if(size.x == size_.x && size.y == size_.y && samples == samples_) return;
|
|
|
|
glDeleteTextures(1, &handle_);
|
|
glCreateTextures(type, 1, &handle_);
|
|
glTextureStorage2DMultisample(handle_, samples_ = samples, format, size.x, size.y, true);
|
|
size_ = glm::ivec3(size, 1);
|
|
}
|
|
|
|
template<enum_t T_, enum_t PF_>
|
|
void texture<T_, PF_>::resize(glm::ivec3 size)
|
|
{
|
|
static_assert(contains_enum<type, texture2DArray, textureCubemapArray, texture3D>::value);
|
|
|
|
if(size.x == size_.x && size.y == size_.y && size.z == size_.z) return;
|
|
|
|
glDeleteTextures(1, &handle_);
|
|
glCreateTextures(type, 1, &handle_);
|
|
glTextureStorage3D(handle_, mip_levels_, format, size.x, size.y, size.z);
|
|
size_ = glm::ivec3(size);
|
|
}
|
|
|
|
template<enum_t T_, enum_t PF_>
|
|
void texture<T_, PF_>::resize(glm::ivec3 size, size_t samples)
|
|
{
|
|
static_assert(contains_enum<type, texture2DMSArray>::value);
|
|
|
|
if(size.x == size_.x && size.y == size_.y && size.z == size_.z && samples == samples_) return;
|
|
|
|
glDeleteTextures(1, &handle_);
|
|
glCreateTextures(type, 1, &handle_);
|
|
glTextureStorage3DMultisample(handle_, samples_ = samples, format, size.x, size.y, size.z, true);
|
|
size_ = glm::ivec3(size);
|
|
}
|
|
|
|
}
|
|
|
|
#endif // GLW_TEXTURE_H
|