diff --git a/data/layout.xml b/data/layout.xml
index 139fa2a..57c7414 100644
--- a/data/layout.xml
+++ b/data/layout.xml
@@ -1666,6 +1666,9 @@ Here's a list of what's available in this release.
+
+
+
diff --git a/src/app_layout.cpp b/src/app_layout.cpp
index abfcd44..8bd1a86 100644
--- a/src/app_layout.cpp
+++ b/src/app_layout.cpp
@@ -1237,6 +1237,23 @@ void App::initLayout()
x->m_color = ShaderManager::ext_framebuffer_fetch ? glm::vec4(0, 1, 0, 1) : glm::vec4(1, 0, 0, 1);
}
+ if (auto x = layout[main_id]->find("ext-flt"))
+ {
+ if (ShaderManager::ext_texture_float || ShaderManager::ext_half_float_pixel)
+ {
+ if (auto t = x->find("ext-flt-text"))
+ {
+ int bits = ShaderManager::ext_texture_float ? 32 : 16;
+ t->set_text_format("flt%d", bits);
+ }
+ x->m_color = glm::vec4(0, 1, 0, 1);
+ }
+ else
+ {
+ x->m_color = glm::vec4(1, 0, 0, 1);
+ }
+ }
+
brush_update();
// hacky thing to make the toolbar buttons not steal events when moving cursor fast
diff --git a/src/app_shaders.cpp b/src/app_shaders.cpp
index 5cf3444..2d30599 100644
--- a/src/app_shaders.cpp
+++ b/src/app_shaders.cpp
@@ -15,10 +15,18 @@ void App::initShaders()
for (int i = 0; i < n_exts; i++)
{
std::string ext = (const char*)glGetStringi(GL_EXTENSIONS, i);
- if (ext.find("shader_framebuffer_fetch") != std::string::npos)
+ if (GLAD_GL_EXT_shader_framebuffer_fetch || GLAD_GL_EXT_shader_framebuffer_fetch_non_coherent)
{
ShaderManager::ext_framebuffer_fetch = true;
}
+ else if (GLAD_GL_ARB_texture_float || GLAD_GL_ATI_texture_float)
+ {
+ ShaderManager::ext_texture_float = true;
+ }
+ else if (GLAD_GL_NV_half_float || GLAD_GL_ARB_half_float_pixel)
+ {
+ ShaderManager::ext_half_float_pixel = true;
+ }
}
});
diff --git a/src/canvas.cpp b/src/canvas.cpp
index a780ccb..4711ab5 100644
--- a/src/canvas.cpp
+++ b/src/canvas.cpp
@@ -1494,15 +1494,24 @@ void Canvas::resize(int width, int height)
m_size = { width, height };
for (int i = 0; i < 6; i++)
{
-//#if defined(__IOS__) || defined(__ANDROID__)
- m_tmp[i].create(width, height, -1, GL_RGBA8);
- m_tmp_dual[i].create(width, height, -1, GL_RGBA8);
- m_tex[i].create(width, height, GL_RGBA8);
-//#else
-// m_tmp[i].create(width, height, -1, GL_RGBA32F);
-// m_tmp_dual[i].create(width, height, -1, GL_RGBA32F);
-// m_tex[i].create(width, height, GL_RGBA32F);
-//#endif
+ if (ShaderManager::ext_texture_float)
+ {
+ m_tmp[i].create(width, height, -1, GL_RGBA32F);
+ m_tmp_dual[i].create(width, height, -1, GL_RGBA32F);
+ m_tex[i].create(width, height, GL_RGBA32F);
+ }
+ else if (ShaderManager::ext_half_float_pixel)
+ {
+ m_tmp[i].create(width, height, -1, GL_RGBA16F);
+ m_tmp_dual[i].create(width, height, -1, GL_RGBA16F);
+ m_tex[i].create(width, height, GL_RGBA16F);
+ }
+ else
+ {
+ m_tmp[i].create(width, height, -1, GL_RGBA8);
+ m_tmp_dual[i].create(width, height, -1, GL_RGBA8);
+ m_tex[i].create(width, height, GL_RGBA8);
+ }
m_tex2[i].create(width, height, GL_RGBA8);
}
for (auto& l : m_layers)
@@ -1539,15 +1548,24 @@ bool Canvas::create(int width, int height)
m_size = { width, height };
for (int i = 0; i < 6; i++)
{
-//#if defined(__IOS__) || defined(__ANDROID__)
- m_tmp[i].create(width, height, -1, GL_RGBA8);
- m_tmp_dual[i].create(width, height, -1, GL_RGBA8);
- m_tex[i].create(width, height, GL_RGBA8);
-//#else
-// m_tmp[i].create(width, height, -1, GL_RGBA32F);
-// m_tmp_dual[i].create(width, height, -1, GL_RGBA32F);
-// m_tex[i].create(width, height, GL_RGBA32F);
-//#endif
+ if (ShaderManager::ext_texture_float)
+ {
+ m_tmp[i].create(width, height, -1, GL_RGBA32F);
+ m_tmp_dual[i].create(width, height, -1, GL_RGBA32F);
+ m_tex[i].create(width, height, GL_RGBA32F);
+ }
+ else if (ShaderManager::ext_half_float_pixel)
+ {
+ m_tmp[i].create(width, height, -1, GL_RGBA16F);
+ m_tmp_dual[i].create(width, height, -1, GL_RGBA16F);
+ m_tex[i].create(width, height, GL_RGBA16F);
+ }
+ else
+ {
+ m_tmp[i].create(width, height, -1, GL_RGBA8);
+ m_tmp_dual[i].create(width, height, -1, GL_RGBA8);
+ m_tex[i].create(width, height, GL_RGBA8);
+ }
m_tex2[i].create(width, height, GL_RGBA8);
}
#if defined(__IOS__) || defined(__ANDROID__)
diff --git a/src/node_panel_grid.cpp b/src/node_panel_grid.cpp
index 07630ff..6712bc2 100644
--- a/src/node_panel_grid.cpp
+++ b/src/node_panel_grid.cpp
@@ -121,12 +121,19 @@ void NodePanelGrid::init_controls()
m_render->on_click = [this](Node*)
{
- gl_state gl;
- gl.save();
- bake_uvs();
- m_hm_shading->set_index(3);
- m_shade_mode = ShadeMode::Textured;
- gl.restore();
+ if (ShaderManager::ext_texture_float || ShaderManager::ext_half_float_pixel)
+ {
+ std::thread([this] {
+ bake_uvs();
+ m_hm_shading->set_index(3);
+ m_shade_mode = ShadeMode::Textured;
+ }).detach();
+ }
+ else
+ {
+ App::I->message_box("Rendering failed",
+ "Your hardware does not support lightmap rendering.");
+ }
};
m_commit->on_click = [this](Node*)
{
@@ -213,6 +220,7 @@ float NodePanelGrid::get_offset() const
void NodePanelGrid::draw_heightmap(const glm::mat4& proj, const glm::mat4& camera, bool commit) const
{
+ assert(App::I->is_render_thread());
if (m_groud_opacity->get_value() > 0.f)
{
bool depth = glIsEnabled(GL_DEPTH_TEST);
@@ -345,38 +353,43 @@ void NodePanelGrid::bake_uvs()
return;
RTT fb;
-#if defined(__IOS__) || defined(__ANDROID__)
- fb.create(m_texture.size().x, m_texture.size().y, -1, GL_RGBA16F);
-#else
- fb.create(m_texture.size().x, m_texture.size().y, -1, GL_RGBA32F);
-#endif
- fb.bindFramebuffer();
- fb.clear({ 1, 0, 0, 1 });
- glDisable(GL_BLEND);
- glDisable(GL_DEPTH_TEST);
- glViewport(0, 0, fb.getWidth(), fb.getHeight());
- ShaderManager::use(kShader::BakeUV);
- ShaderManager::u_mat4(kShaderUniform::MVP, glm::mat4(1));
-
- // bake normal
- ShaderManager::u_int(kShaderUniform::Mode, 0);
- m_hm_plane.draw_fill();
- std::unique_ptr data_nor(fb.readTextureDataFloat());
- //stbi_write_png("bake-nor.png", fb.getWidth(), fb.getHeight(), 4, fb.readTextureData(), 0);
-
- // bake position
- ShaderManager::u_int(kShaderUniform::Mode, 1);
- m_hm_plane.draw_fill();
- std::unique_ptr data_pos(fb.readTextureDataFloat());
- //stbi_write_png("bake-pos.png", fb.getWidth(), fb.getHeight(), 4, fb.readTextureData(), 0);
+ if (ShaderManager::ext_texture_float)
+ {
+ fb.create(m_texture.size().x, m_texture.size().y, -1, GL_RGBA32F);
+ }
+ else if (ShaderManager::ext_half_float_pixel)
+ {
+ fb.create(m_texture.size().x, m_texture.size().y, -1, GL_RGBA16F);
+ }
- fb.unbindFramebuffer();
- fb.destroy();
+ std::unique_ptr data_nor;
+ std::unique_ptr data_pos;
+ App::I->render_task([&]{
+ fb.bindFramebuffer();
+ fb.clear({ 1, 0, 0, 1 });
+ glDisable(GL_BLEND);
+ glDisable(GL_DEPTH_TEST);
+ glViewport(0, 0, fb.getWidth(), fb.getHeight());
+ ShaderManager::use(kShader::BakeUV);
+ ShaderManager::u_mat4(kShaderUniform::MVP, glm::mat4(1));
- auto pb = root()->add_child();
- pb->m_progress->SetWidthP(0);
- pb->m_title->set_text("Lightmap Rendering");
- pb->btn_cancel->destroy();
+ // bake normal
+ ShaderManager::u_int(kShaderUniform::Mode, 0);
+ m_hm_plane.draw_fill();
+ data_nor.reset(fb.readTextureDataFloat());
+ //stbi_write_png("bake-nor.png", fb.getWidth(), fb.getHeight(), 4, fb.readTextureData(), 0);
+
+ // bake position
+ ShaderManager::u_int(kShaderUniform::Mode, 1);
+ m_hm_plane.draw_fill();
+ data_pos.reset(fb.readTextureDataFloat());
+ //stbi_write_png("bake-pos.png", fb.getWidth(), fb.getHeight(), 4, fb.readTextureData(), 0);
+
+ fb.unbindFramebuffer();
+ fb.destroy();
+ });
+
+ auto pb = App::I->show_progress("Lightmap Rendering");
if (m_rt_dirty)
{
diff --git a/src/shader.cpp b/src/shader.cpp
index b277e0b..eede043 100644
--- a/src/shader.cpp
+++ b/src/shader.cpp
@@ -7,6 +7,8 @@
std::map ShaderManager::m_shaders;
Shader* ShaderManager::m_current;
bool ShaderManager::ext_framebuffer_fetch = false;
+bool ShaderManager::ext_texture_float = false;
+bool ShaderManager::ext_half_float_pixel = false;
std::string Shader::read(const std::string& path)
{
diff --git a/src/shader.h b/src/shader.h
index 68bde7a..12d72d1 100644
--- a/src/shader.h
+++ b/src/shader.h
@@ -110,6 +110,8 @@ class ShaderManager
static Shader* m_current;
public:
static bool ext_framebuffer_fetch;
+ static bool ext_texture_float;
+ static bool ext_half_float_pixel;
static bool load(kShader id, const std::string& path);
static bool reload();
static bool create(kShader id, const std::string& vertex, const std::string& fragment);
diff --git a/src/util.cpp b/src/util.cpp
index 262cfa0..f8b5cc3 100644
--- a/src/util.cpp
+++ b/src/util.cpp
@@ -740,6 +740,7 @@ void parallel_for(size_t nb_elements, std::function functor, boo
void gl_state::save()
{
+ assert(App::I->is_render_thread());
blend = glIsEnabled(GL_BLEND);
depth_test = glIsEnabled(GL_DEPTH_TEST);
scissor_test = glIsEnabled(GL_SCISSOR_TEST);
@@ -759,6 +760,7 @@ void gl_state::save()
void gl_state::restore()
{
+ assert(App::I->is_render_thread());
blend ? glEnable(GL_BLEND) : glDisable(GL_BLEND);
depth_test ? glEnable(GL_DEPTH_TEST) : glDisable(GL_DEPTH_TEST);
scissor_test ? glEnable(GL_SCISSOR_TEST) : glDisable(GL_SCISSOR_TEST);