694871da |
#ifndef GLTEXTURE_HPP_
#define GLTEXTURE_HPP_
#include <cstddef>
#include <string>
#include <vector>
#include <globject.hpp>
/// Class
class GLTexture : public GLObject<GL_TEXTURE, glGenTextures, glDeleteTextures>
{
public:
/// Special member functions
explicit GLTexture(
std::string object_label,
GLenum target,
GLenum binding,
GLenum internal_format = 0,
GLenum wrap = 0,
GLenum min_filter = 0,
GLenum mag_filter = 0
);
/// Core
GLOBJECT_ACCESS_THREAD(GLfloat, anisotropy)
GLint unit(bool force_active = false) const;
template<typename Data = GLubyte>
std::vector<Data> data(
GLenum target = 0,
GLenum format = DataTraits<Data>::format,
GLint alignment = 1
) const;
template<typename Data = GLubyte>
GLTexture & data(
std::vector<Data> const & data,
GLenum target = 0,
GLenum format = DataTraits<Data>::format,
GLint alignment = 1
);
template<typename Data = GLubyte>
GLTexture & clear(
Data value = Data{},
GLenum target = 0,
GLenum format = DataTraits<Data>::format,
GLint alignment = 1
);
/// Path
GLOBJECT_ACCESS_THREAD(Path, prefix)
protected:
/// Core
template<typename GLTextureDerived>
GLTextureDerived static const & empty_();
bool min_filter_mipmap_() const;
std::size_t virtual data_size_() const = 0;
void virtual data_(
void const * data,
GLenum target,
GLenum format,
GLenum type
) = 0;
/// Check
void check_unit_active_() const;
void check_unit_texture_() const;
void check_data_size_(std::size_t data_size) const;
/// String
std::string static str_target_(GLenum target);
protected:
GLenum const target_;
private:
/// Core
GLfloat static thread_local anisotropy_;
GLenum const binding_;
GLenum const min_filter_;
GLuint mutable unit_;
/// Path
Path static thread_local prefix_;
};
/// Core
template<typename Data>
inline std::vector<Data> GLTexture::data(
GLenum target,
GLenum format,
GLint alignment
) const
try
{
if (!target)
target = target_;
auto data = std::vector<Data>(data_size_());
unit(true);
glPixelStorei(GL_PACK_ALIGNMENT, alignment);
glGetTexImage(target, 0, format, DataTraits<Data>::type, data.data());
GLOBJECT_DEBUG_IF(1)
check_error_(glGetError());
return data;
}
catch (...)
{
fail_action_("get data of");
}
template<typename Data>
inline GLTexture & GLTexture::data(
std::vector<Data> const & data,
GLenum target,
GLenum format,
GLint alignment
)
try
{
if (!target)
target = target_;
check_data_size_(data.size());
unit(true);
glPixelStorei(GL_UNPACK_ALIGNMENT, alignment);
data_(data.data(), target, format, DataTraits<Data>::type);
GLOBJECT_DEBUG_IF(1)
check_error_(glGetError());
if (min_filter_mipmap_())
if (supported({3, 0}, "GL_ARB_framebuffer_object"))
glGenerateMipmap(target);
return *this;
}
catch (...)
{
fail_action_("set data of");
}
template<typename Data>
GLTexture & GLTexture::clear(
Data value,
GLenum target,
GLenum format,
GLint alignment
)
{
auto static clear = std::vector<Data>{};
clear.resize(data_size_());
std::fill(clear.begin(), clear.end(), value);
data(clear, target, format, alignment);
return *this;
}
template<typename GLTextureDerived>
inline GLTextureDerived const & GLTexture::empty_()
{
auto static const empty = []()
{
auto size = typename GLTextureDerived::Size{};
size.fill(1);
auto tmp = GLTextureDerived("empty", size);
tmp.clear();
return tmp;
}();
return empty;
}
#endif // GLTEXTURE_HPP_
|