#include #include namespace psemek::gfx { static std::optional max_anisotropy_level; texture_1d::texture_1d() { gl::GenTextures(1, &id_); } texture_1d::texture_1d(GLuint id) : id_(id) {} texture_1d texture_1d::null() { return texture_1d(0); } void texture_1d::bind() const { gl::BindTexture(gl::TEXTURE_1D, id_); } texture_1d::texture_1d(texture_1d && other) : id_(other.id_) , width_(other.width_) { other.id_ = 0; other.width_ = 0; } texture_1d & texture_1d::operator = (texture_1d && other) { if (this == &other) return *this; gl::DeleteTextures(1, &id_); id_ = other.id_; width_ = other.width_; other.id_ = 0; other.width_ = 0; return *this; } texture_1d::~texture_1d() { gl::DeleteTextures(1, &id_); } void texture_1d::load(GLint internal_format, std::size_t width, GLenum format, GLenum type, const void * data) { bind(); gl::TexImage1D(gl::TEXTURE_1D, 0, internal_format, width, 0, format, type, data); width_ = width; } void texture_1d::pixels(GLenum format, GLenum type, void * data) const { bind(); gl::GetTexImage(gl::TEXTURE_1D, 0, format, type, data); } texture_1d texture_1d::from_data(GLint internal_format, std::size_t width, GLenum format, GLenum type, const void * data) { texture_1d tex; tex.load(internal_format, width, format, type, data); return tex; } void texture_1d::generate_mipmap() { bind(); gl::GenerateMipmap(gl::TEXTURE_1D); } void texture_1d::nearest_filter() { bind(); gl::TexParameteri(gl::TEXTURE_1D, gl::TEXTURE_MAG_FILTER, gl::NEAREST); gl::TexParameteri(gl::TEXTURE_1D, gl::TEXTURE_MIN_FILTER, gl::LINEAR_MIPMAP_LINEAR); } void texture_1d::linear_filter() { bind(); gl::TexParameteri(gl::TEXTURE_1D, gl::TEXTURE_MAG_FILTER, gl::LINEAR); gl::TexParameteri(gl::TEXTURE_1D, gl::TEXTURE_MIN_FILTER, gl::LINEAR_MIPMAP_LINEAR); } void texture_1d::anisotropy() { if (!gl::exts::var_EXT_texture_filter_anisotropic) return; if (!max_anisotropy_level) { max_anisotropy_level = 0; gl::GetFloatv(gl::MAX_TEXTURE_MAX_ANISOTROPY_EXT, &(*max_anisotropy_level)); } gl::TexParameterf(gl::TEXTURE_1D, gl::TEXTURE_MAX_ANISOTROPY_EXT, *max_anisotropy_level); } void texture_1d::repeat() { bind(); gl::TexParameteri(gl::TEXTURE_1D, gl::TEXTURE_WRAP_S, gl::REPEAT); } void texture_1d::clamp() { bind(); gl::TexParameteri(gl::TEXTURE_1D, gl::TEXTURE_WRAP_S, gl::CLAMP_TO_EDGE); } 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; if (!max_anisotropy_level) { max_anisotropy_level = 0; gl::GetFloatv(gl::MAX_TEXTURE_MAX_ANISOTROPY_EXT, &(*max_anisotropy_level)); } gl::TexParameterf(gl::TEXTURE_2D, gl::TEXTURE_MAX_ANISOTROPY_EXT, *max_anisotropy_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); } texture_3d::texture_3d() { gl::GenTextures(1, &id_); } texture_3d::texture_3d(GLuint id) : id_(id) {} texture_3d texture_3d::null() { return texture_3d(0); } void texture_3d::bind() const { gl::BindTexture(gl::TEXTURE_3D, id_); } texture_3d::texture_3d(texture_3d && other) : id_(other.id_) , width_(other.width_) , height_(other.height_) , depth_(other.depth_) { other.id_ = 0; other.width_ = 0; other.height_ = 0; other.depth_ = 0; } texture_3d & texture_3d::operator = (texture_3d && other) { if (this == &other) return *this; gl::DeleteTextures(1, &id_); id_ = other.id_; width_ = other.width_; height_ = other.height_; depth_ = other.depth_; other.id_ = 0; other.width_ = 0; other.height_ = 0; other.depth_ = 0; return *this; } texture_3d::~texture_3d() { gl::DeleteTextures(1, &id_); } void texture_3d::load(GLint internal_format, std::size_t width, std::size_t height, std::size_t depth, GLenum format, GLenum type, const void * data) { bind(); gl::TexImage3D(gl::TEXTURE_3D, 0, internal_format, width, height, depth, 0, format, type, data); width_ = width; height_ = height; depth_ = depth; } void texture_3d::pixels(GLenum format, GLenum type, void * data) const { bind(); gl::GetTexImage(gl::TEXTURE_3D, 0, format, type, data); } texture_3d texture_3d::from_data(GLint internal_format, std::size_t width, std::size_t height, std::size_t depth, GLenum format, GLenum type, const void * data) { texture_3d tex; tex.load(internal_format, width, height, depth, format, type, data); return tex; } void texture_3d::generate_mipmap() { bind(); gl::GenerateMipmap(gl::TEXTURE_3D); } void texture_3d::nearest_filter() { bind(); gl::TexParameteri(gl::TEXTURE_3D, gl::TEXTURE_MAG_FILTER, gl::NEAREST); gl::TexParameteri(gl::TEXTURE_3D, gl::TEXTURE_MIN_FILTER, gl::LINEAR_MIPMAP_LINEAR); } void texture_3d::linear_filter() { bind(); gl::TexParameteri(gl::TEXTURE_3D, gl::TEXTURE_MAG_FILTER, gl::LINEAR); gl::TexParameteri(gl::TEXTURE_3D, gl::TEXTURE_MIN_FILTER, gl::LINEAR_MIPMAP_LINEAR); } void texture_3d::anisotropy() { if (!gl::exts::var_EXT_texture_filter_anisotropic) return; if (!max_anisotropy_level) { max_anisotropy_level = 0; gl::GetFloatv(gl::MAX_TEXTURE_MAX_ANISOTROPY_EXT, &(*max_anisotropy_level)); } gl::TexParameterf(gl::TEXTURE_3D, gl::TEXTURE_MAX_ANISOTROPY_EXT, *max_anisotropy_level); } void texture_3d::repeat() { bind(); gl::TexParameteri(gl::TEXTURE_3D, gl::TEXTURE_WRAP_S, gl::REPEAT); gl::TexParameteri(gl::TEXTURE_3D, gl::TEXTURE_WRAP_T, gl::REPEAT); gl::TexParameteri(gl::TEXTURE_3D, gl::TEXTURE_WRAP_R, gl::REPEAT); } void texture_3d::clamp() { bind(); gl::TexParameteri(gl::TEXTURE_3D, gl::TEXTURE_WRAP_S, gl::CLAMP_TO_EDGE); gl::TexParameteri(gl::TEXTURE_3D, gl::TEXTURE_WRAP_T, gl::CLAMP_TO_EDGE); gl::TexParameteri(gl::TEXTURE_3D, gl::TEXTURE_WRAP_R, gl::CLAMP_TO_EDGE); } }