render implement thread, wrap GL commands into tasks
This commit is contained in:
135
src/texture.cpp
135
src/texture.cpp
@@ -41,19 +41,22 @@ void TextureManager::invalidate()
|
||||
|
||||
bool Texture2D::create(int width, int height, GLint internal_format, GLint format, const uint8_t* data)
|
||||
{
|
||||
destroy();
|
||||
m_width = width;
|
||||
m_height = height;
|
||||
m_format = format;
|
||||
m_iformat = internal_format;
|
||||
glGenTextures(1, &m_tex);
|
||||
//LOG("TEX create %d", m_tex);
|
||||
bind();
|
||||
auto ifmt = GL_UNSIGNED_BYTE;
|
||||
if (internal_format == GL_RGBA32F) ifmt = GL_FLOAT;
|
||||
if (internal_format == GL_RGBA16F) ifmt = GL_HALF_FLOAT;
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, internal_format, width, height, 0, format, ifmt, data);
|
||||
unbind();
|
||||
App::I.render_task([=]
|
||||
{
|
||||
destroy();
|
||||
m_width = width;
|
||||
m_height = height;
|
||||
m_format = format;
|
||||
m_iformat = internal_format;
|
||||
glGenTextures(1, &m_tex);
|
||||
//LOG("TEX create %d", m_tex);
|
||||
bind();
|
||||
auto ifmt = GL_UNSIGNED_BYTE;
|
||||
if (internal_format == GL_RGBA32F) ifmt = GL_FLOAT;
|
||||
if (internal_format == GL_RGBA16F) ifmt = GL_HALF_FLOAT;
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, internal_format, width, height, 0, format, ifmt, data);
|
||||
unbind();
|
||||
});
|
||||
return true;
|
||||
}
|
||||
bool Texture2D::create(const Image& img)
|
||||
@@ -65,10 +68,13 @@ bool Texture2D::create(const Image& img)
|
||||
|
||||
void Texture2D::create_mipmaps()
|
||||
{
|
||||
bind();
|
||||
glGenerateMipmap(GL_TEXTURE_2D);
|
||||
unbind();
|
||||
has_mips = true;
|
||||
App::I.render_task([this]
|
||||
{
|
||||
bind();
|
||||
glGenerateMipmap(GL_TEXTURE_2D);
|
||||
unbind();
|
||||
has_mips = true;
|
||||
});
|
||||
}
|
||||
|
||||
void Texture2D::assign(GLuint tex, int w/* = -1*/, int h/* = -1*/, GLuint internal_format/* = GL_RGBA8*/, GLuint format/* = GL_RGBA*/)
|
||||
@@ -98,10 +104,37 @@ bool Texture2D::load_file(std::string filename)
|
||||
return create(img);
|
||||
}
|
||||
|
||||
void Texture2D::destroy()
|
||||
{
|
||||
if (m_tex)
|
||||
{
|
||||
App::I.render_task_async([id = m_tex]
|
||||
{
|
||||
glDeleteTextures(1, &id);
|
||||
});
|
||||
m_tex = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void Texture2D::bind() const
|
||||
{
|
||||
assert(App::I.is_render_thread());
|
||||
glBindTexture(GL_TEXTURE_2D, m_tex);
|
||||
}
|
||||
|
||||
void Texture2D::unbind() const
|
||||
{
|
||||
assert(App::I.is_render_thread());
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
}
|
||||
|
||||
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);
|
||||
App::I.render_task([this, data]
|
||||
{
|
||||
bind();
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, m_width, m_height, m_format, GL_UNSIGNED_BYTE, data);
|
||||
});
|
||||
}
|
||||
|
||||
glm::vec2 Texture2D::size() const
|
||||
@@ -113,57 +146,81 @@ Texture2D::~Texture2D()
|
||||
{
|
||||
if (auto_destroy)
|
||||
{
|
||||
LOG("Texture2D auto destroy");
|
||||
App::I.async_start();
|
||||
destroy();
|
||||
App::I.async_end();
|
||||
App::I.render_task_async([this]
|
||||
{
|
||||
LOG("Texture2D auto destroy");
|
||||
destroy();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
bool Sampler::create(GLint filter /*= GL_LINEAR*/, GLint wrap /*= GL_CLAMP_TO_EDGE*/)
|
||||
{
|
||||
bool ret = false;
|
||||
App::I.render_task([this, &ret, filter, wrap]
|
||||
{
|
||||
#if USE_SAMPLER
|
||||
glGenSamplers(1, &id);
|
||||
glGenSamplers(1, &id);
|
||||
#endif // USE_SAMPLER
|
||||
if (id == 0)
|
||||
return false;
|
||||
set(filter, wrap);
|
||||
return true;
|
||||
if (id == 0)
|
||||
{
|
||||
ret = false;
|
||||
return;
|
||||
}
|
||||
set(filter, wrap);
|
||||
ret = true;
|
||||
});
|
||||
return ret;
|
||||
}
|
||||
void Sampler::set(GLint filter /*= GL_LINEAR*/, GLint wrap /*= GL_CLAMP_TO_EDGE*/)
|
||||
{
|
||||
App::I.render_task([=]
|
||||
{
|
||||
#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);
|
||||
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::set_filter(GLint filter_min, GLint filter_mag)
|
||||
{
|
||||
App::I.render_task([=]
|
||||
{
|
||||
#if USE_SAMPLER
|
||||
glSamplerParameteri(id, GL_TEXTURE_MIN_FILTER, filter_min);
|
||||
glSamplerParameteri(id, GL_TEXTURE_MAG_FILTER, filter_mag);
|
||||
glSamplerParameteri(id, GL_TEXTURE_MIN_FILTER, filter_min);
|
||||
glSamplerParameteri(id, GL_TEXTURE_MAG_FILTER, filter_mag);
|
||||
#endif // USE_SAMPLER
|
||||
});
|
||||
}
|
||||
void Sampler::set_border(glm::vec4 rgba)
|
||||
{
|
||||
App::I.render_task([this, rgba]
|
||||
{
|
||||
#if USE_SAMPLER && !defined(__IOS__) && !defined(__ANDROID__)
|
||||
glSamplerParameterfv(id, GL_TEXTURE_BORDER_COLOR, glm::value_ptr(rgba));
|
||||
glSamplerParameterfv(id, GL_TEXTURE_BORDER_COLOR, glm::value_ptr(rgba));
|
||||
#endif // USE_SAMPLER
|
||||
});
|
||||
}
|
||||
void Sampler::bind(int unit) const
|
||||
{
|
||||
current_unit = unit;
|
||||
App::I.render_task([=]
|
||||
{
|
||||
current_unit = unit;
|
||||
#if USE_SAMPLER
|
||||
glBindSampler(unit, id);
|
||||
glBindSampler(unit, id);
|
||||
#endif // USE_SAMPLER
|
||||
});
|
||||
}
|
||||
void Sampler::unbind()
|
||||
{
|
||||
App::I.render_task([=]
|
||||
{
|
||||
#if USE_SAMPLER
|
||||
glBindSampler(current_unit, 0);
|
||||
glBindSampler(current_unit, 0);
|
||||
#endif // USE_SAMPLER
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user