131 lines
2.8 KiB
C++
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, geom::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, geom::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
|
|
|
|
}
|