From 563b4ff86f3fa71d75453ebe2c7d0f10bae963f3 Mon Sep 17 00:00:00 2001 From: omigamedev Date: Sun, 28 Jul 2019 19:22:47 +0200 Subject: [PATCH] check float texture extension, use float32 or float16 if available, show extension on title bar, add thread and render task for lightmap rendering --- data/layout.xml | 3 ++ src/app_layout.cpp | 17 +++++++++ src/app_shaders.cpp | 10 ++++- src/canvas.cpp | 54 +++++++++++++++++--------- src/node_panel_grid.cpp | 85 ++++++++++++++++++++++++----------------- src/shader.cpp | 2 + src/shader.h | 2 + src/util.cpp | 2 + 8 files changed, 120 insertions(+), 55 deletions(-) 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);