Add 3D and 1D textures
This commit is contained in:
parent
e520b464e4
commit
f01219c4e7
2 changed files with 393 additions and 6 deletions
|
|
@ -42,6 +42,80 @@ namespace psemek::gfx
|
|||
static constexpr GLenum type = gl::FLOAT;
|
||||
};
|
||||
|
||||
struct texture_1d
|
||||
{
|
||||
texture_1d();
|
||||
texture_1d(texture_1d const &) = delete;
|
||||
texture_1d(texture_1d &&);
|
||||
|
||||
texture_1d & operator = (texture_1d const &) = delete;
|
||||
texture_1d & operator = (texture_1d &&);
|
||||
|
||||
~texture_1d();
|
||||
|
||||
static texture_1d null();
|
||||
|
||||
GLuint id() const { return id_; }
|
||||
|
||||
void bind() const;
|
||||
|
||||
explicit operator bool () const { return id_ != 0; }
|
||||
|
||||
int width() const { return width_; }
|
||||
|
||||
geom::vector<int, 1> size() const { return {width_}; }
|
||||
|
||||
void load(GLint internal_format, std::size_t width, GLenum format, GLenum type, const void * data);
|
||||
|
||||
template <typename Pixel>
|
||||
void load(std::size_t width, Pixel const * data = nullptr)
|
||||
{
|
||||
using traits = pixel_traits<Pixel>;
|
||||
load(traits::internal_format, width, traits::format, traits::type, data);
|
||||
}
|
||||
|
||||
template <typename Pixel>
|
||||
void load(util::array<Pixel, 1> const & p)
|
||||
{
|
||||
load(p.width(), p.data());
|
||||
}
|
||||
|
||||
void pixels(GLenum format, GLenum type, void * data) const;
|
||||
|
||||
template <typename Pixmap>
|
||||
Pixmap pixels() const
|
||||
{
|
||||
using traits = pixel_traits<typename Pixmap::pixel_type>;
|
||||
Pixmap p({width_});
|
||||
pixels(traits::format, traits::type, p.data());
|
||||
return p;
|
||||
}
|
||||
|
||||
static texture_1d from_data(GLint internal_format, std::size_t width, GLenum format, GLenum type, const void * data);
|
||||
|
||||
template <typename Pixmap>
|
||||
static texture_1d from_pixmap(Pixmap const & p)
|
||||
{
|
||||
texture_1d t;
|
||||
t.load(p);
|
||||
return t;
|
||||
}
|
||||
|
||||
void generate_mipmap();
|
||||
void nearest_filter();
|
||||
void linear_filter();
|
||||
void anisotropy();
|
||||
|
||||
void repeat();
|
||||
void clamp();
|
||||
|
||||
private:
|
||||
GLuint id_;
|
||||
int width_ = 0;
|
||||
|
||||
texture_1d(GLuint id);
|
||||
};
|
||||
|
||||
struct texture_2d
|
||||
{
|
||||
texture_2d();
|
||||
|
|
@ -87,7 +161,7 @@ namespace psemek::gfx
|
|||
Pixmap pixels() const
|
||||
{
|
||||
using traits = pixel_traits<typename Pixmap::pixel_type>;
|
||||
Pixmap p(width_, height_);
|
||||
Pixmap p({width_, height_});
|
||||
pixels(traits::format, traits::type, p.data());
|
||||
return p;
|
||||
}
|
||||
|
|
@ -118,4 +192,82 @@ namespace psemek::gfx
|
|||
texture_2d(GLuint id);
|
||||
};
|
||||
|
||||
struct texture_3d
|
||||
{
|
||||
texture_3d();
|
||||
texture_3d(texture_3d const &) = delete;
|
||||
texture_3d(texture_3d &&);
|
||||
|
||||
texture_3d & operator = (texture_3d const &) = delete;
|
||||
texture_3d & operator = (texture_3d &&);
|
||||
|
||||
~texture_3d();
|
||||
|
||||
static texture_3d null();
|
||||
|
||||
GLuint id() const { return id_; }
|
||||
|
||||
void bind() const;
|
||||
|
||||
explicit operator bool () const { return id_ != 0; }
|
||||
|
||||
int width() const { return width_; }
|
||||
int height() const { return height_; }
|
||||
int depth() const { return depth_; }
|
||||
|
||||
geom::vector<int, 3> size() const { return {width_, height_, depth_}; }
|
||||
|
||||
void load(GLint internal_format, std::size_t width, std::size_t height, std::size_t depth, GLenum format, GLenum type, const void * data);
|
||||
|
||||
template <typename Pixel>
|
||||
void load(std::size_t width, std::size_t height, std::size_t depth, Pixel const * data = nullptr)
|
||||
{
|
||||
using traits = pixel_traits<Pixel>;
|
||||
load(traits::internal_format, width, height, depth, traits::format, traits::type, data);
|
||||
}
|
||||
|
||||
template <typename Pixel>
|
||||
void load(util::array<Pixel, 3> const & p)
|
||||
{
|
||||
load(p.width(), p.height(), p.depth(), p.data());
|
||||
}
|
||||
|
||||
void pixels(GLenum format, GLenum type, void * data) const;
|
||||
|
||||
template <typename Pixmap>
|
||||
Pixmap pixels() const
|
||||
{
|
||||
using traits = pixel_traits<typename Pixmap::pixel_type>;
|
||||
Pixmap p({width_, height_, depth_});
|
||||
pixels(traits::format, traits::type, p.data());
|
||||
return p;
|
||||
}
|
||||
|
||||
static 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);
|
||||
|
||||
template <typename Pixmap>
|
||||
static texture_3d from_pixmap(Pixmap const & p)
|
||||
{
|
||||
texture_3d t;
|
||||
t.load(p);
|
||||
return t;
|
||||
}
|
||||
|
||||
void generate_mipmap();
|
||||
void nearest_filter();
|
||||
void linear_filter();
|
||||
void anisotropy();
|
||||
|
||||
void repeat();
|
||||
void clamp();
|
||||
|
||||
private:
|
||||
GLuint id_;
|
||||
int width_ = 0;
|
||||
int height_ = 0;
|
||||
int depth_ = 0;
|
||||
|
||||
texture_3d(GLuint id);
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,6 +4,118 @@
|
|||
namespace psemek::gfx
|
||||
{
|
||||
|
||||
static std::optional<float> 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_);
|
||||
|
|
@ -99,13 +211,12 @@ namespace psemek::gfx
|
|||
{
|
||||
if (!gl::exts::var_EXT_texture_filter_anisotropic) return;
|
||||
|
||||
static std::optional<float> level;
|
||||
if (!level)
|
||||
if (!max_anisotropy_level)
|
||||
{
|
||||
level = 0;
|
||||
gl::GetFloatv(gl::MAX_TEXTURE_MAX_ANISOTROPY_EXT, &(*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, *level);
|
||||
gl::TexParameterf(gl::TEXTURE_2D, gl::TEXTURE_MAX_ANISOTROPY_EXT, *max_anisotropy_level);
|
||||
}
|
||||
|
||||
void texture_2d::repeat()
|
||||
|
|
@ -122,4 +233,128 @@ namespace psemek::gfx
|
|||
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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue