psemek/libs/gfx/source/texture.cpp

131 lines
2.8 KiB
C++

#include <psemek/gfx/texture.hpp>
#include <optional>
namespace psemek::gfx
{
#ifndef PSEMEK_GLES
template struct basic_texture<1, gl::TEXTURE_1D>;
template struct basic_texture<2, gl::TEXTURE_1D_ARRAY>;
#endif
template struct basic_texture<2, gl::TEXTURE_2D>;
template struct basic_texture<3, gl::TEXTURE_2D_ARRAY>;
template struct basic_texture<3, gl::TEXTURE_3D>;
template struct basic_texture<2, gl::TEXTURE_CUBE_MAP>;
namespace detail
{
static std::optional<float> get_max_anisotropy()
{
if (!gl::sys::ext_ARB_texture_filter_anisotropic()) return std::nullopt;
float level;
gl::GetFloatv(gl::MAX_TEXTURE_MAX_ANISOTROPY, &level);
return level;
return 0.f;
}
std::optional<float> max_anisotropy()
{
static std::optional<float> level = get_max_anisotropy();
return level;
}
}
void texture_cubemap::load(int f, GLint internal_format, math::vector<std::size_t, 2> const & size, GLenum format, GLenum type, const void * data)
{
bind();
gl::TexImage2D(face_to_gl(f), 0, internal_format, size[0], size[1], 0, format, type, data);
size_ = size;
}
#ifndef PSEMEK_GLES
void texture_cubemap::pixels(int f, GLenum format, GLenum type, void * data) const
{
bind();
gl::GetTexImage(face_to_gl(f), 0, format, type, data);
}
#endif
GLenum texture_cubemap::face_to_gl(int f)
{
return gl::TEXTURE_CUBE_MAP_POSITIVE_X + f;
}
#ifndef PSEMEK_GLES
texture_2d_multisample::texture_2d_multisample()
{
gl::GenTextures(1, &id_);
}
texture_2d_multisample::texture_2d_multisample(texture_2d_multisample && other)
: id_(other.id_)
, size_(other.size_)
, samples_(other.samples_)
{
other.id_ = 0;
other.size_ = {0, 0};
other.samples_ = 0;
}
texture_2d_multisample & texture_2d_multisample::operator = (texture_2d_multisample && other)
{
if (this != &other)
{
reset();
id_ = other.id_;
size_ = other.size_;
samples_ = other.samples_;
other.id_ = 0;
other.size_ = {0, 0};
other.samples_ = 0;
}
return *this;
}
texture_2d_multisample::~texture_2d_multisample()
{
reset();
}
texture_2d_multisample texture_2d_multisample::null()
{
return texture_2d_multisample(nullptr);
}
void texture_2d_multisample::reset()
{
gl::DeleteTextures(1, &id_);
}
void texture_2d_multisample::bind() const
{
gl::BindTexture(target, id_);
}
void texture_2d_multisample::bind(int texture_unit) const
{
gl::ActiveTexture(gl::TEXTURE0 + texture_unit);
bind();
}
void texture_2d_multisample::load(GLint internal_format, math::vector<std::size_t, 2> const & size, int samples, bool fixed_sample_locations)
{
bind();
gl::TexImage2DMultisample(target, samples, internal_format, size[0], size[1], fixed_sample_locations ? gl::TRUE : gl::FALSE);
size_ = size;
samples_ = samples;
}
texture_2d_multisample::texture_2d_multisample(std::nullptr_t)
{}
#endif
}