Files
panopainter/engine/texture.cpp

119 lines
2.9 KiB
C++

#include "pch.h"
#include "log.h"
#include "texture.h"
#include "util.h"
std::map<uint16_t, Texture2D> TextureManager::m_textures;
bool TextureManager::load(const char* path)
{
uint16_t id = const_hash(path);
if (m_textures.count(id) == 0 || !m_textures[id].ready())
{
return m_textures[id].load(path);
}
return true;
}
void TextureManager::assign(uint16_t id, GLuint tex, int w/* = -1*/, int h/* = -1*/, GLuint internal_format/* = GL_RGBA8*/, GLuint format/* = GL_RGBA*/)
{
m_textures[id].assign(tex, w, h, internal_format, format);
}
Texture2D& TextureManager::get(uint16_t id)
{
return m_textures[id];
}
void TextureManager::invalidate()
{
for (auto& t : m_textures)
{
t.second.destroy();
}
m_textures.clear();
}
bool Texture2D::create(int width, int height, GLint internal_format, GLint format, const uint8_t* data)
{
m_width = width;
m_height = height;
m_format = format;
m_iformat = internal_format;
glGenTextures(1, &m_tex);
LOG("TEX create %d", m_tex);
bind();
glTexImage2D(GL_TEXTURE_2D, 0, internal_format, width, height, 0, format, GL_UNSIGNED_BYTE, data);
unbind();
return true;
}
bool Texture2D::create(const ui::Image& img)
{
static GLint formats[] = { GL_RED, GL_RG, GL_RGB, GL_RGBA };
static GLint iformats[] = { GL_R8, GL_RG8, GL_RGB8, GL_RGBA8 };
return create(img.width, img.height, iformats[img.comp - 1], formats[img.comp - 1], img.data());
}
void Texture2D::assign(GLuint tex, int w/* = -1*/, int h/* = -1*/, GLuint internal_format/* = GL_RGBA8*/, GLuint format/* = GL_RGBA*/)
{
m_tex = tex;
m_width = w;
m_height = h;
m_format = format;
m_iformat = internal_format;
}
bool Texture2D::load(std::string filename)
{
LOG("load texture %s", filename.c_str());
ui::Image img;
if (!img.load(filename))
return false;
return create(img);
}
void Texture2D::update(const uint8_t* data)
{
bind();
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, m_width, m_height, m_format, GL_UNSIGNED_BYTE, data);
}
glm::vec2 Texture2D::size() const
{
return { m_width, m_height };
}
bool Sampler::create(GLint filter /*= GL_LINEAR*/, GLint wrap /*= GL_CLAMP_TO_EDGE*/)
{
#if USE_SAMPLER
glGenSamplers(1, &id);
#endif // USE_SAMPLER
if (id == 0)
return false;
set(filter, wrap);
return true;
}
void Sampler::set(GLint filter /*= GL_LINEAR*/, GLint wrap /*= GL_CLAMP_TO_EDGE*/)
{
#if USE_SAMPLER
glSamplerParameteri(id, GL_TEXTURE_WRAP_S, wrap);
glSamplerParameteri(id, GL_TEXTURE_WRAP_T, wrap);
glSamplerParameteri(id, GL_TEXTURE_WRAP_R, wrap);
glSamplerParameteri(id, GL_TEXTURE_MIN_FILTER, filter);
glSamplerParameteri(id, GL_TEXTURE_MAG_FILTER, filter);
#endif // USE_SAMPLER
}
void Sampler::bind(int unit)
{
current_unit = unit;
#if USE_SAMPLER
glBindSampler(unit, id);
#endif // USE_SAMPLER
}
void Sampler::unbind()
{
#if USE_SAMPLER
glBindSampler(current_unit, 0);
#endif // USE_SAMPLER
}