125 lines
2.7 KiB
C++
125 lines
2.7 KiB
C++
#include <psemek/gfx/texture.hpp>
|
|
#include <optional>
|
|
|
|
namespace psemek::gfx
|
|
{
|
|
|
|
texture_2d::texture_2d()
|
|
{
|
|
gl::GenTextures(1, &id_);
|
|
}
|
|
|
|
texture_2d::texture_2d(GLuint id)
|
|
: id_(id)
|
|
{}
|
|
|
|
texture_2d texture_2d::null()
|
|
{
|
|
return texture_2d(0);
|
|
}
|
|
|
|
void texture_2d::bind() const
|
|
{
|
|
gl::BindTexture(gl::TEXTURE_2D, id_);
|
|
}
|
|
|
|
texture_2d::texture_2d(texture_2d && other)
|
|
: id_(other.id_)
|
|
, width_(other.width_)
|
|
, height_(other.height_)
|
|
{
|
|
other.id_ = 0;
|
|
other.width_ = 0;
|
|
other.height_ = 0;
|
|
}
|
|
|
|
texture_2d & texture_2d::operator = (texture_2d && other)
|
|
{
|
|
if (this == &other) return *this;
|
|
|
|
gl::DeleteTextures(1, &id_);
|
|
id_ = other.id_;
|
|
width_ = other.width_;
|
|
height_ = other.height_;
|
|
other.id_ = 0;
|
|
other.width_ = 0;
|
|
other.height_ = 0;
|
|
|
|
return *this;
|
|
}
|
|
|
|
texture_2d::~texture_2d()
|
|
{
|
|
gl::DeleteTextures(1, &id_);
|
|
}
|
|
|
|
void texture_2d::load(GLint internal_format, std::size_t width, std::size_t height, GLenum format, GLenum type, const void * data)
|
|
{
|
|
bind();
|
|
gl::TexImage2D(gl::TEXTURE_2D, 0, internal_format, width, height, 0, format, type, data);
|
|
|
|
width_ = width;
|
|
height_ = height;
|
|
}
|
|
|
|
void texture_2d::pixels(GLenum format, GLenum type, void * data) const
|
|
{
|
|
bind();
|
|
gl::GetTexImage(gl::TEXTURE_2D, 0, format, type, data);
|
|
}
|
|
|
|
texture_2d texture_2d::from_data(GLint internal_format, std::size_t width, std::size_t height, GLenum format, GLenum type, const void * data)
|
|
{
|
|
texture_2d tex;
|
|
tex.load(internal_format, width, height, format, type, data);
|
|
return tex;
|
|
}
|
|
|
|
void texture_2d::generate_mipmap()
|
|
{
|
|
bind();
|
|
gl::GenerateMipmap(gl::TEXTURE_2D);
|
|
}
|
|
|
|
void texture_2d::nearest_filter()
|
|
{
|
|
bind();
|
|
gl::TexParameteri(gl::TEXTURE_2D, gl::TEXTURE_MAG_FILTER, gl::NEAREST);
|
|
gl::TexParameteri(gl::TEXTURE_2D, gl::TEXTURE_MIN_FILTER, gl::LINEAR_MIPMAP_LINEAR);
|
|
}
|
|
|
|
void texture_2d::linear_filter()
|
|
{
|
|
bind();
|
|
gl::TexParameteri(gl::TEXTURE_2D, gl::TEXTURE_MAG_FILTER, gl::LINEAR);
|
|
gl::TexParameteri(gl::TEXTURE_2D, gl::TEXTURE_MIN_FILTER, gl::LINEAR_MIPMAP_LINEAR);
|
|
}
|
|
|
|
void texture_2d::anisotropy()
|
|
{
|
|
if (!gl::exts::var_EXT_texture_filter_anisotropic) return;
|
|
|
|
static std::optional<float> level;
|
|
if (!level)
|
|
{
|
|
level = 0;
|
|
gl::GetFloatv(gl::MAX_TEXTURE_MAX_ANISOTROPY_EXT, &(*level));
|
|
}
|
|
gl::TexParameterf(gl::TEXTURE_2D, gl::TEXTURE_MAX_ANISOTROPY_EXT, *level);
|
|
}
|
|
|
|
void texture_2d::repeat()
|
|
{
|
|
bind();
|
|
gl::TexParameteri(gl::TEXTURE_2D, gl::TEXTURE_WRAP_S, gl::REPEAT);
|
|
gl::TexParameteri(gl::TEXTURE_2D, gl::TEXTURE_WRAP_T, gl::REPEAT);
|
|
}
|
|
|
|
void texture_2d::clamp()
|
|
{
|
|
bind();
|
|
gl::TexParameteri(gl::TEXTURE_2D, gl::TEXTURE_WRAP_S, gl::CLAMP_TO_EDGE);
|
|
gl::TexParameteri(gl::TEXTURE_2D, gl::TEXTURE_WRAP_T, gl::CLAMP_TO_EDGE);
|
|
}
|
|
|
|
}
|