#include #include 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 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); } }