151 lines
2.5 KiB
C++
151 lines
2.5 KiB
C++
#include "pw/visual/texture.hpp"
|
|
|
|
#include "glad/glad.h"
|
|
|
|
namespace pw {
|
|
|
|
|
|
struct texture::impl {
|
|
|
|
texture &_host;
|
|
|
|
GLuint _texture_id;
|
|
GLuint _texture_sampler;
|
|
|
|
impl() = delete;
|
|
|
|
impl(texture& host)
|
|
: _host(host)
|
|
{
|
|
}
|
|
|
|
~impl()
|
|
{
|
|
destroy();
|
|
}
|
|
|
|
GLuint gl_shape() {
|
|
switch (_host.shape()) {
|
|
case data_layout::shape_1d:
|
|
return GL_TEXTURE_1D;
|
|
case data_layout::shape_2d:
|
|
return GL_TEXTURE_2D;
|
|
case data_layout::shape_3d:
|
|
return GL_TEXTURE_3D;
|
|
}
|
|
|
|
debug::e() << __PRETTY_FUNCTION__ << " unknown texture layout";
|
|
|
|
return 0;
|
|
}
|
|
|
|
void bind()
|
|
{
|
|
glBindTexture(gl_shape(), _texture_id);
|
|
}
|
|
|
|
void unbind()
|
|
{
|
|
glBindTexture(gl_shape(), 0);
|
|
}
|
|
|
|
void create_sampler()
|
|
{
|
|
bind();
|
|
|
|
glGenSamplers(1, &_texture_sampler);
|
|
glSamplerParameteri(_texture_sampler, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
|
glSamplerParameteri(_texture_sampler, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
|
|
|
// glSamplerParameteri(_texture_sampler, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
|
|
glSamplerParameteri(_texture_sampler, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
|
glSamplerParameteri(_texture_sampler, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
|
|
|
unbind();
|
|
}
|
|
|
|
void create()
|
|
{
|
|
|
|
auto i = _host._image;
|
|
|
|
glGenTextures(1, &_texture_id);
|
|
glBindTexture(gl_shape(),_texture_id);
|
|
|
|
GLuint format = GL_RGBA;
|
|
|
|
glTexImage2D(gl_shape(),0,format,i->size().width,i->size().height,0,format,GL_UNSIGNED_BYTE,i->data());
|
|
|
|
glGenerateMipmap(gl_shape());
|
|
|
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
|
|
|
|
}
|
|
|
|
|
|
void destroy()
|
|
{
|
|
glDeleteTextures(1,&_texture_id);
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
//
|
|
// Wrapper
|
|
//
|
|
|
|
texture::texture()
|
|
: _impl { make_unique<texture::impl>(*this) }
|
|
{
|
|
}
|
|
|
|
texture::texture(image_ref i, texture::data_layout s)
|
|
{
|
|
texture();
|
|
set_image(i);
|
|
set_shape(s);
|
|
|
|
_impl->create();
|
|
}
|
|
|
|
texture::~texture()
|
|
{
|
|
}
|
|
|
|
void texture::set_image(image_ref i)
|
|
{
|
|
_image = i;
|
|
|
|
_impl->create();
|
|
}
|
|
|
|
void texture::set_shape(data_layout s)
|
|
{
|
|
_shape = s;
|
|
}
|
|
|
|
void texture::set_wrap(wrap_mode w)
|
|
{
|
|
_wrap = w;
|
|
}
|
|
|
|
|
|
uint32_t texture::native_handle() const
|
|
{
|
|
return _impl->_texture_id;
|
|
}
|
|
|
|
uint32_t texture::native_sampler_handle() const
|
|
{
|
|
return _impl->_texture_sampler;
|
|
}
|
|
|
|
|
|
}
|