render implement thread, wrap GL commands into tasks

This commit is contained in:
2019-07-06 22:25:07 +02:00
parent db27334ce5
commit 0012e2ce9b
18 changed files with 1252 additions and 904 deletions

View File

@@ -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
});
}